|
68 | 68 | return outputString;
|
69 | 69 | }
|
70 | 70 |
|
71 |
| -static NSString *StringFromDispatchDataWithBrokenUTF8Encoding(const char *dataPtr, size_t dataSz) |
| 71 | +NSString *StringFromDispatchDataWithBrokenUTF8Encoding(const char *dataPtr, size_t dataSz) |
72 | 72 | {
|
73 | 73 | int one = 1;
|
74 | 74 | iconv_t cd = iconv_open("UTF-8", "UTF-8");
|
75 | 75 | iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, &one);
|
76 |
| - size_t inbytesleft = dataSz; |
77 |
| - size_t outbytesleft = dataSz; |
78 | 76 | char *inbuf = (char *)dataPtr;
|
79 | 77 | char *outbuf = malloc(sizeof(char) * dataSz);
|
80 |
| - char *outptr = outbuf; |
81 |
| - NSString *string = nil; |
82 |
| - if (iconv(cd, &inbuf, &inbytesleft, &outptr, &outbytesleft) != (size_t)-1) { |
83 |
| - string = [[NSString alloc] initWithBytes:outbuf length:dataSz - outbytesleft encoding:NSUTF8StringEncoding]; |
| 78 | + NSMutableString *outputString = [NSMutableString string]; |
| 79 | + long bytesToProcess = dataSz; |
| 80 | + while (bytesToProcess > 0) { |
| 81 | + NSString *string = nil; |
| 82 | + size_t inbytesleft = bytesToProcess; |
| 83 | + size_t outbytesleft = bytesToProcess; |
| 84 | + char *outptr = outbuf; |
| 85 | + size_t iconvResult = iconv(cd, &inbuf, &inbytesleft, &outptr, &outbytesleft); |
| 86 | + size_t outbytesLength = bytesToProcess - outbytesleft; |
| 87 | + if (outbytesLength > 0) { |
| 88 | + string = [[NSString alloc] initWithBytesNoCopy:outbuf length:outbytesLength encoding:NSUTF8StringEncoding freeWhenDone:NO]; |
| 89 | + [outputString appendString:string]; |
| 90 | + } |
| 91 | + if (iconvResult != (size_t)-1) { |
| 92 | + inbuf += (bytesToProcess - inbytesleft); |
| 93 | + } else if (errno == EINVAL) { |
| 94 | + // skip first byte and then all next 10xxxxxx bytes (see UTF-8 description for more details) |
| 95 | + do { |
| 96 | + inbuf++; |
| 97 | + inbytesleft--; |
| 98 | + } while (((*inbuf) & 0xC0) == 0x80 && inbytesleft > 0); |
| 99 | + [outputString appendString:@"\uFFFD"]; |
| 100 | + } |
| 101 | + bytesToProcess = inbytesleft; |
84 | 102 | }
|
85 | 103 | free(outbuf);
|
86 | 104 | iconv_close(cd);
|
87 |
| - return string; |
| 105 | + return outputString; |
88 | 106 | }
|
89 | 107 |
|
90 | 108 | static NSArray *LinesFromDispatchData(dispatch_data_t data, BOOL omitNewlineCharacters, BOOL forceUntilTheEnd, size_t *convertedSize)
|
|
0 commit comments