PDA

Просмотр полной версии : protobuf-actionscript3 не пишет тип Number


kyzi007
22.02.2011, 15:49
Насколько я поняла это официально зафиксированный баг.
Может кто-то фиксил напильником?

wvxvw
23.02.2011, 01:13
Я просто не совсем в курсе, а к какому из протобаф типов относится флешевый Number? И нельзя ли заменить на int / uint?

Котяра
23.02.2011, 01:48
не встречал этого бага. А можно подробности?
Вот методы чтения/записи
/** Read a {@code float} field value from the stream. */
public function readFloat():Number {
return readRawLittleEndian32();
}
/** Read a 32-bit little-endian integer from the stream. */
public function readRawLittleEndian32():int {
var b1:int = readRawByte();
var b2:int = readRawByte();
var b3:int = readRawByte();
var b4:int = readRawByte();
return ((b1 & 0xff) ) |
((b2 & 0xff) << 8) |
((b3 & 0xff) << 16) |
((b4 & 0xff) << 24);
}


/** Write a {@code float} field, including tag, to the stream. */
public function writeFloat(fieldNumber:int, value:Number):void {
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
writeRawLittleEndian32(value);
}
/** Write a little-endian 32-bit integer. */
public function writeRawLittleEndian32(value:int):void {
writeRawByte((value ) & 0xFF);
writeRawByte((value >> 8) & 0xFF);
writeRawByte((value >> 16) & 0xFF);
writeRawByte((value >> 24) & 0xFF);
}


UPD. Да есть косяк. Number преобразовывается в int
Мне как то не попадались float в моих проектах. Поэтому баг не замечал.

kyzi007
23.02.2011, 11:56
И еще я смогла прочитать только свою ютф строку:)
То что сделал серверщик недопереварилось.
А я в записях в байтах ни в зуб ногой(
Второй рабочий день и показала ся дубом(

А изменять на инты нельзя.

wvxvw
23.02.2011, 18:27
0 Varint int32, int64, uint32, uint64, sint32, sint64, bool, enum
1 64-bit fixed64, sfixed64, double
2 Length-delimited string, bytes, embedded messages, packed repeated fields
3 Start group groups (deprecated)
4 End group groups (deprecated)
5 32-bit fixed32, sfixed32, float

Это типы которые может записать протобаф. Каким образом вы записиваете флешевый Number?

kyzi007
23.02.2011, 19:24
Я записывала всеми способами которые только есть для чисел в протобуфе, если покопатся в исходниках видно что поддержка намберов там планируется но не доделана.
Как и таинственный тип гроуп который только в константах живет но не обрабатывается.

wvxvw
23.02.2011, 20:15
Хорошо... поставим вопрос по-другому... на каком языке написана принимающая сторона, что принимающая сторона ожидает получить? Самое простое решение было бы записывать Number просто как 8 байт (ByteArray), и тогда если на принимающей стороне существует аналог Number от туда его и прочитать. Есть еще вариант, записать Number как 2 int64, один знаковый для целой части, другой - нет - для дробной. Этого бы точно хватило, чтобы Number поместился. Но это ровно в 2 раза больше, чем нужно для того, чтобы записать Number.

kyzi007
23.02.2011, 20:44
Так я в самом флеше не могу прочитать что сформировала.
Делать два инта мне запретили.
Чесно гря даже не знаю на чем сервер, помоему на си.

Они хотят чтобы все работало без костылей. И без правки серверной части протобуфа.
А дробные числа будут туда-сюда летать толпами и со свистом...

Alex Lexcuk
23.02.2011, 21:13
если он дробные не может передавать, прийдется альтернативы использовать: байтаррай, строкой, можно нумбер умножить на 10000 и получиться инт, сервер один фиг, чего то делает с данными, пусть делит инт на 10000 и будут нормальные нумберы.

wvxvw
23.02.2011, 23:18
Ну дробные - вы определитесь, может вам хватит float? И вы не ответили на вопрос. Как сервер присылает Number - откуда вы его пробуете прочитать? (В protobuf есть float - это, на сколько я понимаю 32 бита, и есть double, это, по-идее и должен быть флешевый Number). Если мое предположение правильное, то используйте соответствующие методы ByteArray - read/writeFloat и read/writeDouble... Я не уверен какой endian используется в protobuf, но, опять же, вариантов у вас всего два, если не big endian, то small endian.

kyzi007
24.02.2011, 11:59
Рид-врайт флоат я пробовала, а вот дабл нет.
Флоаты читаются не верно(
А прочитать я пробую с тестового файлика который мне сделал серверщк.

wvxvw
24.02.2011, 14:18
Ну напишите по байтам, как записано, и как должно прочитаться...

kyzi007
24.02.2011, 14:52
если он дробные не может передавать, прийдется альтернативы использовать: байтаррай, строкой, можно нумбер умножить на 10000 и получиться инт, сервер один фиг, чего то делает с данными, пусть делит инт на 10000 и будут нормальные нумберы.
Нет такое решение не возможно потому что там в будущем и так будут мат расчеты на грани тормозов.

В любом случае нужны еще массивы (в ас порте их нету) и тд, пока тему заморозили, серверщик другим занимается.
Ну напишите по байтам, как записано, и как должно прочитаться...


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

wvxvw
24.02.2011, 15:52
В байте 8 бит, каждый бит можно представить как либо 0 либо 1, таким образом байт можно представить как набор из 8 чисел, каждое из которых - либо еденица, либо ноль. Такая схема записи может быть всегда интерпретирована как число в доичной записи. Есть 2 варианта интерпретации: значимые биты (единицы) в начале и значимые биты в конце. Эти способы так же извесны как endian - big endian и little endian. Далее, способы записи различаются еще и тем, что иногда можно прочитать один (как правило первый) бит как знак числа (если это происходят, то этот бит называют знаковым, а запись sint, sbigint и так далее), если это не происходят, то говорят, что число беззнаковое, и называют его uint, например. Как правило, если явно не указано, что число беззнаковое, предполагается, что оно со знаком. Далее, если за названием следует цифра, то она подразумевает количество бит отведенных на запись, например uint32 - беззнаковое целое число занимающее 32 бита. Кроме этого существуют еще fixed, float, double и много других, fixed - число, в котором определенное количество бит отводится на запись целой и дробной части. float - число, которое записывается по определенным правилам, и состоит из двух числел, которые нужно перемножить и длины дробной части, которую нужно оставить после умножения. Как правило одно из чисел не записывается, т.как оно - константа извесная парсеру. double - как правило имеется в виду практически то же самое, что и float, но в 2 раза длиннее.

Еще одна из общепринятых форм записи байтов - шестнадцатеричная. Это похоже на бинарную (1 и 0), но соответствует следующим правилам: сначала оговаривается, используется ли big endian или little endian, а потом содержание байта чистается так, как будто это uint8 (беззнаковое целое число преставленное восмью битами информации). В AS3 (как и во многих других языках) существует даже специальная форма записи для шестнадцатиричных чисел, например: 0xDEADBEEF - число записаное в такой системе.

Так вот, прочитайте из ByteArray то место, где записан Number, например, побайтово, и запостите сюда их содержание, предварительно указав, используется ли big endian или small endian. :)

kyzi007
24.02.2011, 17:22
Спасибо огромное, как только будет свободная секунда все сделаю!