@@ -131,3 +131,117 @@ public func == (lhs: JSONValue, rhs: JSONValue) -> Bool {
131131 return false
132132 }
133133}
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