I wondering equivalent of Java java.io.ByteArrayOutputStream
or C#’s BinaryWriter
into Swift.
Having some difficulties in the following static public class CustomArrayOutputStream extends java.io.ByteArrayOutputStream
part. I wonder how to achieve the same functionalities in the Swift.
Swift Code
public class CustomSerializer { fileprivate var output: CustomArrayOutputStream func custom_bool(value: Bool) { output.write(value == true ? 1 : 0) } } // Having difficulties to convert it to Swift static public class CustomArrayOutputStream : ?? { public func getBuffer() -> [UInt8] { return buf } }
Java Code:
public class CustomSerializer { protected CustomArrayOutputStream output; public void custom_bool(Boolean value) { output.write(value.booleanValue() ? 1: 0); } } static public class CustomArrayOutputStream extends java.io.ByteArrayOutputStream { public byte[] getBuffer() { return buf; } }
or equivalent of C# BinaryWriter in Swift
protected readonly BinaryWriter output;
Update:
The first case is to achieve something similar
var content:[UInt8] = output.getBuffer() var size: Int = output.size()
but OutputStream
does not have getBuffer()
and size()
do not exist.
or
the second use case, do not know how to convert the following Java into Swift
Java
public int getOffset() { return (int)output.BaseStream.Position; }
Swift
public func getOffset() -> Int { return output.??? }
Advertisement
Answer
For the methods you’re asking for, you could do a very simple implementation using OutputStream, something like this; (have mercy on the code style, I’m rather new at Swift myself)
If you need something more high performance, maybe getting the data to check the offset isn’t the best idea, you may want to extend OutputStream to count bytes as you write instead.
import Foundation public class CustomSerializer { fileprivate var output = OutputStream.toMemory() init() { output.open() } deinit { output.close() } func custom_bool(value: Bool) -> Void { custom_write(value: UInt8(value ? 1 : 0)) } func custom_int(value: Int32) -> Void { custom_write(value: value.bigEndian) } private func custom_write<T>(value: T) -> Void { var value = value let size = MemoryLayout.size(ofValue: value) withUnsafeBytes(of: &value) { ptr in output.write(ptr.baseAddress!.assumingMemoryBound(to: UInt8.self), maxLength: size) } } } extension OutputStream { public func getBuffer() -> [UInt8] { return [UInt8](self.property(forKey: .dataWrittenToMemoryStreamKey) as! Data) } public func getOffset() -> Int { return (self.property(forKey: .dataWrittenToMemoryStreamKey) as! Data).count } } let test = CustomSerializer() test.custom_bool(value: true) test.custom_int(value: 4711) print(test.output.getBuffer()) // [1, 0, 0, 18, 103] print(test.output.getOffset()). // 5