Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   как прочесть и записать u30 число? (http://www.flasher.ru/forum/showthread.php?t=133638)

DEAFFF 09.12.2009 17:46

как прочесть и записать u30 число?
 
вопрос к профессионалам

делаю небольшой декомпилятор на ас3, дошел уже до ABC тега
там в принципе не сложно, но есть какие то числа:
Цитата:

The type u30 represents a variable-length encoded 30-bit unsigned integer value.
The types u32 and s32 represent variable-length encoded 32-bit unsigned and signed integer values respectively.
Это выдержка из доки официальной.
http://www.adobe.com/devnet/actionsc...m2overview.pdf

есть достаточно похожий опенсорс проект swfutils
http://swfutils.riaforge.org/

но к сожалению там тока чтение этих чисел, например u30 у них читается так:

Код AS3:

public function readEU32():uint
{
        var result:uint = _dataInput.readUnsignedByte();
                if (!(result & 0x00000080))
                        return result;
        result = (result & 0x0000007f) | _dataInput.readUnsignedByte()<<7;
                if (!(result & 0x00004000))
                        return result;
        result = (result & 0x00003fff) | _dataInput.readUnsignedByte()<<14;
                if (!(result & 0x00200000))
                        return result;
        result = (result & 0x001fffff) | _dataInput.readUnsignedByte()<<21;
                if (!(result & 0x10000000))
                        return result;
        return (result & 0x0fffffff) | _dataInput.readUnsignedByte()<<28;
};

я не особо силен в булевых вычислениях... как записать подобное число? и где можно об этом почитать?

bicubic_bublic 09.12.2009 18:53

оттуда же:
Цитата:

The variable-length encoding for u30, u32, and s32 uses one to five bytes, depending on the magnitude of the
value encoded. Each byte contributes its low seven bits to the value. If the high (eighth) bit of a byte is set,
then the next byte of the abcFile is also part of the value. In the case of s32, sign extension is applied: the
seventh bit of the last byte of the encoding is propagated to fill out the 32 bits of the decoded value.
Добавлено через 6 минут
Код AS3:

function writeU32(ba:ByteArray, value:uint) {
  if (value == 0) {
      ba.writeByte(0);
  }
  var byte:uint;
  while (value != 0) {
      byte = value & 0x0000007f; // отрезаем 7 бит от числа
      value = value >> 7; //смещаем на 7 бит
      if (value != 0) { //если что-то еще осталось добавляем 8-й бит флаг
        byte = byte | 0x00000080;
      }
      ba.writeByte(byte); //пишем текущий байт..
  }
}


etc 09.12.2009 19:59

Код AS3:

    public function readASInt():int {
        var result:uint = 0;
        var i:uint = 0, byte:uint;
        do {
            byte = super.readUnsignedByte();
            result |= ( byte & 0x7F ) << ( i*7 );
            i+=1;
        } while ( byte & 1<<7 );
        return result;           
    }


DEAFFF 09.12.2009 20:46

ооо спасибо ребята!!!
а что на счет u32 и s32? интересует чтение и запись...

etc 09.12.2009 20:49

u32 и s32 можно прочитать стандартными методами ByteArray.

DEAFFF 09.12.2009 21:11

это то я понимаю )))
я имею ввиду эти два
The types u32 and s32 represent variable-length encoded 32-bit unsigned and signed integer values respectively.
они подобны u30 на сколько я понял

bicubic_bublic 09.12.2009 21:17

Цитата:

Сообщение от DEAFFF (Сообщение 871559)
это то я понимаю )))
я имею ввиду эти два
The types u32 and s32 represent variable-length encoded 32-bit unsigned and signed integer values respectively.
они подобны u30 на сколько я понял

для u32 чтения/записи можно использовать те же самые функции что и для u30

Цитата:

u32 и s32 можно прочитать стандартными методами ByteArray.
вот для s32 немного другая тема.. кстати он не считивается стандартным ByteArray'ем (впрочем как и u32)

Добавлено через 6 минут
Код AS3:

