Browse Source

Add NSData_SA_NSDataExtensions

master
achmizs 10 years ago
parent
commit
558399ad6c

+ 0
- 1
.gitignore View File

*.ipa *.ipa


libirc* libirc*
NSData*


*~ *~

+ 90
- 0
NSData+SA_NSDataExtensions/NSData+SA_NSDataExtensions.h View File

//
// NSData+SA_NSDataExtensions.h
//
// Copyright (c) 2015 Said Achmiz.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#import <Foundation/Foundation.h>

/** \category NSData+SA_NSDataExtensions
* @brief Adds several utility methods to NSData.
*/
@interface NSData (SA_NSDataExtensions)

// NOTE on stripping nulls from the ends of byte arrays.
//
// If you strip a null from the end of an array which is something other than
// a null-terminated C string (such as, for example, the bytes representing a
// UTF-16 string), and thereby cause yourself difficulties, you have only
// yourself to blame. Be sure that you know what your NSData objects are
// supposed to contain!

/** Returns YES if the last byte of the stored data is null, NO otherwise.
*/
@property (readonly, getter=isNullTerminated) BOOL nullTerminated;

/** Returns the stored bytes as a null-terminated C string (byte array).
If the stored data is already null-terminated, the returned pointer will
be a pointer to the bytes managed by the receiver. If it is not already
null-terminated, the returned pointer will point to bytes managed by a
copy of the receiver (and the bytes of the copy will be null-terminated).
*/
@property (readonly) const char *SA_terminatedCString;

/** Returns data containing the stored bytes as a null-terminated C string
(byte array).
If the stored data is already null-terminated, this method simply returns
the receiver. If it is not already null-terminated, this method returns a
reference to a fresh copy of the receiver (a copy that contains a
null-terminated byte array, of course).
*/
@property (readonly) NSData *SA_dataWithTerminatedCString;

/** Returns the stored bytes as an non-null-terminated byte array.
If the stored data was not null-terminated to begin with, the returned
pointer will be a pointer to the bytes managed by the receiver. If the
stored data was null-terminated, the returned pointer will point to bytes
managed by a copy of the receiver (and the bytes of the copy will not be
null-terminated; but see NOTE).
NOTE: If the receiver's *last* byte is null, the bytes pointed to by the
returned pointer will have that null stripped; but if there are any more
null bytes prior to that last null, they will remain untouched!
*/
@property (readonly) const char *SA_unterminatedByteString;

/** Returns data containing the stored bytes as a non-null-terminated byte
array.
If the stored data was not null-terminated to begin with, this method simply
returns the receiver. If the stored data was null-terminated, this method
returns a reference to a fresh copy of the receiver (a copy that contains a
non-null-terminated byte array, of course; but see NOTE).
NOTE: If the receiver's *last* byte is null, the bytes managed by the
returned object will have that null stripped; but if there are any more
null bytes prior to that last null, they will remain untouched!
*/
@property (readonly) NSData *SA_dataWithUnterminatedByteString;

@end

+ 78
- 0
NSData+SA_NSDataExtensions/NSData+SA_NSDataExtensions.m View File

//
// NSData+SA_NSDataExtensions.h
//
// Copyright (c) 2015 Said Achmiz.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#import "NSData+SA_NSDataExtensions.h"

@implementation NSData (SA_NSDataExtensions)

-(BOOL)isNullTerminated
{
return (((char*) self.bytes)[self.length - 1] == '\0');
}

-(const char *)SA_terminatedCString
{
return self.SA_dataWithTerminatedCString.bytes;
}

-(NSData *)SA_dataWithTerminatedCString
{
if(self.length == 0)
{
return [NSData dataWithBytes:"\0" length:1];
}
else if(self.isNullTerminated)
{
return self;
}
else
{
char* terminated_string_buffer = malloc(self.length + 1);
[self getBytes:terminated_string_buffer length:self.length];
terminated_string_buffer[self.length] = '\0';
return [NSData dataWithBytesNoCopy:terminated_string_buffer length:self.length + 1 freeWhenDone:YES];
}
}

-(const char *)SA_unterminatedByteString
{
return self.SA_dataWithUnterminatedByteString.bytes;
}

-(NSData *)SA_dataWithUnterminatedByteString
{
if(self.length == 0 || self.isNullTerminated == NO)
{
return self;
}
else
{
char* unterminated_string_buffer = malloc(self.length - 1);
[self getBytes:unterminated_string_buffer length:self.length - 1];
return [NSData dataWithBytesNoCopy:unterminated_string_buffer length:self.length - 1 freeWhenDone:YES];
}
}

@end

Loading…
Cancel
Save