#pragma author WerWolv #pragma description MessagePack binary serialization format #pragma MIME application/x-msgpack enum Type : u8 { PositiveFixInt = 0x00 ... 0x7F, FixMap = 0x80 ... 0x8F, FixArray = 0x90 ... 0x9F, FixStr = 0xA0 ... 0xBF, Nil = 0xC0, Unused = 0xC1, False = 0xC2, True = 0xC3, Bin8 = 0xC4, Bin16 = 0xC5, Bin32 = 0xC6, Ext8 = 0xC7, Ext16 = 0xC8, Ext32 = 0xC9, Float32 = 0xCA, Float64 = 0xCB, Uint8 = 0xCC, Uint16 = 0xCD, Uint32 = 0xCE, Uint64 = 0xCF, Int8 = 0xD0, Int16 = 0xD1, Int32 = 0xD2, Int64 = 0xD3, FixExt1 = 0xD4, FixExt2 = 0xD5, FixExt4 = 0xD6, FixExt8 = 0xD7, FixExt16 = 0xD8, Str8 = 0xD9, Str16 = 0xDA, Str32 = 0xDB, Array16 = 0xDC, Array32 = 0xDD, Map16 = 0xDE, Map32 = 0xDF, NegativeFixInt = 0xE0 ... 0xFF }; fn format_positive_fixint(u8 value) { return value & 0b0111'1111; }; fn format_negative_fixint(u8 value) { return -(value & 0b0001'1111); }; using MessagePack; struct MapEntry { MessagePack key, value; }; struct MessagePack { Type type; if (u8(type) <= 0x7F) { $ -= 1; u8 value [[format("format_positive_fixint")]]; } else if (u8(type) >= Type::NegativeFixInt) { $ -= 1; u8 value [[format("format_negative_fixint")]]; } else if (type == Type::Uint8) be u8 value; else if (type == Type::Uint16) be u16 value; else if (type == Type::Uint32) be u32 value; else if (type == Type::Uint64) be u64 value; else if (type == Type::Int8) be s8 value; else if (type == Type::Int16) be s16 value; else if (type == Type::Int32) be s32 value; else if (type == Type::Int64) be s64 value; else if (type == Type::Float32) be float value; else if (type == Type::Float64) be double value; else if ((u8(type) & 0b1110'0000) == Type::FixStr) char value[u8(type) & 0b0001'1111]; else if (type == Type::Str8) { be u8 length; char value[length]; } else if (type == Type::Str16) { be u16 length; char value[length]; } else if (type == Type::Str32) { be u32 length; char value[length]; } else if (type == Type::Bin8) { be u8 length; u8 value[length]; } else if (type == Type::Bin16) { be u16 length; u8 value[length]; } else if (type == Type::Bin32) { be u32 length; u8 value[length]; } else if ((u8(type) & 0b1111'0000) == Type::FixArray) MessagePack value[u8(type) & 0b0000'1111]; else if (type == Type::Array16) { be u16 length; MessagePack value[length]; } else if (type == Type::Array32) { be u32 length; MessagePack value[length]; } else if ((u8(type) & 0b1111'0000) == Type::FixMap) MapEntry value[u8(type) & 0b0000'1111]; else if (type == Type::Map16) { be u16 length; MapEntry value[length]; } else if (type == Type::Map32) { be u32 length; MapEntry value[length]; } else if (type == Type::FixExt1) { s8 type; u8 data; } else if (type == Type::FixExt2) { s8 type; u16 data; } else if (type == Type::FixExt4) { s8 type; u32 data; } else if (type == Type::FixExt8) { s8 type; u64 data; } else if (type == Type::FixExt16) { s8 type; u128 data; } else if (type == Type::Ext8) { u8 length; s8 type; if (type == 0x0e) { MessagePack data; } else { u8 data[length]; } } else if (type == Type::Ext16) { u16 length; s8 type; if (type == 0x0e) { MessagePack data; } else { u8 data[length]; } } else if (type == Type::Ext32) { u32 length; s8 type; if (type == 0x0e) { MessagePack data; } else { u8 data[length]; } } }; struct FlowRecord { be u32 length; MessagePack content; }; FlowRecord flowrecord @0x00;