function writeS32(ba:ByteArray, value:int):void {
  if (value >= 0) {
      writeU32(ba, value);
      return;
  }
  var len:uint = 0;
  var abs:uint = - value; // абсолютное значение value;
  while (abs != 0) { // длина в битах абсолютного значения
      abs = abs >> 1;
      len++;
  }
  abs = - value;
  var signBytePos:uint = Math.floor(len / 7) + 1; // длина s32, порядковый номер байта в котором содержится знак-бит;
  while (signBytePos-- != 0) {
      byte = abs & 0x0000007f; // отрезаем 7 бит от числа
      abs = abs >> 7; //смещаем на 7 бит
      if (signBytePos != 0) { //если что-то еще осталось добавляем 8-й бит флаг
        byte = byte | 0x00000080;
      } else { //последний байт - добавляем знак-бит
        byte = byte | 0x00000040;
      }
      ba.writeByte(byte); //пишем текущий байт..
  }
}

возможно перепутал со знаком..

etc 09.12.2009 21:54

bicubic_bublic, s32 вообще-то обычный writeInt/readInt. Единственное, что нужно читать ручками — u30.

bicubic_bublic 09.12.2009 21:56

Цитата:

Сообщение от etc (Сообщение 871572)
bicubic_bublic, s32 вообще-то обычный writeInt/readInt. Единственное, что нужно читать ручками — u30.

s32 - от 1 до 5 байт
readInt - считывает 4 байта

DEAFFF 09.12.2009 22:28

спасибо! ))) буду пробовать

etc 09.12.2009 23:25

Цитата:

Сообщение от bicubic_bublic (Сообщение 871573)
s32 - от 1 до 5 байт
readInt - считывает 4 байта

Это у вас какой-то свой s32. А в народе s32 — обычный signed int 32.

bicubic_bublic 09.12.2009 23:27

Цитата:

Сообщение от etc (Сообщение 871591)
Это у вас какой-то свой s32. А в народе s32 — обычный signed int 32.

повторюсь:
Цитата:

The variable-length encoding for u30, u32, and s32 uses one to five bytes, depending on the magnitude of the
value encoded. Each byte contributes its low seven bits to the value. If the high (eighth) bit of a byte is set,
then the next byte of the abcFile is also part of the value. In the case of s32, sign extension is applied: the
seventh bit of the last byte of the encoding is propagated to fill out the 32 bits of the decoded value.
источник: http://www.adobe.com/devnet/actionsc...m2overview.pdf

etc 10.12.2009 09:05

Это всё читается одним и тем же методом. Во всяком случае, за два с половиной года после прочтения этой доки проблем не возникло.
А за терминологию Adobe нужно оторвать руки по пояс.

bicubic_bublic 10.12.2009 11:25

Цитата:

Сообщение от etc (Сообщение 871636)
Это всё читается одним и тем же методом. Во всяком случае, за два с половиной года после прочтения этой доки проблем не возникло.
А за терминологию Adobe нужно оторвать руки по пояс.

а в какой именно документации ошибка - спецификация avm2 или ByteArray?
то есть если я напишу .writeInt(1) - то на выходе будет 1 байт или 4 ?

etc 10.12.2009 11:48

Цитата:

Сообщение от bicubic_bublic (Сообщение 871647)
а в какой именно документации ошибка - спецификация avm2 или ByteArray?

Не ошибка, а изменение терминологии в документации. s32 — вполне себе signed int 32 и без всяких variable-length, как везде. Кроме Adobe.

Цитата:

Сообщение от bicubic_bublic (Сообщение 871647)
то есть если я напишу .writeInt(1) - то на выходе будет 1 байт или 4 ?

Не вижу смысла задавать вопрос, ответ на который известен.

DEAFFF 10.12.2009 12:06

уважаемый etc давайте не будем спорить, мы щаз говорим о разных вещах, вы об общепринятых u32 s32 а мы об условно так же названных но variable-length encoding for u30, u32, and s32 для файла абс виртуальной машины.

etc 10.12.2009 12:12

А я говорю, что всё читается одним и тем же методом.

DEAFFF 10.12.2009 12:57

bicubic_bublic

слушай с u30 и u32 вроде чтение запись работает, правда запись иногда зацикливается...

