-
-
Save natecook1000/c3ed7164340dbbd45baa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
/* | |
Toying with tools to help read binary formats. | |
I've seen lots of approaches in swift that create | |
an intermediate object per-read (usually another NSData) | |
but even if these are lightweight under the hood, | |
it seems like overkill. Plus this taught me about <()> | |
*/ | |
protocol BinaryReadable { | |
var littleEndian: Self { get } | |
var bigEndian: Self { get } | |
} | |
extension UInt8: BinaryReadable { | |
var littleEndian: UInt8 { return self } | |
var bigEndian: UInt8 { return self } | |
} | |
extension UInt16: BinaryReadable {} | |
extension UInt32: BinaryReadable {} | |
extension UInt64: BinaryReadable {} | |
class BinaryDataScanner { | |
let data: NSData | |
let littleEndian: Bool | |
let encoding: NSStringEncoding | |
var current: ConstUnsafePointer<()> | |
var remaining: Int | |
init(data: NSData, littleEndian: Bool, encoding: NSStringEncoding) { | |
self.data = data | |
self.littleEndian = littleEndian | |
self.encoding = encoding | |
self.current = self.data.bytes | |
self.remaining = self.data.length | |
} | |
func read<T: BinaryReadable>() -> T? { | |
let byteCount = sizeof(T) | |
println(byteCount) | |
println(remaining) | |
if remaining < byteCount { | |
return nil | |
} | |
let tCurrent = ConstUnsafePointer<T>(current) | |
let v = tCurrent.memory | |
current = ConstUnsafePointer<()>(tCurrent.successor()) | |
remaining -= byteCount | |
return littleEndian ? v.littleEndian : v.bigEndian | |
} | |
func readNullTerminatedString() -> String? { | |
var string:String? = nil | |
var tCurrent = ConstUnsafePointer<UInt8>(current) | |
var count: Int = 0 | |
// scan | |
while (remaining > 0 && tCurrent.memory != 0) { | |
remaining -= 1 | |
count += 1 | |
tCurrent = tCurrent.successor() | |
} | |
// create string if available | |
if (remaining > 0 && tCurrent.memory == 0) { | |
string = NSString(bytes: current, length: count, encoding: encoding) as String | |
current = ConstUnsafePointer<()>(tCurrent.successor()) | |
remaining -= 1 | |
} | |
return string | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment