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