Возвращение байтовой строки в ExternalInterface.call приводит к ошибке - PullRequest
8 голосов
/ 21 января 2010

Я работаю над проектом с открытым исходным кодом Downloadify , и до сих пор он просто обрабатывал возвращаемые строки в ответ на команды ExternalInterface.call.

Я пытаюсь собрать тестовый набор, используя JSZip и Downloadify вместе, в результате получается, что файл Zip динамически создается в браузере, а затем сохраняется на диск с помощью FileReference.save. Однако это моя проблема:

Библиотека JSZip может возвращать либо кодированную строку base64 Zip, либо необработанную строку байтов. Проблема в том, что если я возвращаю эту строку байтов в ответ на команду ExternalInterface.call, я получаю эту ошибку:

Error #1085: The element type "string" must be terminated by the matching end-tag "</string>"

ActionScript 3:

var theData:* = ExternalInterface.call('Downloadify.getTextForSave',queue_name);

Где queue_name - просто строка, используемая для идентификации правильного экземпляра в JS.

JavaScript:

var zip = new JSZip();
zip.add("test.txt", "Hello world!\n");
var content = zip.generate(true);
return content;

Если я вместо обычной строки байтов возвращаю обычную строку, вызов работает правильно. Я бы хотел избежать использования base64, так как мне пришлось бы включить декодер base64 в мой swf, что увеличит его размер.

Наконец: я не ищу генератор Z3 AS3. Для моего проекта обязательно, чтобы эта часть выполнялась в JavaScript

По общему признанию не программист AS3 по профессии, поэтому, если вам нужно больше подробностей, пожалуйста, дайте мне знать.

Ответы [ 2 ]

3 голосов
/ 21 января 2010

Когда данные возвращаются из вызовов javascript, они сериализуются в строку XML. Поэтому, если «необработанная строка», возвращаемая JSZip, будет содержать символы, которые делают XML недействительным, что, как я думаю, происходит здесь, вы получите такие ошибки.

На самом деле вы получаете в ответ:

<string>[your JSZip generated string]</string>

Представьте, что ваша возвращаемая строка содержит символ "<" - это сделает XML недействительным, и трудно сказать, какие коды символов будет также преобразовывать необработанный поток байтов. </p>

Подробнее о формате XML внешнего API можно прочитать на LiveDocs

1 голос
/ 21 января 2010

Я думаю, что проблема вызвана тем фактом, что flash ожидает строку utf8, и вы добавляете в нее некоторые двоичные файлы. я думаю, например, 0x00FF не будет действительным utf8 ...

Вы можете попробовать поиграться с flash.system::System.setCodePage, но я не был бы слишком оптимистичен ...

Полагаю, декодер base64, вероятно, действительно самый простой ... Я бы предпочел беспокоиться о скорости, а не о размере файла, хотя ... этот элементарный метод декодирования использует меньше половины K:

public function decodeBase64(source:String):ByteArray {
 var ret:ByteArray = new ByteArray();
 var map:Object = new Object();
 var i:int = 0;
 for each (var char:String in "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("")) map[char] = i++;
 map["="] = 0;
 source = source.split("\n").join("").split("\r").join("");//remove linebreaks
 for (i = 0; i < source.length/4; i++) {
  var buf:int = 0;
  for each (char in source.substr(i * 4, 4).split("")) buf = (buf << 6) + map[char];
  ret.writeByte(buf >>> 16);
  ret.writeShort(buf);
 }
 return ret;
}

Вы можете просто сократить имена функций и взять меньшее изображение ... или использовать ColorTransform или ConvolutionFilter на одном изображении вместо четырех ... или скомпилировать изображение в SWF для уменьшения общего размера ... или уменьшить длину имени функции ...

так что, если вы не планируете работать с МБ данных, то это путь ...

...