Записки о Flash

getDefinitionNames

У класса ApplicationDomain есть замечательный метод getDefinitionByName, возвращающий нам класс нужного объекта или функцию. Но нет метода getDefinitionNames, возвращающий имена всех классов, находящихся в данном домене (или загруженном swf). Моя функция getDefinitionNames призвана устранить данный недостаток. Для получения имен классов необходимо передать объект LoaderInfo или ByteArray, содержащий корректный swf.

Исходники

Версия 2.1 от 09.03.10:

  • Теперь в обычный режим поиска возвращает только классы (ранее были ещё и интерфейсы).
  • Появилась поддержка Flash 10 (наконец-то :) ) и типа данных Vector. В расширенном режиме поиска классы типа Vector. (где X — имя класса) также будут перечислены.
  • Версия 2.0 от 16.09.09:

  • Новый режим extended, работающий по другому алгоритму (чуть-чуть медленнее обычного поиска). В этом режиме вы получите не только список классов и интерфейсов, а все доступные definitions, т. е. функции, пространства имен, константы, переменные и т. п.
  • Также появился режим onlyLinked (в этом случае не работает extended), при котором вы получите список только тех классов, которые указаны в качестве linkage в библиотеке swf. В том числе те, которые создаются при использовании метатега [Embed]. Такой режим существенно быстрее обычного и расширенного поиска и рекомендуется в тех случаях, когда вы загружаете библиотеку графических и звуковых ресурсов и вам нужен список только самих ресурсов.
  • Эта версия полностью совместима с предыдущими, при обновлении вам потребуется всего лишь обновить код getDefinitionNames
  • Версия 1.1.1 от 16.09.09:

  • Ещё раз исправлена ошибка поиска классов :)
  • Версия 1.1 от 13.09.09:

  • Исправлена ошибка, в результате которой второй и последующие кадры swf, содержащие код, не распознавались
  • В качестве аргумента в функцию можно передавать как LoaderInfo (как было в предыдущей версии), так и ByteArray, содержащий корректный swf
  • P. S.: Решение для тех, кто хочет знать о подгруженном swf больше.


    20 comments

    20 Comments so far

    1. tikhop August 15th, 2008 14:43

      Привет, извиняюсь за, наверно, глупый вопрос, да и не по теме… Но все же, с помощью чего создаются такие странички, как страничка при клике на “Исходники”…

    2. etc August 15th, 2008 15:12

      Во Flex Builder в Export Release Build есть опция Include source. В папке bin-release будет страница View Source.

    3. tikhop August 15th, 2008 15:18

      Большое спасибо за оперативный ответ)

    4. julien revel September 12th, 2008 20:07

      Hi, this is a great tool, I was looking for this kind of function to list all classes in an application.
      Helas, I tried it on a very big Flex App, with several modules, and the function crashed here :

      tag = this._data.readUnsignedShort();

      Error: Error #2030: End of file detected
      at flash.utils::ByteArray/readUnsignedShort()

      I called the function using Application.application.loaderInfo.
      I tried with another (dummy and simple) app, and it worked
      Maybe it comes from the fact that modules are loaded into applicationDomain ?
      I have no idea, but maybe you have
      Thanks and bravo
      Julien

    5. etc September 12th, 2008 20:22

      It seems you call this method too early (earlier, than Event.COMPLETE occurs). Can you send me an example with which such problems arise? Or, a simplified example.

    6. wdrai October 10th, 2008 03:04

      I think there is a bug with swfs containing multiple frames, in particular Flex swfs which contain 2 frames.
      I could get only the classes of the first frame.

      I have made a little modification on your class and now it works fine.

      public function getDefinitionNames():Array {
      var definitions:Array = new Array();
      var next:uint = this.findTag();

      while (next > 0) {
      definitions.push.apply(definitions, this.getDefinitionNamesInTag());
      this._data.position = next;
      next = this.findTag();
      }

      return definitions;
      }

      /**
      * @private
      */
      private function findTag():uint {
      var tag:uint;
      var id:uint;
      var length:uint;
      var minorVersion:uint;
      var majorVersion:uint;

      while (this._data.bytesAvailable) {
      tag = this._data.readUnsignedShort();
      id = tag >> 6;
      length = tag & 0x3F;
      length = (length == 0x3F) ? this._data.readUnsignedInt() : length;

      var pos:uint = _data.position;

      switch (id) {
      case 72:
      case 82:
      if (id == 82) {
      this._data.position += 4;
      this._data.readString(); // identifier
      }

      minorVersion = this._data.readUnsignedShort();
      majorVersion = this._data.readUnsignedShort();

      if (minorVersion == 0×0010 && majorVersion == 0x002E) {
      return pos + length;
      } else {
      this._data.position += length;
      }
      break;

      default:
      this._data.position += length;
      }
      }

      return 0;
      }

    7. etc October 10th, 2008 08:20

      Hmmm, strange bug, getDefinitionNames should handle multiple definitions, but something was wrong. Thank you, William! I’ll see your modifications later and add them into source.

    8. Записки о Flash » ClassExplorer October 10th, 2008 13:37

      [...] Если вам нужно получить только список классов, то есть вариант попроще — getDefinitionNames. [...]

    9. [...] blog posting (in Russian) – link [...]

    10. [...] getDefinitionNames до версии [...]

    11. peko September 14th, 2009 00:17

      Спасибо за инструмент.
      а то приходилось генерить через jsfl массивы объектов в библиотеке.

    12. [...] день обновлений В очередной раз обновился getDefinitionNames. На этот раз сразу до версии [...]

    13. makc February 10th, 2010 01:47

      Прикручивая эту штуку к своему мегаобфускатору, обнаружил, что функция не работает, если передан ByteArray с position не показывающим в начало SWF. Оно вроде правильно так, но хорошо бы было приписку в комментах.

    14. makc February 10th, 2010 01:55

      TypeError: Error #1009: Cannot access a property or method of a null object reference.
      at Finder/getName()[D:\code\makc\flash\obfuscator\src\ru\etcs\utils\getDefinitionNames.as:368]
      at Finder/readTraits()[D:\code\makc\flash\obfuscator\src\ru\etcs\utils\getDefinitionNames.as:350]
      at Finder/getDefinitionNamesInTag()[D:\code\makc\flash\obfuscator\src\ru\etcs\utils\getDefinitionNames.as:314]
      at Finder/getDefinitionNames()[D:\code\makc\flash\obfuscator\src\ru\etcs\utils\getDefinitionNames.as:128]
      at global/ru.etcs.utils::getDefinitionNames()[D:\code\makc\flash\obfuscator\src\ru\etcs\utils\getDefinitionNames.as:48]

      да и методы не видно… придётся копнуть class explorer.

    15. etc February 10th, 2010 04:59

      position? Странно, должно было работать. Погляжу.
      А про какие методы речь идёт?

    16. makc February 10th, 2010 13:03

      это просто в лоб передал ByteArray, работает без проблем на 3х SWFках из 4х, на 4 – фэйл.

    17. makc February 10th, 2010 13:20

      “про какие методы” – протупил, да, имеется ввиду не видно имён методов, только классы.

    18. etc February 10th, 2010 13:29

      Так методы нельзя получить через getDefinitionByName и getDefinition.

    19. makc February 10th, 2010 13:58

      ну да, просто смутила фраза “В этом режиме вы получите не только список классов и интерфейсов, а все доступные definitions, т. е. функции, пространства имен, константы, переменные и т. п.” я чёт не подумал что речь о глобальных функциях.

    20. [...] обновление getDefinitionNames до версии 2.1. Появилась совместимость с Flash 10, изменен [...]

    Leave a reply