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