@@ -130,3 +130,117 @@ public func == (lhs: JSONValue, rhs: JSONValue) -> Bool {
130
130
return false
131
131
}
132
132
}
133
+
134
+ @available ( * , deprecated, message: " Don't use this, this is slow " )
135
+ class WritableBuffer {
136
+ private var ptr : UnsafeMutableRawBufferPointer
137
+
138
+ @usableFromInline typealias _Index = UInt32
139
+ @usableFromInline typealias _Capacity = UInt32
140
+
141
+ @usableFromInline var _index : _Index = 0
142
+ @usableFromInline var _capacity : _Capacity = 6144
143
+
144
+ init ( ) {
145
+ self . ptr = UnsafeMutableRawBufferPointer . allocate ( byteCount: Int ( _capacity) , alignment: 0 )
146
+ }
147
+
148
+ @inline ( __always) func write( _ ptr: UnsafeRawBufferPointer ) {
149
+ let bytesCount = ptr. count
150
+ let target = UnsafeMutableRawBufferPointer ( rebasing: self . ptr. dropFirst ( Int ( _index) ) )
151
+ target. copyBytes ( from: ptr)
152
+ self . _index += _Index ( bytesCount)
153
+ }
154
+
155
+ @inline ( __always) func write( byte: UInt8 ) {
156
+ self . ptr [ Int ( self . _index) ] = byte
157
+ self . _index += 1
158
+ }
159
+
160
+ @inline ( __always) func toBytes( ) -> [ UInt8 ] {
161
+ return [ UInt8] ( ptr)
162
+ }
163
+ }
164
+
165
+ extension WritableBuffer {
166
+
167
+ func write( json: JSONValue ) {
168
+
169
+ switch json {
170
+ case . null:
171
+ self . write ( byte: UInt8 ( ascii: " n " ) )
172
+ self . write ( byte: UInt8 ( ascii: " u " ) )
173
+ self . write ( byte: UInt8 ( ascii: " l " ) )
174
+ self . write ( byte: UInt8 ( ascii: " l " ) )
175
+
176
+ case . bool( true ) :
177
+ self . write ( byte: UInt8 ( ascii: " t " ) )
178
+ self . write ( byte: UInt8 ( ascii: " r " ) )
179
+ self . write ( byte: UInt8 ( ascii: " u " ) )
180
+ self . write ( byte: UInt8 ( ascii: " e " ) )
181
+
182
+ case . bool( false ) :
183
+ self . write ( byte: UInt8 ( ascii: " f " ) )
184
+ self . write ( byte: UInt8 ( ascii: " a " ) )
185
+ self . write ( byte: UInt8 ( ascii: " l " ) )
186
+ self . write ( byte: UInt8 ( ascii: " s " ) )
187
+ self . write ( byte: UInt8 ( ascii: " e " ) )
188
+
189
+ case . string( let string) :
190
+ self . write ( byte: UInt8 ( ascii: " \" " ) )
191
+ string. utf8. withContiguousStorageIfAvailable {
192
+ self . write ( UnsafeRawBufferPointer ( $0) )
193
+ }
194
+ self . write ( byte: UInt8 ( ascii: " \" " ) )
195
+ case . number( let string) :
196
+ string. utf8. withContiguousStorageIfAvailable {
197
+ self . write ( UnsafeRawBufferPointer ( $0) )
198
+ }
199
+ case . array( let array) :
200
+ var iterator = array. makeIterator ( )
201
+ self . write ( byte: UInt8 ( ascii: " [ " ) )
202
+ // we don't like branching, this is why we have this extra
203
+ if let first = iterator. next ( ) {
204
+ self . write ( json: first)
205
+ }
206
+ while let item = iterator. next ( ) {
207
+ self . write ( byte: UInt8 ( ascii: " , " ) )
208
+ self . write ( json: item)
209
+ }
210
+ self . write ( byte: UInt8 ( ascii: " ] " ) )
211
+ case . object( let dict) :
212
+ var iterator = dict. makeIterator ( )
213
+ self . write ( byte: UInt8 ( ascii: " { " ) )
214
+ if let ( key, value) = iterator. next ( ) {
215
+ self . write ( byte: UInt8 ( ascii: " \" " ) )
216
+ key. utf8. withContiguousStorageIfAvailable {
217
+ self . write ( UnsafeRawBufferPointer ( $0) )
218
+ }
219
+ self . write ( byte: UInt8 ( ascii: " \" " ) )
220
+ self . write ( byte: UInt8 ( ascii: " : " ) )
221
+ self . write ( json: value)
222
+ }
223
+ while let ( key, value) = iterator. next ( ) {
224
+ self . write ( byte: UInt8 ( ascii: " , " ) )
225
+ self . write ( byte: UInt8 ( ascii: " \" " ) )
226
+ key. utf8. withContiguousStorageIfAvailable {
227
+ self . write ( UnsafeRawBufferPointer ( $0) )
228
+ }
229
+ self . write ( byte: UInt8 ( ascii: " \" " ) )
230
+ self . write ( byte: UInt8 ( ascii: " : " ) )
231
+ self . write ( json: value)
232
+ }
233
+ self . write ( byte: UInt8 ( ascii: " } " ) )
234
+ }
235
+ }
236
+ }
237
+
238
+ extension JSONValue {
239
+
240
+ @available ( * , deprecated, message: " Don't use this, this is slow " )
241
+ public func toBytes( ) -> [ UInt8 ] {
242
+ let buffer = WritableBuffer ( )
243
+ buffer. write ( json: self )
244
+ return buffer. toBytes ( )
245
+ }
246
+ }
0 commit comments