metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2015-09-02 06:11 pm

Генераторы сериализаторов-десериализаторов.

Меня немного удивляет существование protocol buffers, и еще больше удивляет, когда кроме них изобретают еще и Apache Thrift, а потом еще и https://capnproto.org/ и https://google.github.io/flatbuffers/.

Все эти протоколы подразумевают, что система разрабатывается одной и той же командой (или двумя тесно взаимодействующими) с обоих сторон, что типы передаваемых меняются достаточно синхронно, т.е. что протокол за 2-3 итерации не превратится во что-нибудь вроде "у нас тут 100 опциональных полей на каждый случай жизни".

А вот генератора парсеров на случай "протокол дали ембеддеры-психи, засунув в 8 бит 2 флага и 2 поля по 3 бита с длиной дополнительных данных в пакете" или "обвязка протокол описана в виде ABNF в RFC, а в payload опять поселились эмбеддеры с бинарными форматами" я чего-то не видел.

[identity profile] aamonster.livejournal.com 2015-09-04 10:04 am (UTC)(link)
Ну это большое страшное заклинание же должно было вызвать демона?

[identity profile] binf.livejournal.com 2015-09-04 05:53 pm (UTC)(link)
))
ну я не думаю что алгоритм на каком нибудь Си будет проще (двоично-десятичное число из шести цифр):
let (|Digits|) b =  
    decimal(b >>> 4), decimal(b &&& 0x0Fuy) 
 
let (|DecNums2|_|) (Digits (b1,b2)) =  
    if b1<10m && b2<10m then Some(b1,b2) else None 
 
let (|SignComa|) x =  
    let coma = decimal (x &&& 0b111uy )  
    let sign = if (x >>> 7) = 0uy then 1m else (-1m) 
    sign, coma 
 
let (|Bcd6Float|_|) bcd =             
    match Seq.toList bcd with  
    |   SignComa(sign,coma):: 
        DecNums2(d'100'000,d10'000)::DecNums2(d1000,d100)::DecNums2(d10,d1)::_ -> 
        Some( sign*(d'100'000*100000m + d10'000*10000m + d1000*1000m + d100*100m + d10*10m + d1 )/( pow 10m coma ) )  
    | _ -> None


надеюсь, это менее ужасно