а s32 вообще странно работает пишу одно число, а считывается другое )))

вот коды:

Код AS3:

public function writeVarUint32(value:uint):void
{
        if (value == 0)
        {
                _byteArray.writeByte(0);
        }
 
        var byte:uint;
        while (value != 0)
        {
                byte = value & 0x0000007f; // отрезаем 7 бит от числа
                value = value >> 7; //смещаем на 7 бит
                if (value != 0)  //если что-то еще осталось добавляем 8-й бит флаг
                {
                        byte = byte | 0x00000080;
                }
                _byteArray.writeByte(byte); //пишем текущий байт..
        }
}
 
public function readVarInt32():int
{
        var result:int = _byteArray.readUnsignedByte();
                if (!(result & 0x00000080))
                        return (result << 25 ) >> 25;
        result = (result & 0x0000007f) | _byteArray.readUnsignedByte()<<7;
                if (!(result & 0x00004000))
                        return (result << 18 ) >> 18;
        result = (result & 0x00003fff) | _byteArray.readUnsignedByte()<<14;
                if (!(result & 0x00200000))
                        return (result << 11 ) >> 11;
        result = (result & 0x001fffff) | _byteArray.readUnsignedByte()<<21;
                if (!(result & 0x10000000))
                        return (result << 4 ) >> 4;
        return (result & 0x0fffffff) | _byteArray.readUnsignedByte()<<28;
}
 
public function writeVarInt32(value:int):void
{
        if (value >= 0)
        {
                writeVarUint32(value);
                return;
        }
 
        var len:uint = 0;
        var abs:uint = - value; // абсолютное значение value;
 
        while (abs != 0) // длина в битах абсолютного значения
        {
                abs = abs >> 1;
                len++;
        }
 
        abs = - value;
 
        var signBytePos:uint = Math.floor(len / 7) + 1; // длина s32, порядковый номер байта в котором содержится знак-бит;
 
        while (signBytePos-- != 0) {
                var byte:uint = abs & 0x0000007f; // отрезаем 7 бит от числа
                abs = abs >> 7; //смещаем на 7 бит
                if (signBytePos != 0) //если что-то еще осталось добавляем 8-й бит флаг
                {
                        byte = byte | 0x00000080;
                }
                else //последний байт - добавляем знак-бит
                {
                        byte = byte | 0x00000040;
                }
                _byteArray.writeByte(byte); //пишем текущий байт..
        }
}

Добавлено через 1 минуту
etc
ребята из swf utils читают почему то по другому ? )) из того что я привел выше в коде функции чтения их

bicubic_bublic 10.12.2009 14:17

да.. немного намудрил с s32
Код AS3:

public function writeVarInt32(value:int):void
{
        if (value == 0)
        {
                _byteArray.writeByte(0);
                return;
        }
 
        var len:uint = 0;
        var signByte:uint = (0x80000000 & uint(value)) >> 25; // знак-бит (перемещаем на место 7го бита)
        var abs:uint = 0x7fffffff & uint(value); // значение без знака
 
        while (abs != 0) // длина в битах
        {
                abs = abs >> 1;
                len++;
        }
 
        abs = 0x7fffffff & uint(value);
 
        var signBytePos:uint = Math.floor(len / 7) + 1; // длина s32, порядковый номер байта в котором содержится знак-бит;
 
        while (signBytePos-- != 0) {
                var byte:uint = abs & 0x0000007f; // отрезаем 7 бит от числа
                abs = abs >> 7; //смещаем на 7 бит
                if (signBytePos != 0) //если что-то еще осталось добавляем 8-й бит флаг
                {
                        byte = byte | 0x00000080;
                }
                else //последний байт - добавляем знак-бит
                {
                        byte = byte | signByte;
                }
                _byteArray.writeByte(byte); //пишем текущий байт..
        }
}


DEAFFF 10.12.2009 14:34

все равно что то не то
записываю число = -22222
получаю = B2 D2 FE FF C7
читая получаю = 2147461426

если записывать просто = 22222
то получим = CE AD 01 FF C7
читаем = 22222

