【发布时间】:2015-02-11 16:59:44
【问题描述】:
我在 NSData 上有以下分类方法。我正在尝试提取给定索引处的位字段并将其作为 NSNumber 返回。我让它对所有正数都有效,但我也需要它与负数一起工作。
我的实现如下所示:
#import <Foundation/Foundation.h>
@interface NSData (ExternalDevices)
@end
@implementation NSData (ExternalDevices)
- (NSNumber *)extractLittleEndianBitFieldAtIndex:(int)index forLength:(int)length
{
//This function has limitations on the "length" parameter that are not yet know/defined
//These limitations are due to the max size of "NSInteger intData" defined below
int first_byte = index/8; //Index of the first byte containing this bit field
int last_byte = (length+index-1)/8; //Index of the last byte containing this bit field
int byte_length = last_byte - first_byte + 1; //number of bytes containing this bit field
Byte *byteArray = (Byte*)malloc(byte_length);
memcpy(byteArray, [[self subdataWithRange:NSMakeRange(first_byte, byte_length)] bytes], byte_length);
NSInteger intData = *((NSInteger *)byteArray);
free(byteArray);
return [NSNumber numberWithInt:intData];
}
+ (NSData *)dataFromHexString:(NSString *)string
{
string = [string lowercaseString];
NSMutableData *data= [NSMutableData new];
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
int i = 0;
NSUInteger length = string.length;
while (i < length-1) {
char c = [string characterAtIndex:i++];
if (c < '0' || (c > '9' && c < 'a') || c > 'f')
continue;
byte_chars[0] = c;
byte_chars[1] = [string characterAtIndex:i++];
whole_byte = strtol(byte_chars, NULL, 16);
[data appendBytes:&whole_byte length:1];
}
return data;
}
@end
@interface Testing:NSObject
@end
@implementation Testing
- (instancetype)init
{
self = [super init];
if (self)
{
{
NSData *data = [NSData dataFromHexString:@"e30b"];
NSLog(@"%@ should be 3043", [data extractLittleEndianBitFieldAtIndex:0 forLength:16]);
}
{
NSData *data = [NSData dataFromHexString:@"46e0"];
NSLog(@"%@ should be -8122", [data extractLittleEndianBitFieldAtIndex:0 forLength:16]);
}
{
NSData *data = [NSData dataFromHexString:@"f208"];
NSLog(@"%@ should be 2290", [data extractLittleEndianBitFieldAtIndex:0 forLength:16]);
}
{
NSData *data = [NSData dataFromHexString:@"10e6"];
NSLog(@"%@ should be -6640", [data extractLittleEndianBitFieldAtIndex:0 forLength:16]);
}
{
NSData *data = [NSData dataFromHexString:@"018900"];
NSLog(@"%@ should be 137", [data extractLittleEndianBitFieldAtIndex:8 forLength:16]);
}
}
return self;
}
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
[[Testing alloc] init];
}
}
以下网站似乎总能在 INT16 - Little Endian (BA) 下产生我想要的结果
http://www.scadacore.com/field-applications/miscellaneous/online-hex-converter.html
虽然重要的是要注意并非我使用的每个数字都是 INT16
【问题讨论】:
标签: ios objective-c hex nsdata