khenaidoo | ac63710 | 2019-01-14 15:44:34 -0500 | [diff] [blame^] | 1 | // Package cbor provides primitives for storing different data |
| 2 | // in the CBOR (binary) format. CBOR is defined in RFC7049. |
| 3 | package cbor |
| 4 | |
| 5 | import "time" |
| 6 | |
| 7 | const ( |
| 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 | ) |
| 40 | const ( |
| 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 | |
| 51 | const ( |
| 52 | maskOutAdditionalType byte = (7 << majorOffset) |
| 53 | maskOutMajorType byte = 31 |
| 54 | ) |
| 55 | |
| 56 | const ( |
| 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). |
| 67 | var IntegerTimeFieldFormat = time.RFC3339 |
| 68 | |
| 69 | // NanoTimeFieldFormat indicates the format of timestamp decoded |
| 70 | // from a float value (time in seconds and nano seconds). |
| 71 | var NanoTimeFieldFormat = time.RFC3339Nano |
| 72 | |
| 73 | func 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 | } |