blob: fead65efdf8896df1db9619374bdfe0ddaf91cd6 [file] [log] [blame]
Austin Schuh58b9b472020-11-25 19:12:44 -08001/*
James Kuszmaul8e62b022022-03-22 09:33:25 -07002 * Copyright 2021 Google Inc. All rights reserved.
Austin Schuh58b9b472020-11-25 19:12:44 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Austin Schuh2dd86a92022-09-14 21:19:23 -070017#if !os(WASI)
Austin Schuh272c6132020-11-14 16:37:52 -080018import Foundation
Austin Schuh2dd86a92022-09-14 21:19:23 -070019#else
20import SwiftOverlayShims
21#endif
Austin Schuh272c6132020-11-14 16:37:52 -080022
James Kuszmaul8e62b022022-03-22 09:33:25 -070023/// `ByteBuffer` is the interface that stores the data for a `Flatbuffers` object
24/// it allows users to write and read data directly from memory thus the use of its
25/// functions should be used
26@frozen
Austin Schuh272c6132020-11-14 16:37:52 -080027public struct ByteBuffer {
Austin Schuh272c6132020-11-14 16:37:52 -080028
Austin Schuh58b9b472020-11-25 19:12:44 -080029 /// Storage is a container that would hold the memory pointer to solve the issue of
30 /// deallocating the memory that was held by (memory: UnsafeMutableRawPointer)
31 @usableFromInline
32 final class Storage {
33 // This storage doesn't own the memory, therefore, we won't deallocate on deinit.
34 private let unowned: Bool
35 /// pointer to the start of the buffer object in memory
36 var memory: UnsafeMutableRawPointer
37 /// Capacity of UInt8 the buffer can hold
38 var capacity: Int
Austin Schuh272c6132020-11-14 16:37:52 -080039
James Kuszmaul8e62b022022-03-22 09:33:25 -070040 @usableFromInline
Austin Schuh58b9b472020-11-25 19:12:44 -080041 init(count: Int, alignment: Int) {
James Kuszmaul8e62b022022-03-22 09:33:25 -070042 memory = UnsafeMutableRawPointer.allocate(
43 byteCount: count,
44 alignment: alignment)
Austin Schuh58b9b472020-11-25 19:12:44 -080045 capacity = count
46 unowned = false
Austin Schuh272c6132020-11-14 16:37:52 -080047 }
48
James Kuszmaul8e62b022022-03-22 09:33:25 -070049 @usableFromInline
Austin Schuh58b9b472020-11-25 19:12:44 -080050 init(memory: UnsafeMutableRawPointer, capacity: Int, unowned: Bool) {
51 self.memory = memory
52 self.capacity = capacity
53 self.unowned = unowned
Austin Schuh272c6132020-11-14 16:37:52 -080054 }
55
Austin Schuh58b9b472020-11-25 19:12:44 -080056 deinit {
57 if !unowned {
58 memory.deallocate()
59 }
Austin Schuh272c6132020-11-14 16:37:52 -080060 }
61
James Kuszmaul8e62b022022-03-22 09:33:25 -070062 @usableFromInline
Austin Schuh58b9b472020-11-25 19:12:44 -080063 func copy(from ptr: UnsafeRawPointer, count: Int) {
64 assert(
65 !unowned,
66 "copy should NOT be called on a buffer that is built by assumingMemoryBound")
67 memory.copyMemory(from: ptr, byteCount: count)
Austin Schuh272c6132020-11-14 16:37:52 -080068 }
69
James Kuszmaul8e62b022022-03-22 09:33:25 -070070 @usableFromInline
Austin Schuh58b9b472020-11-25 19:12:44 -080071 func initialize(for size: Int) {
72 assert(
73 !unowned,
74 "initalize should NOT be called on a buffer that is built by assumingMemoryBound")
75 memset(memory, 0, size)
Austin Schuh272c6132020-11-14 16:37:52 -080076 }
77
Austin Schuh58b9b472020-11-25 19:12:44 -080078 /// Reallocates the buffer incase the object to be written doesnt fit in the current buffer
79 /// - Parameter size: Size of the current object
80 @usableFromInline
James Kuszmaul8e62b022022-03-22 09:33:25 -070081 func reallocate(_ size: Int, writerSize: Int, alignment: Int) {
Austin Schuh58b9b472020-11-25 19:12:44 -080082 let currentWritingIndex = capacity &- writerSize
83 while capacity <= writerSize &+ size {
84 capacity = capacity << 1
85 }
Austin Schuh272c6132020-11-14 16:37:52 -080086
Austin Schuh58b9b472020-11-25 19:12:44 -080087 /// solution take from Apple-NIO
88 capacity = capacity.convertToPowerofTwo
Austin Schuh272c6132020-11-14 16:37:52 -080089
James Kuszmaul8e62b022022-03-22 09:33:25 -070090 let newData = UnsafeMutableRawPointer.allocate(
91 byteCount: capacity,
92 alignment: alignment)
Austin Schuh58b9b472020-11-25 19:12:44 -080093 memset(newData, 0, capacity &- writerSize)
94 memcpy(
95 newData.advanced(by: capacity &- writerSize),
96 memory.advanced(by: currentWritingIndex),
97 writerSize)
98 memory.deallocate()
99 memory = newData
Austin Schuh272c6132020-11-14 16:37:52 -0800100 }
Austin Schuh58b9b472020-11-25 19:12:44 -0800101 }
Austin Schuh272c6132020-11-14 16:37:52 -0800102
Austin Schuh58b9b472020-11-25 19:12:44 -0800103 @usableFromInline var _storage: Storage
Austin Schuh272c6132020-11-14 16:37:52 -0800104
Austin Schuh58b9b472020-11-25 19:12:44 -0800105 /// The size of the elements written to the buffer + their paddings
106 private var _writerSize: Int = 0
107 /// Aliginment of the current memory being written to the buffer
James Kuszmaul8e62b022022-03-22 09:33:25 -0700108 var alignment = 1
Austin Schuh58b9b472020-11-25 19:12:44 -0800109 /// Current Index which is being used to write to the buffer, it is written from the end to the start of the buffer
James Kuszmaul8e62b022022-03-22 09:33:25 -0700110 var writerIndex: Int { _storage.capacity &- _writerSize }
Austin Schuh272c6132020-11-14 16:37:52 -0800111
Austin Schuh58b9b472020-11-25 19:12:44 -0800112 /// Reader is the position of the current Writer Index (capacity - size)
113 public var reader: Int { writerIndex }
114 /// Current size of the buffer
115 public var size: UOffset { UOffset(_writerSize) }
116 /// Public Pointer to the buffer object in memory. This should NOT be modified for any reason
117 public var memory: UnsafeMutableRawPointer { _storage.memory }
118 /// Current capacity for the buffer
119 public var capacity: Int { _storage.capacity }
Austin Schuh272c6132020-11-14 16:37:52 -0800120
Austin Schuh58b9b472020-11-25 19:12:44 -0800121 /// Constructor that creates a Flatbuffer object from a UInt8
122 /// - Parameter bytes: Array of UInt8
123 public init(bytes: [UInt8]) {
124 var b = bytes
125 _storage = Storage(count: bytes.count, alignment: alignment)
126 _writerSize = _storage.capacity
127 b.withUnsafeMutableBytes { bufferPointer in
128 self._storage.copy(from: bufferPointer.baseAddress!, count: bytes.count)
Austin Schuh272c6132020-11-14 16:37:52 -0800129 }
Austin Schuh58b9b472020-11-25 19:12:44 -0800130 }
Austin Schuh272c6132020-11-14 16:37:52 -0800131
Austin Schuh2dd86a92022-09-14 21:19:23 -0700132 #if !os(WASI)
Austin Schuh58b9b472020-11-25 19:12:44 -0800133 /// Constructor that creates a Flatbuffer from the Swift Data type object
134 /// - Parameter data: Swift data Object
135 public init(data: Data) {
136 var b = data
137 _storage = Storage(count: data.count, alignment: alignment)
138 _writerSize = _storage.capacity
139 b.withUnsafeMutableBytes { bufferPointer in
140 self._storage.copy(from: bufferPointer.baseAddress!, count: data.count)
Austin Schuh272c6132020-11-14 16:37:52 -0800141 }
Austin Schuh58b9b472020-11-25 19:12:44 -0800142 }
Austin Schuh2dd86a92022-09-14 21:19:23 -0700143 #endif
Austin Schuh272c6132020-11-14 16:37:52 -0800144
Austin Schuh58b9b472020-11-25 19:12:44 -0800145 /// Constructor that creates a Flatbuffer instance with a size
146 /// - Parameter size: Length of the buffer
147 init(initialSize size: Int) {
148 let size = size.convertToPowerofTwo
149 _storage = Storage(count: size, alignment: alignment)
150 _storage.initialize(for: size)
151 }
Austin Schuh272c6132020-11-14 16:37:52 -0800152
Austin Schuh2dd86a92022-09-14 21:19:23 -0700153 #if swift(>=5.0) && !os(WASI)
Austin Schuh58b9b472020-11-25 19:12:44 -0800154 /// Constructor that creates a Flatbuffer object from a ContiguousBytes
155 /// - Parameters:
156 /// - contiguousBytes: Binary stripe to use as the buffer
157 /// - count: amount of readable bytes
158 public init<Bytes: ContiguousBytes>(
159 contiguousBytes: Bytes,
160 count: Int)
161 {
162 _storage = Storage(count: count, alignment: alignment)
163 _writerSize = _storage.capacity
164 contiguousBytes.withUnsafeBytes { buf in
165 _storage.copy(from: buf.baseAddress!, count: buf.count)
Austin Schuh272c6132020-11-14 16:37:52 -0800166 }
Austin Schuh58b9b472020-11-25 19:12:44 -0800167 }
168 #endif
Austin Schuh272c6132020-11-14 16:37:52 -0800169
Austin Schuh58b9b472020-11-25 19:12:44 -0800170 /// Constructor that creates a Flatbuffer from unsafe memory region without copying
171 /// - Parameter assumingMemoryBound: The unsafe memory region
172 /// - Parameter capacity: The size of the given memory region
James Kuszmaul8e62b022022-03-22 09:33:25 -0700173 public init(
174 assumingMemoryBound memory: UnsafeMutableRawPointer,
175 capacity: Int)
176 {
Austin Schuh58b9b472020-11-25 19:12:44 -0800177 _storage = Storage(memory: memory, capacity: capacity, unowned: true)
178 _writerSize = capacity
179 }
180
181 /// Creates a copy of the buffer that's being built by calling sizedBuffer
182 /// - Parameters:
183 /// - memory: Current memory of the buffer
184 /// - count: count of bytes
James Kuszmaul8e62b022022-03-22 09:33:25 -0700185 init(memory: UnsafeMutableRawPointer, count: Int) {
Austin Schuh58b9b472020-11-25 19:12:44 -0800186 _storage = Storage(count: count, alignment: alignment)
187 _storage.copy(from: memory, count: count)
188 _writerSize = _storage.capacity
189 }
190
191 /// Creates a copy of the existing flatbuffer, by copying it to a different memory.
192 /// - Parameters:
193 /// - memory: Current memory of the buffer
194 /// - count: count of bytes
195 /// - removeBytes: Removes a number of bytes from the current size
James Kuszmaul8e62b022022-03-22 09:33:25 -0700196 init(
197 memory: UnsafeMutableRawPointer,
198 count: Int,
199 removing removeBytes: Int)
200 {
Austin Schuh58b9b472020-11-25 19:12:44 -0800201 _storage = Storage(count: count, alignment: alignment)
202 _storage.copy(from: memory, count: count)
203 _writerSize = removeBytes
204 }
205
206 /// Fills the buffer with padding by adding to the writersize
207 /// - Parameter padding: Amount of padding between two to be serialized objects
Austin Schuh2dd86a92022-09-14 21:19:23 -0700208 @inline(__always)
Austin Schuh58b9b472020-11-25 19:12:44 -0800209 @usableFromInline
210 mutating func fill(padding: Int) {
211 assert(padding >= 0, "Fill should be larger than or equal to zero")
212 ensureSpace(size: padding)
213 _writerSize = _writerSize &+ (MemoryLayout<UInt8>.size &* padding)
214 }
215
James Kuszmaul8e62b022022-03-22 09:33:25 -0700216 /// Adds an array of type Scalar to the buffer memory
Austin Schuh58b9b472020-11-25 19:12:44 -0800217 /// - Parameter elements: An array of Scalars
Austin Schuh2dd86a92022-09-14 21:19:23 -0700218 @inline(__always)
Austin Schuh58b9b472020-11-25 19:12:44 -0800219 @usableFromInline
220 mutating func push<T: Scalar>(elements: [T]) {
221 let size = elements.count &* MemoryLayout<T>.size
222 ensureSpace(size: size)
223 elements.reversed().forEach { s in
224 push(value: s, len: MemoryLayout.size(ofValue: s))
Austin Schuh272c6132020-11-14 16:37:52 -0800225 }
Austin Schuh58b9b472020-11-25 19:12:44 -0800226 }
227
James Kuszmaul8e62b022022-03-22 09:33:25 -0700228 /// Adds an object of type NativeStruct into the buffer
Austin Schuh58b9b472020-11-25 19:12:44 -0800229 /// - Parameters:
James Kuszmaul8e62b022022-03-22 09:33:25 -0700230 /// - value: Object that will be written to the buffer
231 /// - size: size to subtract from the WriterIndex
Austin Schuh2dd86a92022-09-14 21:19:23 -0700232 @usableFromInline
James Kuszmaul8e62b022022-03-22 09:33:25 -0700233 @inline(__always)
234 mutating func push<T: NativeStruct>(struct value: T, size: Int) {
Austin Schuh58b9b472020-11-25 19:12:44 -0800235 ensureSpace(size: size)
Austin Schuh58b9b472020-11-25 19:12:44 -0800236 var v = value
James Kuszmaul8e62b022022-03-22 09:33:25 -0700237 memcpy(_storage.memory.advanced(by: writerIndex &- size), &v, size)
238 _writerSize = _writerSize &+ size
Austin Schuh58b9b472020-11-25 19:12:44 -0800239 }
240
241 /// Adds an object of type Scalar into the buffer
242 /// - Parameters:
243 /// - value: Object that will be written to the buffer
244 /// - len: Offset to subtract from the WriterIndex
Austin Schuh2dd86a92022-09-14 21:19:23 -0700245 @inline(__always)
Austin Schuh58b9b472020-11-25 19:12:44 -0800246 @usableFromInline
247 mutating func push<T: Scalar>(value: T, len: Int) {
248 ensureSpace(size: len)
249 var v = value
250 memcpy(_storage.memory.advanced(by: writerIndex &- len), &v, len)
251 _writerSize = _writerSize &+ len
252 }
253
254 /// Adds a string to the buffer using swift.utf8 object
255 /// - Parameter str: String that will be added to the buffer
256 /// - Parameter len: length of the string
Austin Schuh2dd86a92022-09-14 21:19:23 -0700257 @inline(__always)
Austin Schuh58b9b472020-11-25 19:12:44 -0800258 @usableFromInline
259 mutating func push(string str: String, len: Int) {
260 ensureSpace(size: len)
James Kuszmaul8e62b022022-03-22 09:33:25 -0700261 if str.utf8
262 .withContiguousStorageIfAvailable({ self.push(bytes: $0, len: len) }) !=
263 nil
264 {
Austin Schuh58b9b472020-11-25 19:12:44 -0800265 } else {
266 let utf8View = str.utf8
267 for c in utf8View.reversed() {
268 push(value: c, len: 1)
269 }
270 }
271 }
272
273 /// Writes a string to Bytebuffer using UTF8View
274 /// - Parameters:
275 /// - bytes: Pointer to the view
276 /// - len: Size of string
Austin Schuh2dd86a92022-09-14 21:19:23 -0700277 @usableFromInline
James Kuszmaul8e62b022022-03-22 09:33:25 -0700278 @inline(__always)
279 mutating func push(
Austin Schuh58b9b472020-11-25 19:12:44 -0800280 bytes: UnsafeBufferPointer<String.UTF8View.Element>,
281 len: Int) -> Bool
282 {
283 memcpy(
284 _storage.memory.advanced(by: writerIndex &- len),
285 UnsafeRawPointer(bytes.baseAddress!),
286 len)
287 _writerSize = _writerSize &+ len
288 return true
289 }
290
291 /// Write stores an object into the buffer directly or indirectly.
292 ///
293 /// Direct: ignores the capacity of buffer which would mean we are referring to the direct point in memory
294 /// indirect: takes into respect the current capacity of the buffer (capacity - index), writing to the buffer from the end
295 /// - Parameters:
296 /// - value: Value that needs to be written to the buffer
297 /// - index: index to write to
298 /// - direct: Should take into consideration the capacity of the buffer
Austin Schuh2dd86a92022-09-14 21:19:23 -0700299 @inline(__always)
Austin Schuh58b9b472020-11-25 19:12:44 -0800300 func write<T>(value: T, index: Int, direct: Bool = false) {
301 var index = index
302 if !direct {
303 index = _storage.capacity &- index
304 }
305 assert(index < _storage.capacity, "Write index is out of writing bound")
306 assert(index >= 0, "Writer index should be above zero")
307 _storage.memory.storeBytes(of: value, toByteOffset: index, as: T.self)
308 }
309
310 /// Makes sure that buffer has enouch space for each of the objects that will be written into it
311 /// - Parameter size: size of object
312 @discardableResult
Austin Schuh2dd86a92022-09-14 21:19:23 -0700313 @usableFromInline
James Kuszmaul8e62b022022-03-22 09:33:25 -0700314 @inline(__always)
Austin Schuh58b9b472020-11-25 19:12:44 -0800315 mutating func ensureSpace(size: Int) -> Int {
316 if size &+ _writerSize > _storage.capacity {
317 _storage.reallocate(size, writerSize: _writerSize, alignment: alignment)
318 }
319 assert(size < FlatBufferMaxSize, "Buffer can't grow beyond 2 Gigabytes")
320 return size
321 }
322
323 /// pops the written VTable if it's already written into the buffer
324 /// - Parameter size: size of the `VTable`
Austin Schuh2dd86a92022-09-14 21:19:23 -0700325 @usableFromInline
James Kuszmaul8e62b022022-03-22 09:33:25 -0700326 @inline(__always)
327 mutating func pop(_ size: Int) {
328 assert(
329 (_writerSize &- size) > 0,
330 "New size should NOT be a negative number")
Austin Schuh58b9b472020-11-25 19:12:44 -0800331 memset(_storage.memory.advanced(by: writerIndex), 0, _writerSize &- size)
332 _writerSize = size
333 }
334
335 /// Clears the current size of the buffer
Austin Schuh2dd86a92022-09-14 21:19:23 -0700336 @inline(__always)
Austin Schuh58b9b472020-11-25 19:12:44 -0800337 mutating public func clearSize() {
338 _writerSize = 0
339 }
340
341 /// Clears the current instance of the buffer, replacing it with new memory
Austin Schuh2dd86a92022-09-14 21:19:23 -0700342 @inline(__always)
Austin Schuh58b9b472020-11-25 19:12:44 -0800343 mutating public func clear() {
344 _writerSize = 0
345 alignment = 1
346 _storage.initialize(for: _storage.capacity)
347 }
348
349 /// Reads an object from the buffer
350 /// - Parameters:
351 /// - def: Type of the object
352 /// - position: the index of the object in the buffer
Austin Schuh2dd86a92022-09-14 21:19:23 -0700353 @inline(__always)
Austin Schuh58b9b472020-11-25 19:12:44 -0800354 public func read<T>(def: T.Type, position: Int) -> T {
James Kuszmaul8e62b022022-03-22 09:33:25 -0700355 _storage.memory.advanced(by: position).load(as: T.self)
Austin Schuh58b9b472020-11-25 19:12:44 -0800356 }
357
358 /// Reads a slice from the memory assuming a type of T
359 /// - Parameters:
360 /// - index: index of the object to be read from the buffer
361 /// - count: count of bytes in memory
James Kuszmaul8e62b022022-03-22 09:33:25 -0700362 @inline(__always)
Austin Schuh58b9b472020-11-25 19:12:44 -0800363 public func readSlice<T>(
James Kuszmaul8e62b022022-03-22 09:33:25 -0700364 index: Int,
365 count: Int) -> [T]
Austin Schuh58b9b472020-11-25 19:12:44 -0800366 {
James Kuszmaul8e62b022022-03-22 09:33:25 -0700367 assert(
368 index + count <= _storage.capacity,
369 "Reading out of bounds is illegal")
370 let start = _storage.memory.advanced(by: index)
371 .assumingMemoryBound(to: T.self)
372 let array = UnsafeBufferPointer(start: start, count: count)
Austin Schuh58b9b472020-11-25 19:12:44 -0800373 return Array(array)
374 }
375
Austin Schuh2dd86a92022-09-14 21:19:23 -0700376 #if !os(WASI)
Austin Schuh58b9b472020-11-25 19:12:44 -0800377 /// Reads a string from the buffer and encodes it to a swift string
378 /// - Parameters:
379 /// - index: index of the string in the buffer
380 /// - count: length of the string
381 /// - type: Encoding of the string
Austin Schuh2dd86a92022-09-14 21:19:23 -0700382 @inline(__always)
Austin Schuh58b9b472020-11-25 19:12:44 -0800383 public func readString(
James Kuszmaul8e62b022022-03-22 09:33:25 -0700384 at index: Int,
385 count: Int,
Austin Schuh58b9b472020-11-25 19:12:44 -0800386 type: String.Encoding = .utf8) -> String?
387 {
James Kuszmaul8e62b022022-03-22 09:33:25 -0700388 assert(
389 index + count <= _storage.capacity,
390 "Reading out of bounds is illegal")
391 let start = _storage.memory.advanced(by: index)
392 .assumingMemoryBound(to: UInt8.self)
393 let bufprt = UnsafeBufferPointer(start: start, count: count)
Austin Schuh58b9b472020-11-25 19:12:44 -0800394 return String(bytes: Array(bufprt), encoding: type)
395 }
Austin Schuh2dd86a92022-09-14 21:19:23 -0700396 #else
397 /// Reads a string from the buffer and encodes it to a swift string
398 /// - Parameters:
399 /// - index: index of the string in the buffer
400 /// - count: length of the string
401 /// - type: Encoding of the string
402 @inline(__always)
403 public func readString(
404 at index: Int,
405 count: Int) -> String?
406 {
407 assert(
408 index + count <= _storage.capacity,
409 "Reading out of bounds is illegal")
410 let start = _storage.memory.advanced(by: index)
411 .assumingMemoryBound(to: UInt8.self)
412 let bufprt = UnsafeBufferPointer(start: start, count: count)
413 return String(cString: bufprt.baseAddress!)
414 }
415 #endif
Austin Schuh58b9b472020-11-25 19:12:44 -0800416
417 /// Creates a new Flatbuffer object that's duplicated from the current one
418 /// - Parameter removeBytes: the amount of bytes to remove from the current Size
Austin Schuh2dd86a92022-09-14 21:19:23 -0700419 @inline(__always)
Austin Schuh58b9b472020-11-25 19:12:44 -0800420 public func duplicate(removing removeBytes: Int = 0) -> ByteBuffer {
421 assert(removeBytes > 0, "Can NOT remove negative bytes")
James Kuszmaul8e62b022022-03-22 09:33:25 -0700422 assert(
423 removeBytes < _storage.capacity,
424 "Can NOT remove more bytes than the ones allocated")
Austin Schuh58b9b472020-11-25 19:12:44 -0800425 return ByteBuffer(
426 memory: _storage.memory,
427 count: _storage.capacity,
428 removing: _writerSize &- removeBytes)
429 }
James Kuszmaul8e62b022022-03-22 09:33:25 -0700430
431 /// Returns the written bytes into the ``ByteBuffer``
432 public var underlyingBytes: [UInt8] {
433 let cp = capacity &- writerIndex
434 let start = memory.advanced(by: writerIndex)
435 .bindMemory(to: UInt8.self, capacity: cp)
436
437 let ptr = UnsafeBufferPointer<UInt8>(start: start, count: cp)
438 return Array(ptr)
439 }
440
441 /// SkipPrefix Skips the first 4 bytes in case one of the following
442 /// functions are called `getPrefixedSizeCheckedRoot` & `getPrefixedSizeRoot`
443 /// which allows us to skip the first 4 bytes instead of recreating the buffer
Austin Schuh2dd86a92022-09-14 21:19:23 -0700444 @discardableResult
James Kuszmaul8e62b022022-03-22 09:33:25 -0700445 @usableFromInline
Austin Schuh2dd86a92022-09-14 21:19:23 -0700446 @inline(__always)
447 mutating func skipPrefix() -> Int32 {
James Kuszmaul8e62b022022-03-22 09:33:25 -0700448 _writerSize = _writerSize &- MemoryLayout<Int32>.size
Austin Schuh2dd86a92022-09-14 21:19:23 -0700449 return read(def: Int32.self, position: 0)
James Kuszmaul8e62b022022-03-22 09:33:25 -0700450 }
Austin Schuh2dd86a92022-09-14 21:19:23 -0700451
Austin Schuh272c6132020-11-14 16:37:52 -0800452}
453
454extension ByteBuffer: CustomDebugStringConvertible {
455
Austin Schuh58b9b472020-11-25 19:12:44 -0800456 public var debugDescription: String {
457 """
458 buffer located at: \(_storage.memory), with capacity of \(_storage.capacity)
459 { writerSize: \(_writerSize), readerSize: \(reader), writerIndex: \(writerIndex) }
460 """
461 }
Austin Schuh272c6132020-11-14 16:37:52 -0800462}