| package msgp |
| |
| // size of every object on the wire, |
| // plus type information. gives us |
| // constant-time type information |
| // for traversing composite objects. |
| // |
| var sizes = [256]bytespec{ |
| mnil: {size: 1, extra: constsize, typ: NilType}, |
| mfalse: {size: 1, extra: constsize, typ: BoolType}, |
| mtrue: {size: 1, extra: constsize, typ: BoolType}, |
| mbin8: {size: 2, extra: extra8, typ: BinType}, |
| mbin16: {size: 3, extra: extra16, typ: BinType}, |
| mbin32: {size: 5, extra: extra32, typ: BinType}, |
| mext8: {size: 3, extra: extra8, typ: ExtensionType}, |
| mext16: {size: 4, extra: extra16, typ: ExtensionType}, |
| mext32: {size: 6, extra: extra32, typ: ExtensionType}, |
| mfloat32: {size: 5, extra: constsize, typ: Float32Type}, |
| mfloat64: {size: 9, extra: constsize, typ: Float64Type}, |
| muint8: {size: 2, extra: constsize, typ: UintType}, |
| muint16: {size: 3, extra: constsize, typ: UintType}, |
| muint32: {size: 5, extra: constsize, typ: UintType}, |
| muint64: {size: 9, extra: constsize, typ: UintType}, |
| mint8: {size: 2, extra: constsize, typ: IntType}, |
| mint16: {size: 3, extra: constsize, typ: IntType}, |
| mint32: {size: 5, extra: constsize, typ: IntType}, |
| mint64: {size: 9, extra: constsize, typ: IntType}, |
| mfixext1: {size: 3, extra: constsize, typ: ExtensionType}, |
| mfixext2: {size: 4, extra: constsize, typ: ExtensionType}, |
| mfixext4: {size: 6, extra: constsize, typ: ExtensionType}, |
| mfixext8: {size: 10, extra: constsize, typ: ExtensionType}, |
| mfixext16: {size: 18, extra: constsize, typ: ExtensionType}, |
| mstr8: {size: 2, extra: extra8, typ: StrType}, |
| mstr16: {size: 3, extra: extra16, typ: StrType}, |
| mstr32: {size: 5, extra: extra32, typ: StrType}, |
| marray16: {size: 3, extra: array16v, typ: ArrayType}, |
| marray32: {size: 5, extra: array32v, typ: ArrayType}, |
| mmap16: {size: 3, extra: map16v, typ: MapType}, |
| mmap32: {size: 5, extra: map32v, typ: MapType}, |
| } |
| |
| func init() { |
| // set up fixed fields |
| |
| // fixint |
| for i := mfixint; i < 0x80; i++ { |
| sizes[i] = bytespec{size: 1, extra: constsize, typ: IntType} |
| } |
| |
| // nfixint |
| for i := uint16(mnfixint); i < 0x100; i++ { |
| sizes[uint8(i)] = bytespec{size: 1, extra: constsize, typ: IntType} |
| } |
| |
| // fixstr gets constsize, |
| // since the prefix yields the size |
| for i := mfixstr; i < 0xc0; i++ { |
| sizes[i] = bytespec{size: 1 + rfixstr(i), extra: constsize, typ: StrType} |
| } |
| |
| // fixmap |
| for i := mfixmap; i < 0x90; i++ { |
| sizes[i] = bytespec{size: 1, extra: varmode(2 * rfixmap(i)), typ: MapType} |
| } |
| |
| // fixarray |
| for i := mfixarray; i < 0xa0; i++ { |
| sizes[i] = bytespec{size: 1, extra: varmode(rfixarray(i)), typ: ArrayType} |
| } |
| } |
| |
| // a valid bytespsec has |
| // non-zero 'size' and |
| // non-zero 'typ' |
| type bytespec struct { |
| size uint8 // prefix size information |
| extra varmode // extra size information |
| typ Type // type |
| _ byte // makes bytespec 4 bytes (yes, this matters) |
| } |
| |
| // size mode |
| // if positive, # elements for composites |
| type varmode int8 |
| |
| const ( |
| constsize varmode = 0 // constant size (size bytes + uint8(varmode) objects) |
| extra8 = -1 // has uint8(p[1]) extra bytes |
| extra16 = -2 // has be16(p[1:]) extra bytes |
| extra32 = -3 // has be32(p[1:]) extra bytes |
| map16v = -4 // use map16 |
| map32v = -5 // use map32 |
| array16v = -6 // use array16 |
| array32v = -7 // use array32 |
| ) |
| |
| func getType(v byte) Type { |
| return sizes[v].typ |
| } |