parsing NSData object for information

£可爱£侵袭症+ 提交于 2019-12-02 17:43:39

问题


I have a NSData object coming back from my server, it varies in its content but sticks to a particular structure.

I would like to know (hopfully with some example code) how to work though this object to get the data I need out of it.

the structure of the data objects inside the objects are like this

  • leading value (UInt16) - (tells me what section of the response it is)
  • Size of string (UInt32) or number - (UInt32)
  • String (not null terminated) i.e. followed by the next leading value.

I have been reading through the Binary Data Programming Guide however that's only really showing me how to put my data into new NSData objects and accessing and compairing the bytes.

The thing I am stuck on is how do I say grab the info dynamically. Check the NSdata objects first leading value figure out if its string or int then get the string or int and move onto the next leading value..

any suggestions or example code would be really helpfull.. just stuck in abit of a mind block as I have never attempted anything like this in objective C.


回答1:


Some of this depends on how your server is written to encode the data into what it is sending you. Assuming it is encoding the numeric values using standard network byte ordering (big-endian) you will want it converted to the correct byte-ordering for iOS (I believe that is always little-endian).

I would approach it something like this:

uint16_t typeWithNetworkOrdering, typeWithLocalOrdering;
uint32_t sizeWithNetworkOrdering, sizeWithLocalOrdering;
char *cstring = NULL;
uint32_t numberWithNetworkOrdering, numberWithLocalOrdering;
const void *bytes = [myData bytes];
NSUInteger length = [myData length];

while (length > 0) {
    memcpy(&typeWithNetworkOrdering, bytes, sizeof(uint16_t));
    bytes += sizeof(uint16_t);
    length -= sizeof(uint16_t);
    memcpy(&sizeWithNetworkOrdering, bytes, sizeof(uint32_t));
    bytes += sizeof(uint32_t);
    length -= sizeof(uint32_t);
    typeWithLocalOrdering = CFSwapInt16BigToHost(typeWithNetworkOrdering);
    sizeWithLocalOrdering = CFSwapInt32BigToHost(sizeWithNetworkOrdering);

    if (typeWithLocalOrdering == STRING_TYPE) { // STRING_TYPE is whatever type value corresponds to a string
        cstring = (char *) malloc(sizeWithLocalOrdering + 1);
        strncpy(cstring, bytes, sizeWithLocalOrdering);
        cstring[sizeWithLocalOrdering] = '\0';
        NSString *resultString = [NSString stringWithCString:cstring encoding:NSUTF8StringEncoding];
        NSLog(@"String = %@", resultString);
        free(cstring);
        bytes += sizeWithLocalOrdering;
        length -= sizeWithLocalOrdering;
        // Do whatever you need to with the string
    }
    else if (typeWithLocalOrdering == NUMBER_TYPE) { // NUMBER_TYPE is whatever type value corresponds to a number
        memcpy(&numberWithNetworkOrdering, bytes, sizeof(uint32_t));
        numberWithLocalOrdering = CFSwapInt32BigToHost(numberWithNetworkOrdering);
        NSLog(@"Number = %u", numberWithLocalOrdering);
        bytes += sizeof(uint32_t);
        length -= sizeof(uint32_t);
        // Do whatever you need to with the number
    }
}



回答2:


Define your own internal structs and cast the pointer to it:

NSData* data;
struct headerType
{
    uint16_t type;
    uint32_t length;

};
const struct headerType* header=(const struct headerType*)[data bytes]; // get the header of the response
if (header->type==1)
{
    const char* text=((const char*)header)+6; // skip the header (16bits+32bits=6 bytes offset)
}

EDIT: If you need to read them in a loop:

NSData* data;
const uint8_t* cursor=(const uint8_t*)[data bytes];
while (true)
{
    uint16_t type=*((uint16_t*)cursor);
    cursor+=2;
    if (cursor==1)
    {
        // string
        uint32_t length=*((uint32_t*)cursor);
        cursor+=4;
        const char* str=(const char*)cursor;
        cursor+=length;
    }
    else if (cursor==2)
    {
        // another type
    }
    else
        break;
}


来源:https://stackoverflow.com/questions/9507053/parsing-nsdata-object-for-information

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!