что бы это значило?

bicubic_bublic 10.12.2009 15:06

Цитата:

все равно что то не то
записываю число = -22222
получаю = B2 D2 FE FF C7
читая получаю = 2147461426
с последним байтом какой-то косяк..
кажется так правильнее
Код AS3:

var signByte:uint = (0x80000000 & uint(value)) >>> 25; // используется беззнаковое смещение


DEAFFF 10.12.2009 15:12

не все равно какой то косяк (((

bicubic_bublic 10.12.2009 15:14

как записывается -22222 теперь?
и как считывается скажем 0x40 ?

DEAFFF 10.12.2009 15:19

теперь -22222 записывается так = B2 D2 FE FF 47
читается так = 2147461426

байт 0x40 читается так = -64

bicubic_bublic 10.12.2009 15:24

Код AS3:

        var abs:uint = 0x80000000 | uint(value); // значение без знака
 
        while (abs != 0xffffffff) // длина в битах
        {
                abs = abs >> 1;
                len++;
        }
 
        abs = uint(value);


DEAFFF 10.12.2009 15:24

мне кажется чтение я не то взял ) какое то оно странное и непонятно где в нем берется минус...

bicubic_bublic 10.12.2009 15:25

(result << 25 ) >> 25; - вот тут берется знак

DEAFFF 10.12.2009 15:26

вставил новые строки, при записи зациклолось

Добавлено через 37 секунд
Цитата:

Сообщение от bicubic_bublic (Сообщение 871770)
(result << 25 ) >> 25; - вот тут берется знак

ааа понятно...

bicubic_bublic 10.12.2009 15:36

Код AS3:

public function writeVarInt32(value:int):void
{
        if (value == 0)
        {
                _byteArray.writeByte(0);
                return;
        }
 
        var len:uint = 0; // значимая длина в битах
        var signByte:uint = (0x80000000 & uint(value)) >>> 25; // знак-бит (перемещаем на место 7го бита)
        var abs:uint = uint(value);
 
        while ((abs != 0) && (abs != 0xffffffff))
        {
                abs = abs >> 1;
                len++;
        }
 
        abs = uint(value);
 
        var signBytePos:uint = Math.floor(len / 7) + 1; // длина s32
 
        while (signBytePos-- != 0) {
                var byte:uint = abs & 0x0000007f; // отрезаем 7 бит от числа
                abs = abs >> 7; //смещаем на 7 бит
                if (signBytePos != 0) //если что-то еще осталось добавляем 8-й бит флаг
                {
                        byte = byte | 0x00000080;
                }
                else //последний байт - добавляем знак-бит
                {
                        byte = byte | signByte; // это вообще кажется не обязательно теперь..
                }
                _byteArray.writeByte(byte); //пишем текущий байт..
        }
}


DEAFFF 10.12.2009 15:41

ура заработало! ))))))

Добавлено через 1 минуту
супер спасибо огромное!!!

bicubic_bublic 10.12.2009 16:59

тут еще ошибка была.. нужно было смещать беззнаково
Код AS3:

public function writeVarUint32(value:uint):void
{
        if (value == 0)
        {
                _byteArray.writeByte(0);
        }
 
        var byte:uint;
        while (value != 0)
        {
                byte = value & 0x0000007f; // отрезаем 7 бит от числа
                value = value >>> 7; //смещаем на 7 бит
                if (value != 0)  //если что-то еще осталось добавляем 8-й бит флаг
                {
                        byte = byte | 0x00000080;
                }
                _byteArray.writeByte(byte); //пишем текущий байт..
        }
}


DEAFFF 10.12.2009 20:00

понятно... но вроде и так работало )))

а надо ли сделать так?

Код AS3:

if (value == 0) 
{
        _byteArray.writeByte(0);
        return;
}


bicubic_bublic 10.12.2009 21:58

Цитата:

понятно... но вроде и так работало )))
не работало для чисел больше 0x7fffffff
и да.. разумеется надо прекратить выполнение функции в это случае

DEAFFF 10.12.2009 22:14

ага )


Часовой пояс GMT +4, время: 00:14.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.