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