1 ! Copyright (C) 2010 Sascha Matzke.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs bson.constants byte-arrays calendar
4 combinators combinators.short-circuit endian io io.encodings
5 io.encodings.binary io.encodings.utf8 io.files
6 io.streams.byte-array kernel locals math namespaces sequences
7 sequences.extras serialize strings typed vectors ;
14 ERROR: unknown-bson-type type msg ;
20 : read-int32 ( -- int32 )
21 4 read signed-le> ; inline
23 : read-longlong ( -- longlong )
24 8 read signed-le> ; inline
26 : read-double ( -- double )
27 8 read le> bits>double ; inline
29 : read-byte-raw ( -- byte-raw )
32 : read-byte ( -- byte )
33 read-byte-raw first ; inline
35 : read-cstring ( -- string )
36 input-stream get utf8 <decoder>
37 "\0" swap stream-read-until drop ; inline
39 : read-sized-string ( length -- string )
40 read binary [ read-cstring ] with-byte-reader ; inline
42 : read-timestamp ( -- timestamp )
43 8 read [ 4 head signed-le> ] [ 4 tail signed-le> ] bi <mongo-timestamp> ;
45 : object-result ( quot -- object )
48 [ clear-assoc ] [ ] [ ] tri state
49 ] dip with-variable ; inline
51 : bson-object-data-read ( -- ? )
52 read-int32 [ f ] [ drop read-elements t ] if-zero ; inline recursive
54 : bson-binary-read ( -- binary )
57 { T_Binary_Default [ read ] }
58 { T_Binary_Bytes_Deprecated [ drop read-int32 read ] }
59 { T_Binary_Custom [ read bytes>object ] }
60 { T_Binary_Function [ read-sized-string ] }
61 { T_Binary_MD5 [ read >string ] }
62 { T_Binary_UUID [ read >string ] }
63 [ "unknown binary sub-type" unknown-bson-type ]
66 TYPED: bson-regexp-read ( -- mdbregexp: mdbregexp )
68 read-cstring >>regexp read-cstring >>options ; inline
70 TYPED: bson-oid-read ( -- oid: oid )
71 read-longlong read-int32 oid boa ; inline
73 : check-object ( assoc -- object )
74 dup dbref-assoc? [ assoc>dbref ] when ; inline
76 TYPED: element-data-read ( type: integer -- object )
78 { T_OID [ bson-oid-read ] }
79 { T_String [ read-int32 read-sized-string ] }
80 { T_Integer [ read-int32 ] }
81 { T_Integer64 [ read-longlong ] }
82 { T_Binary [ bson-binary-read ] }
83 { T_Object [ [ bson-object-data-read drop ] object-result check-object ] }
84 { T_Array [ [ bson-object-data-read drop ] object-result values ] }
85 { T_Double [ read-double ] }
86 { T_Boolean [ read-byte 1 = ] }
87 { T_Date [ read-longlong millis>timestamp ] }
88 { T_Regexp [ bson-regexp-read ] }
89 { T_Timestamp [ read-timestamp ] }
90 { T_Code [ read-int32 read-sized-string ] }
91 { T_ScopedCode [ read-int32 drop read-cstring H{ } clone stream>assoc <mongo-scoped-code> ] }
93 [ "type unknown" unknown-bson-type ]
94 } case ; inline recursive
96 TYPED: (read-object) ( type: integer name: string -- )
97 [ element-data-read ] dip state get set-at ; inline recursive
99 TYPED: (element-read) ( type: integer -- cont?: boolean )
101 [ read-cstring (read-object) t ]
102 [ drop f ] if ; inline recursive
104 : read-elements ( -- )
105 read-byte (element-read)
106 [ read-elements ] when ; inline recursive
110 : stream>assoc ( exemplar -- assoc/f )
112 state [ bson-object-data-read ] with-variable
113 ] keep swap [ drop f ] unless ;
115 : path>bson-sequence ( path -- assoc )
117 [ H{ } stream>assoc ] loop>array