Показать сообщение отдельно
Старый 07.10.2011, 14:08
trng вне форума Посмотреть профиль Отправить личное сообщение для trng Найти все сообщения от trng
  № 6  
Ответить с цитированием
trng

Регистрация: Jun 2011
Сообщений: 212
А вот как раз со спецификацией есть нюансы. А именно с длинной вектора, которая вроде как должна быть U29.
Пишем вот такой нехитрый код (Vector.<uint> - для примера):
Код AS3:
function traceHex(data:Vector.<uint>):void {
	var ba:ByteArray = new ByteArray();
	ba.writeObject(data);
	var s:String = data.length.toString() + ' : ';
 
	// чисто оформительское обрезание:
	// признак вектора  (1 байт) + длина (макс. 4 байта) + U8 + данные (одно uint 4 байта) = 10
	var j:int = (ba.length > 10) ? 10 : ba.length;
 
	for (var i:int=0;i<j;i++) {
		if (ba[i] < 0x10) s += '0'; 
		s +=  ba[i].toString(16).toUpperCase() + ' ';
	}
	trace (s);
}
 
var la:Array = new Array(1, 2, 0x10, 0xff, 0xffff, 0xffffff);
var bh:Vector.<uint>;
 
 
bh = new Vector.<uint>(0);
traceHex( bh );
 
 
for (var i:int=0;i<la.length;i++) {
   bh = new Vector.<uint>(la[i]);
   bh[0] = 0x90807060; // чтобы было видно начало вектора
   traceHex( bh );
}
Получаем:


Код:

        0 : 0E 01 00 
        1 : 0E 03 00 90 80 70 60 
        2 : 0E 05 00 90 80 70 60 00 00 00 
       16 : 0E 21 00 90 80 70 60 00 00 00 
      255 : 0E 83 7F 00 90 80 70 60 00 00 
    65535 : 0E 87 FF 7F 00 90 80 70 60 00 
 16777215 : 0E 87 FF FF FF 00 90 80 70 60
Итак:
  1. 0E - (1 байт) маркер вектора uint. Правильно.
  2. длина вектора (U29) - как то на UINT29 не похоже
  3. 00 - (U8) vector-fixed-flag - правильно
  4. первый элемент вектора (uint - 4 байта) - правильно

По поводу длины вектора. Читаем спецификацию U29:
  • 0x00000000 - 0x0000007F : 0xxxxxxx
  • 0x00000080 - 0x00003FFF : 1xxxxxxx 0xxxxxxx
  • 0x00004000 - 0x001FFFFF : 1xxxxxxx 1xxxxxxx 0xxxxxxx
  • 0x00200000 - 0x3FFFFFFF : 1xxxxxxx 1xxxxxxx 1xxxxxxx xxxxxxxx
  • 0x40000000 - 0xFFFFFFFF : throw range exception

Получается что 0 должен быть 0, 1 должно быть 1, 2 должно быть 2
Имеем:
вместо нуля - 1
вместо 1 - 3
вместо 2 - 5.


Допустим, что спецификацию U29 надо понимать так, как написано в комменте на хабре:
; The first (low) bit is a flag with value 1.
; The remaining 1 to 28 significant bits are used to encode
; the length of the vector
Тогда получается, что 0, 1, 2, 16 - правильно.
А все что больше - неправильно.
Наприрмер для 255 (0xff): как ни крути 837F - 8 единиц подряд (0xff) не получается. Получается либо больше либо меньше.

Добавлено через 7 минут
0x83: 10000011
0x7f : 01111111
Как из этого получить 8 единиц?

Добавлено через 1 час 44 минуты
Ошибочка вышла. Работает.
Если взять readUInt29() из http://cvlib.googlecode.com/svn-hist...or/amf/AMF3.as и результат сдвинуть вправо на один бит, то работет.