Skip to content
This repository was archived by the owner on Mar 19, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions MVPCStruct.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
05A8B6C2194B1718006366DF /* MVPCStruct.h in Headers */ = {isa = PBXBuildFile; fileRef = 05A8B6C1194B1718006366DF /* MVPCStruct.h */; settings = {ATTRIBUTES = (Public, ); }; };
05A8B6C8194B1718006366DF /* MVPCStruct.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05A8B6BC194B1718006366DF /* MVPCStruct.framework */; };
05A8B6D9194B1755006366DF /* CStruct.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05A8B6D8194B1755006366DF /* CStruct.swift */; };
4BBF61AA1B7079F500821C5F /* CStruct.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05A8B6D8194B1755006366DF /* CStruct.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -226,6 +227,7 @@
files = (
058E72AE194B36DD002168A2 /* PackTests.swift in Sources */,
058E72B0194B3715002168A2 /* UnpackTests.swift in Sources */,
4BBF61AA1B7079F500821C5F /* CStruct.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
63 changes: 32 additions & 31 deletions MVPCStruct/CStruct.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ import Cocoa

// Split a large integer into bytes.
extension Int {
func splitBytes(endianness: CStruct.Endianness, size: Int) -> UInt8[] {
var bytes = UInt8[]()
func splitBytes(endianness: CStruct.Endianness, size: Int) -> [UInt8] {
var bytes = [UInt8]()
var shift: Int
var step: Int
if endianness == .LittleEndian {
Expand All @@ -52,16 +52,16 @@ extension Int {
shift = (size - 1) * 8
step = -8
}
for count in 0..size {
for count in 0..<size {
bytes.append(UInt8((self >> shift) & 0xff))
shift += step
}
return bytes
}
}
extension UInt {
func splitBytes(endianness: CStruct.Endianness, size: Int) -> UInt8[] {
var bytes = UInt8[]()
func splitBytes(endianness: CStruct.Endianness, size: Int) -> [UInt8] {
var bytes = [UInt8]()
var shift: Int
var step: Int
if endianness == .LittleEndian {
Expand All @@ -71,7 +71,7 @@ extension UInt {
shift = Int((size - 1) * 8)
step = -8
}
for count in 0..size {
for count in 0..<size {
bytes.append(UInt8((self >> UInt(shift)) & 0xff))
shift = shift + step
}
Expand Down Expand Up @@ -129,7 +129,7 @@ class CStruct: NSObject {
case PackPointer
}

var opStream = Ops[]()
var opStream = [Ops]()

let bytesForValue = [
Ops.SkipByte: 1,
Expand All @@ -145,7 +145,7 @@ class CStruct: NSObject {
Ops.PackUInt64: 8,
Ops.PackFloat: 4,
Ops.PackDouble: 8,
Ops.PackPointer: sizeof(CConstVoidPointer),
Ops.PackPointer: sizeof(UnsafePointer<UInt>),
]

let PAD_BYTE = UInt8(0)
Expand All @@ -165,25 +165,25 @@ class CStruct: NSObject {

// Unpacking.

func unpack(data: NSData, format: String, error: NSErrorPointer) -> AnyObject[]? {
func unpack(data: NSData, format: String, error: NSErrorPointer) -> [AnyObject]? {
if !self.parseFormat(format, error: error) {
return nil
}
return self.unpack(data, error: error)
}
func unpack(data: NSData, error: NSErrorPointer) -> AnyObject[]? {

func unpack(data: NSData, error: NSErrorPointer) -> [AnyObject]? {

var values = AnyObject[]()
var values = [AnyObject]()
var index = 0
var alignment = true
var endianness = self.platformEndianness

// Set error message and return nil.
func failure(message: String) -> AnyObject[]? {
if error {
func failure(message: String) -> [AnyObject]? {
if (error != nil) {
error.memory = NSError(domain: ERROR_DOMAIN,
code: Error.Unpacking.toRaw(),
code: Error.Unpacking.rawValue,
userInfo: [NSLocalizedDescriptionKey: message])
}
return nil
Expand All @@ -201,13 +201,13 @@ class CStruct: NSObject {
}

// Read UInt8 values from data.
func readBytes(count: Int) -> UInt8[]? {
var bytes = UInt8[]()
func readBytes(count: Int) -> [UInt8]? {
var bytes = [UInt8]()
if index + count > data.length {
return nil
}
let ptr = UnsafePointer<UInt8>(data.bytes)
let unsafeBytes = UnsafeArray<UInt8>(start:ptr + index, length:count)
let unsafeBytes = UnsafeBufferPointer<UInt8>(start:ptr + index, count:count)
index += count
for byte in unsafeBytes {
bytes.append(byte)
Expand All @@ -216,15 +216,15 @@ class CStruct: NSObject {
}

// Create integer from bytes.
func intFromBytes(bytes: UInt8[]) -> Int {
func intFromBytes(bytes: [UInt8]) -> Int {
var i: Int = 0
for byte in endianness == .LittleEndian ? bytes.reverse() : bytes {
i <<= 8
i |= Int(byte)
}
return i
}
func uintFromBytes(bytes: UInt8[]) -> UInt {
func uintFromBytes(bytes: [UInt8]) -> UInt {
var i: UInt = 0
for byte in endianness == .LittleEndian ? bytes.reverse() : bytes {
i <<= 8
Expand Down Expand Up @@ -317,25 +317,25 @@ class CStruct: NSObject {

// Packing.

func pack(values: AnyObject[], format: String, error: NSErrorPointer) -> NSData? {
func pack(values: [AnyObject], format: String, error: NSErrorPointer) -> NSData? {
if !self.parseFormat(format, error: error) {
return nil
}
return self.pack(values, error: error)
}

func pack(values: AnyObject[], error: NSErrorPointer) -> NSData? {
func pack(values: [AnyObject], error: NSErrorPointer) -> NSData? {

var bytes = UInt8[]()
var bytes = [UInt8]()
var index = 0
var alignment = true
var endianness = self.platformEndianness

// Set error message and return nil.
func failure(message: String) -> NSData? {
if error {
if (error != nil) {
error.memory = NSError(domain: ERROR_DOMAIN,
code: Error.Packing.toRaw(),
code: Error.Packing.rawValue,
userInfo: [NSLocalizedDescriptionKey: message])
}
return nil
Expand Down Expand Up @@ -389,7 +389,8 @@ class CStruct: NSObject {

case .PackChar:
if let str = rawValue as? String {
let codePoint = str.utf16[0]
let utf16view = str.utf16
let codePoint = Int(utf16view[utf16view.startIndex])
if codePoint < 128 {
bytes.append(UInt8(codePoint))
} else {
Expand Down Expand Up @@ -504,8 +505,8 @@ class CStruct: NSObject {

case .PackPointer:
if let value = rawValue as? UInt {
padAlignment(sizeof(CConstVoidPointer))
bytes.extend(value.splitBytes(endianness, size: sizeof(CConstVoidPointer)))
padAlignment(sizeof(UnsafePointer<UInt>))
bytes.extend(value.splitBytes(endianness, size: sizeof(UnsafePointer<UInt>)))
} else {
return failure("cannot convert argument to UInt")
}
Expand Down Expand Up @@ -569,7 +570,7 @@ class CStruct: NSObject {
// If we have a repeat count we expect a format character.
if repeat > 0 {
// Add one op for each repeat count.
for i in 0..repeat {
for i in 0..<repeat {
switch c {
case "x": opStream.append(.SkipByte)
case "c": opStream.append(.PackChar)
Expand All @@ -588,9 +589,9 @@ class CStruct: NSObject {
case "p": opStream.append(.PackPString)
case "P": opStream.append(.PackPointer)
default:
if error {
if (error != nil) {
error.memory = NSError(domain: ERROR_DOMAIN,
code: Error.Parsing.toRaw(),
code: Error.Parsing.rawValue,
userInfo: [NSLocalizedDescriptionKey: "bad character in format"])
}
return false
Expand Down
29 changes: 20 additions & 9 deletions MVPCStructTests/PackTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,46 @@ class PackTests: XCTestCase {
override func tearDown() {
super.tearDown()
}

func testBooleanPack() {
var error:NSError?

let packer = CStruct()
let booleanFacit = NSData(bytes: [0x01, 0x01, 0x00, 0x01] as [UInt8], length: 4)
if let result = packer.pack([true, true, false, true], format: "????", error: &error) {
XCTAssertEqual(result, booleanFacit)
} else {
XCTFail("result is nil")
}
}

func testHello() {
let facit = "Hello".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
var error: NSError?

let packer = CStruct()
if let result = packer.pack(["H", "e", "l", "l", "o"], format: "ccccc", error: &error) {
XCTAssertEqual(result, facit)
XCTAssertEqual(result, facit!)
} else {
XCTFail("result is nil")
}
if let result = packer.pack(["H", "e", "l", "l", "o"], format: "5c", error: &error) {
XCTAssertEqual(result, facit)
XCTAssertEqual(result, facit!)
} else {
XCTFail("result is nil")
}
}

func testInts() {
var error: NSError?
let signedFacit = NSData(bytes: [0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] as UInt8[], length: 15)
let signedFacit = NSData(bytes: [0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] as [UInt8], length: 15)
let packer = CStruct()
if let result = packer.pack([-1, -2, -3, -4], format: "<bhiq", error: &error) {
XCTAssertEqual(signedFacit, result)
} else {
XCTFail("result is nil")
}
let unsignedFacit = NSData(bytes: [0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] as UInt8[], length: 15)
let unsignedFacit = NSData(bytes: [0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] as [UInt8], length: 15)
if let result = packer.pack([1, 2, 3, 4], format: "<BHIQ", error: &error) {
println("Unsigned result: \(result)")
} else {
Expand All @@ -59,21 +71,21 @@ class PackTests: XCTestCase {

let packer = CStruct()

let signedFacit16 = NSData(bytes: [0x01, 0x00, 0x02, 0x00] as UInt8[], length: 4)
let signedFacit16 = NSData(bytes: [0x01, 0x00, 0x02, 0x00] as [UInt8], length: 4)
if let result = packer.pack([1, 2], format: "@BH", error: &error) {
XCTAssertEqual(signedFacit16, result)
} else {
XCTFail("result is nil")
}

let signedFacit32 = NSData(bytes: [0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00] as UInt8[], length: 8)
let signedFacit32 = NSData(bytes: [0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00] as [UInt8], length: 8)
if let result = packer.pack([1, 2], format: "@BI", error: &error) {
XCTAssertEqual(signedFacit32, result)
} else {
XCTFail("result is nil")
}

let signedFacit64 = NSData(bytes: [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] as UInt8[], length: 16)
let signedFacit64 = NSData(bytes: [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] as [UInt8], length: 16)
if let result = packer.pack([1, 2], format: "@BQ", error: &error) {
XCTAssertEqual(signedFacit64, result)
} else {
Expand All @@ -84,7 +96,7 @@ class PackTests: XCTestCase {
func testBigEndian() {
var error: NSError?

let facit = NSData(bytes: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e] as UInt8[], length: 14)
let facit = NSData(bytes: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e] as [UInt8], length: 14)

let packer = CStruct()

Expand Down Expand Up @@ -113,5 +125,4 @@ class PackTests: XCTestCase {
XCTFail("bad format should return nil")
}
}

}
16 changes: 8 additions & 8 deletions MVPCStructTests/UnpackTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ class UnpackTests: XCTestCase {
var error: NSError?

let packer = CStruct()
if let result = packer.unpack(helloData, format: "ccccc", error: &error) as? String[] {
for i in 0..facit.count {
if let result = packer.unpack(helloData!, format: "ccccc", error: &error) as? [String] {
for i in 0..<facit.count {
XCTAssertEqual(result[i], facit[i])
}
}
if let result = packer.unpack(helloData, format: "5c", error: &error) as? String[] {
for i in 0..facit.count {
if let result = packer.unpack(helloData!, format: "5c", error: &error) as? [String] {
for i in 0..<facit.count {
XCTAssertEqual(result[i], facit[i])
}
}
Expand All @@ -40,12 +40,12 @@ class UnpackTests: XCTestCase {
func testBigEndian() {
var error: NSError?

let data = NSData(bytes: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e] as UInt8[], length: 14)
let facit: UInt[] = [0x0102, 0x03040506, 0x0708090a0b0c0d0e]
let data = NSData(bytes: [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e] as [UInt8], length: 14)
let facit: [UInt] = [0x0102, 0x03040506, 0x0708090a0b0c0d0e]

let packer = CStruct()
if let result = packer.unpack(data, format: ">HIQ", error: &error) as? UInt[] {
for i in 0..facit.count {
if let result = packer.unpack(data, format: ">HIQ", error: &error) as? [UInt] {
for i in 0..<facit.count {
XCTAssertEqual(facit[i], result[i])
}
} else {
Expand Down