Skip to content

A framework containing a safe wrapper for UnsafeMutablePointer with integer to byte array generics.

Notifications You must be signed in to change notification settings

gpongelli/GPSafeSwiftPointer

Repository files navigation

GPSafeSwiftPointer

Carthage compatible Build Status Tag License Swift

A framework containing a safe wrapper for UnsafeMutablePointer with integer to byte array generics.

Requirements

Swift4.2 branch

  • Xcode 10
  • Swift 4.2

Swift3 branch

  • Xcode 8
  • Swift 3

Swift2.1 branch

  • Xcode 7
  • Swift 2

Motivation

Why I made this framework? Because I found UnsafeMutablePointer very unsafe . UnsafeMutablePointer Reference for alloc method defines

Allocate memory for num objects of type Memory.

So it's expected to

let test = UnsafeMutablePointer<UInt8>.alloc(1)
test[0] = 5
print(test[0])  // correctly prints 5

but it's not expected to have these result IMHO

print(test[1])  // why prints 0 ?!
print(test[2])  // why again prints 0 ?!
...
print(test[7])  // why prints 127 ?!

Playground are you serious 😳 ⁉️ ⁉️

This is one of the reason I created this class, having these results

let test = GPSafeSwiftPointer<UInt8>()  // pointer to one UInt8
test[0] = 5
print(test[0])  // correctly prints Optional(5)
print(test[1])  // correctly returns nil 
...
test[2] = 4  // this instruction returns without setting any value
print(test[2])  // correctly returns nil as before

Another reason that let me create this framework was about memory management, because after alloc() and initialize() it's developer's responsibility to call dealloc() and destroy(); this class automatically call these methods on deinit.

Installation

Carthage

Insert github "gpongelli/GPSafeSwiftPointer" ~> 0.3 in your Cartfile

Usage

Some simple usage are reported here, some usage are already showed in motivation paragraph, for other example see iOS tests file.

Initialization

GPSafeSwiftPointer variables can be initializated as follows

  1. let test = GPSafeSwiftPointer<type>() // alloc one element of type type
  2. let test = GPSafeSwiftPointer<type>(allocatedMemory: k) // alloc k elements of type type
  3. let test = GPSafeSwiftPointer<type>(initializeWithValue: n) // alloc one element of type type initialized with value n

Underlying UnsafeMutablePointer

Having a

let test = GPSafeSwiftPointer<TYPE>() 
test.ump 

returns the underlying UnsafeMutablePointer to be used when calling Apple methods as I do for SecRandomCopyBytes .

Byte Array Protocol for Integers

Test file contains some tests about all integer types conversion to and from byte array, having Big Endian coding.

So for example, an UInt16 equal to 24288 will be converted to an array of two UInt8 containing [94, 224] having these representation:

Representation MSB LSB
integer 94 224
binary 01011110 11100000
hexadecimal 0x5E 0xE0

Converting back the hexadecimal or binary representation will lead to the original value.

Byte Array Protocol for UnsafeMutablePointer and GPSafeSwiftPointer

Looking at test file you'll find two test about UnsafeMutablePointer and GPSafeSwiftPointer using Byte Array protocol.

The called method and the results are the same as for simple integer variables, but in this case the pointed integer is used without any hassle.

UnsafeBitCast

Using GPSafeSwiftPointer and Byte Array protocol to return the contained value as byte array, it can be avoided to use unsafeBitCast to have the pointed value casted as another type as erroneously wrote in some blog post around internet, ➡️ Swift prevents to do this ⬅️ .

Looking at the relative test, it's clear that an UnsafeMutablePointer of any type casted to UInt (32 bit) does not return the pointed value; inspecting the results with playground it's easy to see that the returned value is the address that UnsafeMutablePointer contains, not it's pointed value .

The only unsafeBitCast that works is to the same type of original pointed type, as showed inside the test.

A typical example I use for GPSafeSwiftPointer instead of unsafeBitCast is when generating random bytes with SecRandomCopyBytes .

Author

Gabriele Pongelli

Contribution

Thanks to @krzyzanowskim to his gist, I've included his code inside this project adding some changes I commented to his gist simply because I prefer Big Endian to Little Endian representation.

License

GPSafeSwiftPointer is available under the MIT license. See the LICENSE file for more info.

About

A framework containing a safe wrapper for UnsafeMutablePointer with integer to byte array generics.

Resources

Stars

Watchers

Forks

Packages

No packages published