1// Package cbor provides primitives for storing different data 2// in the CBOR (binary) format. CBOR is defined in RFC7049. 3package cbor 4 5import "time" 6 7const ( 8 majorOffset = 5 9 additionalMax = 23 10 11 // Non Values. 12 additionalTypeBoolFalse byte = 20 13 additionalTypeBoolTrue byte = 21 14 additionalTypeNull byte = 22 15 16 // Integer (+ve and -ve) Sub-types. 17 additionalTypeIntUint8 byte = 24 18 additionalTypeIntUint16 byte = 25 19 additionalTypeIntUint32 byte = 26 20 additionalTypeIntUint64 byte = 27 21 22 // Float Sub-types. 23 additionalTypeFloat16 byte = 25 24 additionalTypeFloat32 byte = 26 25 additionalTypeFloat64 byte = 27 26 additionalTypeBreak byte = 31 27 28 // Tag Sub-types. 29 additionalTypeTimestamp byte = 01 30 31 // Extended Tags - from https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml 32 additionalTypeTagNetworkAddr uint16 = 260 33 additionalTypeTagNetworkPrefix uint16 = 261 34 additionalTypeEmbeddedJSON uint16 = 262 35 additionalTypeTagHexString uint16 = 263 36 37 // Unspecified number of elements. 38 additionalTypeInfiniteCount byte = 31 39) 40const ( 41 majorTypeUnsignedInt byte = iota << majorOffset // Major type 0 42 majorTypeNegativeInt // Major type 1 43 majorTypeByteString // Major type 2 44 majorTypeUtf8String // Major type 3 45 majorTypeArray // Major type 4 46 majorTypeMap // Major type 5 47 majorTypeTags // Major type 6 48 majorTypeSimpleAndFloat // Major type 7 49) 50 51const ( 52 maskOutAdditionalType byte = (7 << majorOffset) 53 maskOutMajorType byte = 31 54) 55 56const ( 57 float32Nan = "\xfa\x7f\xc0\x00\x00" 58 float32PosInfinity = "\xfa\x7f\x80\x00\x00" 59 float32NegInfinity = "\xfa\xff\x80\x00\x00" 60 float64Nan = "\xfb\x7f\xf8\x00\x00\x00\x00\x00\x00" 61 float64PosInfinity = "\xfb\x7f\xf0\x00\x00\x00\x00\x00\x00" 62 float64NegInfinity = "\xfb\xff\xf0\x00\x00\x00\x00\x00\x00" 63) 64 65// IntegerTimeFieldFormat indicates the format of timestamp decoded 66// from an integer (time in seconds). 67var IntegerTimeFieldFormat = time.RFC3339 68 69// NanoTimeFieldFormat indicates the format of timestamp decoded 70// from a float value (time in seconds and nano seconds). 71var NanoTimeFieldFormat = time.RFC3339Nano 72 73func appendCborTypePrefix(dst []byte, major byte, number uint64) []byte { 74 byteCount := 8 75 var minor byte 76 switch { 77 case number < 256: 78 byteCount = 1 79 minor = additionalTypeIntUint8 80 81 case number < 65536: 82 byteCount = 2 83 minor = additionalTypeIntUint16 84 85 case number < 4294967296: 86 byteCount = 4 87 minor = additionalTypeIntUint32 88 89 default: 90 byteCount = 8 91 minor = additionalTypeIntUint64 92 93 } 94 dst = append(dst, byte(major|minor)) 95 byteCount-- 96 for ; byteCount >= 0; byteCount-- { 97 dst = append(dst, byte(number>>(uint(byteCount)*8))) 98 } 99 return dst 100} 101