import Foundation class MemoryBuffer { var data: Data var length: Int init(data: Data) { self.data = data self.length = data.count } } final class WriteBuffer: MemoryBuffer { var offset = 0 init() { super.init(data: Data()) } func makeData() -> Data { return self.data } func reset() { self.offset = 0 } func write(_ data: UnsafeRawPointer, offset: Int = 0, length: Int) { if self.offset + length > self.data.count { self.data.count = self.offset + length + 256 } self.data.withUnsafeMutableBytes { bytes in let _ = memcpy(bytes.baseAddress!.advanced(by: self.offset), data + offset, length) } self.offset += length self.length = self.offset } func write(_ data: Data) { data.withUnsafeBytes { bytes in self.write(bytes.baseAddress!, length: bytes.count) } } func writeInt8(_ value: Int8) { var value = value self.write(&value, length: 1) } func writeInt32(_ value: Int32) { var value = value self.write(&value, length: 4) } func writeFloat(_ value: Float) { var value: Float32 = value self.write(&value, length: 4) } func seek(offset: Int) { self.offset = offset } } final class ReadBuffer: MemoryBuffer { var offset = 0 override init(data: Data) { super.init(data: data) } func read(_ data: UnsafeMutableRawPointer, length: Int) { self.data.copyBytes(to: data.assumingMemoryBound(to: UInt8.self), from: self.offset ..< (self.offset + length)) self.offset += length } func readDataNoCopy(length: Int) -> Data { let result = self.data.withUnsafeBytes { bytes -> Data in return Data(bytesNoCopy: UnsafeMutableRawPointer(mutating: bytes.baseAddress!.advanced(by: self.offset)), count: length, deallocator: .none) } self.offset += length return result } func readInt8() -> Int8 { var result: Int8 = 0 self.read(&result, length: 1) return result } func readInt32() -> Int32 { var result: Int32 = 0 self.read(&result, length: 4) return result } func readFloat() -> Float { var result: Float32 = 0 self.read(&result, length: 4) return result } func skip(_ length: Int) { self.offset += length } func reset() { self.offset = 0 } }