-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathobjectid.go
126 lines (106 loc) · 2.79 KB
/
objectid.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package bson
import (
"crypto/rand"
"encoding"
"encoding/hex"
"encoding/json"
"errors"
mathrand "math/rand"
"sync/atomic"
"time"
)
var ErrBadObjectID = errors.New("not a valid ObjectID")
// ObjectID represents BSON object ID.
type ObjectID [12]byte
// NewObjectID returns a new ObjectID.
func NewObjectID() ObjectID {
return NewObjectIDWithTime(time.Now())
}
// NewObjectIDWithTime returns a new ObjectID.
func NewObjectIDWithTime(t time.Time) ObjectID {
ts := uint32(t.UTC().Unix())
c := objectIDCounter.Add(1)
var oid ObjectID
oid[0] = byte(ts >> 24)
oid[1] = byte(ts >> 16)
oid[2] = byte(ts >> 8)
oid[3] = byte(ts)
oid[4] = procUniqueID[0]
oid[5] = procUniqueID[1]
oid[6] = procUniqueID[2]
oid[7] = procUniqueID[3]
oid[8] = procUniqueID[4]
oid[9] = byte(c >> 16)
oid[10] = byte(c >> 8)
oid[11] = byte(c)
return oid
}
// String returns a hex string representation of the id.
// Example: ObjectID('64d526fa37931c1e97eea90f').
func (oid ObjectID) String() string {
return "ObjectID('" + hex.EncodeToString(oid[:]) + "')"
}
// MarshalBSON implements [bson.Marshaler].
func (oid *ObjectID) MarshalBSON() ([]byte, error) {
b := make([]byte, len(oid))
copy(b, oid[:])
return b, nil
}
// UnmarshalBSON implements [bson.Unmarshaler].
func (oid *ObjectID) UnmarshalBSON(b []byte) error {
switch len(b) {
case 12:
copy(oid[:], b)
return nil
case 24:
n, err := hex.Decode(oid[:], b)
if n != 12 {
panic("unreachable")
}
return err
default:
return ErrBadObjectID
}
}
// MarshalText implements [encoding.TextMarshaler].
func (oid ObjectID) MarshalText() ([]byte, error) {
return oid.MarshalBSON()
}
// UnmarshalText implements [encoding.TextUnmarshaler].
func (oid *ObjectID) UnmarshalText(b []byte) error {
return oid.UnmarshalBSON(b)
}
// MarshalBinary implements [encoding.BinaryMarshaler].
func (oid ObjectID) MarshalBinary() ([]byte, error) {
return oid.MarshalBSON()
}
// UnmarshalBinary implements [encoding.BinaryUnmarshaler].
func (oid *ObjectID) UnmarshalBinary(b []byte) error {
return oid.UnmarshalBSON(b)
}
// MarshalJSON implements [json.Marshaler].
func (oid ObjectID) MarshalJSON() ([]byte, error) {
return oid.MarshalText()
}
// UnmarshalJSON implements [json.Unmarshaler].
func (oid *ObjectID) UnmarshalJSON(b []byte) error {
return oid.UnmarshalBSON(b)
}
var (
procUniqueID [5]byte
objectIDCounter atomic.Uint32
)
func init() {
must(rand.Read(procUniqueID[:]))
objectIDCounter.Store(mathrand.Uint32())
}
var (
_ Marshaler = &ObjectID{}
_ Unmarshaler = &ObjectID{}
_ encoding.TextMarshaler = &ObjectID{}
_ encoding.TextUnmarshaler = &ObjectID{}
_ encoding.BinaryMarshaler = &ObjectID{}
_ encoding.BinaryUnmarshaler = &ObjectID{}
_ json.Marshaler = &ObjectID{}
_ json.Unmarshaler = &ObjectID{}
)