1 USING: accessors assocs bson.constants byte-arrays byte-vectors fry io
2 io.binary io.encodings.string io.encodings.utf8 kernel math namespaces
3 sequences serialize arrays calendar io.encodings ;
9 TUPLE: element { type integer } name ;
11 { size initial: -1 } { read initial: 0 } exemplar
12 result scope element ;
14 : <state> ( exemplar -- state )
16 [ clone >>exemplar ] keep
17 clone [ >>result ] [ V{ } clone [ push ] keep >>scope ] bi
18 V{ } clone [ T_Object "" element boa swap push ] keep >>element ;
20 PREDICATE: bson-eoo < integer T_EOO = ;
21 PREDICATE: bson-not-eoo < integer T_EOO > ;
23 PREDICATE: bson-double < integer T_Double = ;
24 PREDICATE: bson-integer < integer T_Integer = ;
25 PREDICATE: bson-string < integer T_String = ;
26 PREDICATE: bson-object < integer T_Object = ;
27 PREDICATE: bson-array < integer T_Array = ;
28 PREDICATE: bson-binary < integer T_Binary = ;
29 PREDICATE: bson-regexp < integer T_Regexp = ;
30 PREDICATE: bson-binary-bytes < integer T_Binary_Bytes = ;
31 PREDICATE: bson-binary-function < integer T_Binary_Function = ;
32 PREDICATE: bson-binary-uuid < integer T_Binary_UUID = ;
33 PREDICATE: bson-binary-custom < integer T_Binary_Custom = ;
34 PREDICATE: bson-oid < integer T_OID = ;
35 PREDICATE: bson-boolean < integer T_Boolean = ;
36 PREDICATE: bson-date < integer T_Date = ;
37 PREDICATE: bson-null < integer T_NULL = ;
38 PREDICATE: bson-ref < integer T_DBRef = ;
40 GENERIC: element-read ( type -- cont? )
41 GENERIC: element-data-read ( type -- object )
42 GENERIC: element-binary-read ( length type -- object )
44 : byte-array>number ( seq -- number )
45 byte-array>bignum >integer ; inline
47 : get-state ( -- state )
50 : count-bytes ( count -- )
51 [ get-state ] dip '[ _ + ] change-read drop ; inline
53 : read-int32 ( -- int32 )
54 4 [ read byte-array>number ] [ count-bytes ] bi ; inline
56 : read-longlong ( -- longlong )
57 8 [ read byte-array>number ] [ count-bytes ] bi ; inline
59 : read-double ( -- double )
60 8 [ read byte-array>number bits>double ] [ count-bytes ] bi ; inline
62 : read-byte-raw ( -- byte-raw )
63 1 [ read ] [ count-bytes ] bi ; inline
65 : read-byte ( -- byte )
66 read-byte-raw first ; inline
68 : read-cstring ( -- string )
69 input-stream get utf8 <decoder>
70 "\0" swap stream-read-until drop ; inline
72 : read-sized-string ( length -- string )
73 drop read-cstring ; inline
75 : read-element-type ( -- type )
78 : push-element ( type name -- element )
80 [ get-state element>> push ] keep ; inline
82 : pop-element ( -- element )
83 get-state element>> pop ; inline
85 : peek-scope ( -- ht )
86 get-state scope>> peek ; inline
88 : read-elements ( -- )
91 [ read-elements ] when ; inline recursive
93 GENERIC: fix-result ( assoc type -- result )
95 M: bson-object fix-result ( assoc type -- result )
98 M: bson-array fix-result ( assoc type -- result )
102 GENERIC: end-element ( type -- )
104 M: bson-object end-element ( type -- )
107 M: bson-array end-element ( type -- )
110 M: object end-element ( type -- )
114 M: bson-eoo element-read ( type -- cont? )
116 get-state scope>> [ pop ] keep swap ! vec assoc
117 pop-element [ type>> ] keep ! vec assoc element
119 rot length 0 > ! assoc element
120 [ name>> peek-scope set-at t ]
121 [ drop [ get-state ] dip >>result drop f ] if ;
123 M: bson-not-eoo element-read ( type -- cont? )
124 [ peek-scope ] dip ! scope type
125 '[ _ read-cstring push-element [ name>> ] [ type>> ] bi
126 [ element-data-read ] keep
131 : [scope-changer] ( state -- state quot )
132 dup exemplar>> '[ [ [ _ clone ] dip push ] keep ] ; inline
134 : (object-data-read) ( type -- object )
138 [scope-changer] change-scope
139 scope>> peek ; inline
141 M: bson-object element-data-read ( type -- object )
144 M: bson-array element-data-read ( type -- object )
147 M: bson-string element-data-read ( type -- object )
149 read-int32 read-sized-string ;
151 M: bson-integer element-data-read ( type -- object )
155 M: bson-double element-data-read ( type -- double )
159 M: bson-boolean element-data-read ( type -- boolean )
163 M: bson-date element-data-read ( type -- timestamp )
165 read-longlong millis>timestamp ;
167 M: bson-binary element-data-read ( type -- binary )
169 read-int32 read-byte element-binary-read ;
171 M: bson-regexp element-data-read ( type -- mdbregexp )
173 read-cstring >>regexp read-cstring >>options ;
175 M: bson-null element-data-read ( type -- bf )
179 M: bson-oid element-data-read ( type -- oid )
184 M: bson-binary-custom element-binary-read ( size type -- dbref )
187 read-cstring objref boa ;
189 M: bson-binary-bytes element-binary-read ( size type -- bytes )
192 M: bson-binary-function element-binary-read ( size type -- quot )
193 drop read bytes>object ;
197 : stream>assoc ( exemplar -- assoc bytes-read )
199 [ read-int32 >>size read-elements ] with-variable
200 [ result>> ] [ read>> ] bi ;