Skip to content

Commit 2017ff8

Browse files
committed
bson: support all non-deprecated types and fix int/uint bugs
1 parent b2cb5c3 commit 2017ff8

File tree

4 files changed

+225
-108
lines changed

4 files changed

+225
-108
lines changed

doc/formats.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,10 @@ bplist> from_ns_keyed_archiver(1)
434434

435435
## bson
436436

437+
Limitations:
438+
439+
- The decimal128 type is not supported for decoding, will just be treated as binary
440+
437441
### Convert represented value to JSON
438442

439443
```

format/bson/bson.go

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package bson
22

33
// https://bsonspec.org/spec.html
4-
// TODO: more types
54

65
import (
76
"embed"
@@ -27,42 +26,50 @@ func init() {
2726
}
2827

2928
const (
30-
elementTypeDouble = 0x01
31-
elementTypeString = 0x02
32-
elementTypeDocument = 0x03
33-
elementTypeArray = 0x04
34-
elementTypeBinary = 0x05
35-
elementTypeUndefined = 0x06
36-
elementTypeObjectID = 0x07
37-
elementTypeBoolean = 0x08
38-
elementTypeDatatime = 0x09
39-
elementTypeNull = 0x0a
40-
elementTypeRegexp = 0x0b
41-
elementTypeInt32 = 0x10
42-
elementTypeTimestamp = 0x11
43-
elementTypeInt64 = 0x12
29+
elementTypeDouble = 0x01
30+
elementTypeString = 0x02
31+
elementTypeDocument = 0x03
32+
elementTypeArray = 0x04
33+
elementTypeBinary = 0x05
34+
elementTypeUndefined = 0x06
35+
elementTypeObjectID = 0x07
36+
elementTypeBoolean = 0x08
37+
elementTypeDatetime = 0x09
38+
elementTypeNull = 0x0a
39+
elementTypeRegexp = 0x0b
40+
elementTypeJavaScript = 0x0d
41+
elementTypeInt32 = 0x10
42+
elementTypeTimestamp = 0x11
43+
elementTypeInt64 = 0x12
44+
elementTypeDecimal128 = 0x13
45+
elementTypeMinKey = 0xFF
46+
elementTypeMaxKey = 0x7f
4447
)
4548

4649
var elementTypeMap = scalar.UintMap{
47-
elementTypeDouble: {Sym: "double", Description: "64-bit binary floating point"},
48-
elementTypeString: {Sym: "string", Description: "UTF-8 string"},
49-
elementTypeDocument: {Sym: "document", Description: "Embedded document"},
50-
elementTypeArray: {Sym: "array", Description: "Array"},
51-
elementTypeBinary: {Sym: "binary", Description: "Binary data"},
52-
elementTypeUndefined: {Sym: "undefined", Description: "Undefined (deprecated)"},
53-
elementTypeObjectID: {Sym: "object_id", Description: "ObjectId"},
54-
elementTypeBoolean: {Sym: "boolean", Description: "Boolean"},
55-
elementTypeDatatime: {Sym: "datatime", Description: "UTC datetime"},
56-
elementTypeNull: {Sym: "null", Description: "Null value"},
57-
elementTypeRegexp: {Sym: "regexp", Description: "Regular expression"},
58-
elementTypeInt32: {Sym: "int32", Description: "32-bit integer"},
59-
elementTypeTimestamp: {Sym: "timestamp", Description: "Timestamp"},
60-
elementTypeInt64: {Sym: "int64", Description: "64-bit integer"},
50+
elementTypeDouble: {Sym: "double", Description: "64-bit binary floating point"},
51+
elementTypeString: {Sym: "string", Description: "UTF-8 string"},
52+
elementTypeDocument: {Sym: "document", Description: "Embedded document"},
53+
elementTypeArray: {Sym: "array", Description: "Array"},
54+
elementTypeBinary: {Sym: "binary", Description: "Binary data"},
55+
elementTypeUndefined: {Sym: "undefined", Description: "Undefined (deprecated)"},
56+
elementTypeObjectID: {Sym: "object_id", Description: "ObjectId"},
57+
elementTypeBoolean: {Sym: "boolean", Description: "Boolean"},
58+
elementTypeDatetime: {Sym: "datetime", Description: "UTC datetime"},
59+
elementTypeNull: {Sym: "null", Description: "Null value"},
60+
elementTypeRegexp: {Sym: "regexp", Description: "Regular expression"},
61+
elementTypeJavaScript: {Sym: "javascript", Description: "JavaScript code"},
62+
elementTypeInt32: {Sym: "int32", Description: "32-bit integer"},
63+
elementTypeTimestamp: {Sym: "timestamp", Description: "Timestamp"},
64+
elementTypeInt64: {Sym: "int64", Description: "64-bit integer"},
65+
elementTypeDecimal128: {Sym: "decimal128", Description: "128-bit decimal floating point"},
66+
elementTypeMinKey: {Sym: "minkey", Description: "Min key"},
67+
elementTypeMaxKey: {Sym: "maxkey", Description: "Max key"},
6168
}
6269

6370
func decodeBSONDocument(d *decode.D) {
64-
size := d.FieldU32("size")
65-
d.FramedFn(int64(size-4)*8, func(d *decode.D) {
71+
size := d.FieldS32("size")
72+
d.FramedFn((size-4)*8, func(d *decode.D) {
6673
d.FieldArray("elements", func(d *decode.D) {
6774
for d.BitsLeft() > 8 {
6875
d.FieldStruct("element", func(d *decode.D) {
@@ -79,28 +86,38 @@ func decodeBSONDocument(d *decode.D) {
7986
case elementTypeArray:
8087
d.FieldStruct("value", decodeBSONDocument)
8188
case elementTypeBinary:
82-
length := d.FieldU32("length")
89+
length := d.FieldS32("length")
8390
d.FieldU8("subtype")
84-
d.FieldRawLen("value", int64(length)*8)
91+
d.FieldRawLen("value", length*8)
8592
case elementTypeUndefined:
8693
//deprecated
8794
case elementTypeObjectID:
8895
d.FieldRawLen("value", 12*8)
8996
case elementTypeBoolean:
9097
d.FieldU8("value")
91-
case elementTypeDatatime:
92-
d.FieldS32("value")
98+
case elementTypeDatetime:
99+
d.FieldS64("value")
93100
case elementTypeNull:
94101
d.FieldValueAny("value", nil)
95102
case elementTypeRegexp:
96103
d.FieldUTF8Null("value")
97104
d.FieldUTF8Null("options")
105+
case elementTypeJavaScript:
106+
length := d.FieldS32("length")
107+
d.FieldUTF8NullFixedLen("value", int(length))
98108
case elementTypeInt32:
99109
d.FieldS32("value")
100110
case elementTypeTimestamp:
101111
d.FieldU64("value")
102112
case elementTypeInt64:
103113
d.FieldS64("value")
114+
case elementTypeDecimal128:
115+
// TODO: Parse the IEEE 754 decimal128 value.
116+
d.FieldRawLen("value", 128)
117+
case elementTypeMinKey:
118+
d.FieldValueAny("value", nil)
119+
case elementTypeMaxKey:
120+
d.FieldValueAny("value", nil)
104121
default:
105122
d.FieldRawLen("value", d.BitsLeft())
106123
}

format/bson/testdata/test.bson

206 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)