Convert NSString to 64 Databases for XML Serialization

I am using the Apple NSXMLParser class to load data. I have a separate structure for serializing my data.

I had a fairly long dash, Word quotes, etc. that appear in my XML output and cause parsing errors, which often leads to data loss due to poor parser management of these characters.

If I have user input as an NSString object, I want to convert it to Base64 (for which I have a utility method), and then write these bytes to an XML file instead of NSString. I understand that this may take up more space, but at least I no longer have to deal with verification issues.

My question is how to convert NSData bytes (which look like <8d72...> in the NSLog instruction) to NSString without using encoding to return the original value. I want these actual bytes, as they appear in the log statement, to be converted to NSString. And finally (when loading serialized data), if you have NSString:

 NSString *loadedData = @"8d72..."; 

How to move from this form to a human readable person? The whole coding process is a little difficult for me to understand, but I think this is a really reliable way to ensure that weird user input is properly stored in my XML files.

+5
xml objective-c encoding parsing cocoa
source share
1 answer

Got it. I use the encoding / decoding methods from this answer to convert NSString objects to NSData objects and vice versa: Any base64 library on iphone-sdk?

And then I wrote these quick methods that use the above methods, and let me write Base64 string data in XML. Downloading it works fine, has been verified with Chinese characters, Word characters, etc. You can also parse them if you want, but at least the error is not in the parser. (Which can easily lead to data loss if you handle errors incorrectly.)

 + (NSString *)toBase64String:(NSString *)string { NSData *data = [string dataUsingEncoding: NSUnicodeStringEncoding]; NSString *ret = [NSStringUtil base64StringFromData:data length:[data length]]; return ret; } + (NSString *)fromBase64String:(NSString *)string { NSData *base64Data = [NSStringUtil base64DataFromString:string]; NSString* decryptedStr = [[NSString alloc] initWithData:base64Data encoding:NSUnicodeStringEncoding]; return [decryptedStr autorelease]; } 

Edit: As the source link is down, I have been looking for my code for a long time, here are my NSStringUtil methods mentioned above. Note. I am not the author of this code, but it has been working well for many years:

 + (NSData *)base64DataFromString: (NSString *)string { unsigned long ixtext, lentext; unsigned char ch, input[4], output[3]; short i, ixinput; Boolean flignore, flendtext = false; const char *temporary; NSMutableData *result; if (!string) { return [NSData data]; } ixtext = 0; temporary = [string UTF8String]; lentext = [string length]; result = [NSMutableData dataWithCapacity: lentext]; ixinput = 0; while (true) { if (ixtext >= lentext) { break; } ch = temporary[ixtext++]; flignore = false; if ((ch >= 'A') && (ch <= 'Z')) { ch = ch - 'A'; } else if ((ch >= 'a') && (ch <= 'z')) { ch = ch - 'a' + 26; } else if ((ch >= '0') && (ch <= '9')) { ch = ch - '0' + 52; } else if (ch == '+') { ch = 62; } else if (ch == '=') { flendtext = true; } else if (ch == '/') { ch = 63; } else { flignore = true; } if (!flignore) { short ctcharsinput = 3; Boolean flbreak = false; if (flendtext) { if (ixinput == 0) { break; } if ((ixinput == 1) || (ixinput == 2)) { ctcharsinput = 1; } else { ctcharsinput = 2; } ixinput = 3; flbreak = true; } input[ixinput++] = ch; if (ixinput == 4) { ixinput = 0; unsigned char0 = input[0]; unsigned char1 = input[1]; unsigned char2 = input[2]; unsigned char3 = input[3]; output[0] = (char0 << 2) | ((char1 & 0x30) >> 4); output[1] = ((char1 & 0x0F) << 4) | ((char2 & 0x3C) >> 2); output[2] = ((char2 & 0x03) << 6) | (char3 & 0x3F); for (i = 0; i < ctcharsinput; i++) { [result appendBytes: &output[i] length: 1]; } } if (flbreak) { break; } } } return result; } + (NSString *)base64StringFromData: (NSData *)data length: (NSUInteger)length { unsigned long ixtext, lentext; long ctremaining; unsigned char input[3], output[4]; short i, charsonline = 0, ctcopy; const unsigned char *raw; NSMutableString *result; lentext = [data length]; if (lentext < 1) { return @""; } result = [NSMutableString stringWithCapacity: lentext]; raw = [data bytes]; ixtext = 0; while (true) { ctremaining = lentext - ixtext; if (ctremaining <= 0) { break; } for (i = 0; i < 3; i++) { unsigned long ix = ixtext + i; if (ix < lentext) { input[i] = raw[ix]; } else { input[i] = 0; } } output[0] = (input[0] & 0xFC) >> 2; output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4); output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6); output[3] = input[2] & 0x3F; ctcopy = 4; switch (ctremaining) { case 1: ctcopy = 2; break; case 2: ctcopy = 3; break; } for (i = 0; i < ctcopy; i++) { [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]]; } for (i = ctcopy; i < 4; i++) { [result appendString: @"="]; } ixtext += 3; charsonline += 4; if ((ixtext % 90) == 0) { [result appendString: @"\n"]; } if (length > 0) { if (charsonline >= length) { charsonline = 0; [result appendString: @"\n"]; } } } return result; } 
+11
source share

All Articles