diff options
author | rowanbeentje <rowan@beent.je> | 2011-04-23 17:15:18 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2011-04-23 17:15:18 +0000 |
commit | d60880e78188b4ef7cc2e73106eb980af3c13642 (patch) | |
tree | 1b3e064f9909c9e8d9f5afd7342c49b671dbb048 | |
parent | 555cb252a3e42d0df5835a18df4abbe1a0b0725a (diff) | |
download | sequelpro-d60880e78188b4ef7cc2e73106eb980af3c13642.tar.gz sequelpro-d60880e78188b4ef7cc2e73106eb980af3c13642.tar.bz2 sequelpro-d60880e78188b4ef7cc2e73106eb980af3c13642.zip |
Alter result string processing to use returned string length and not null-terminated string processing:
- This fixes issues caused by null characters in strings - addressing Issue 1029
- Also appears to be a few percent faster than the old approach when processing lots of short strings
- Allows significant simplification of MCPResult and low-memory MCPStreamingResult code, avoiding a memory copy; this also gives a significant speedup and can actually make full streaming in MCPStreamingResult faster than "fast streaming".
The code will be reviewed further in future to improve on the gains seen here.
-rw-r--r-- | Frameworks/MCPKit/MCPFoundationKit/MCPResult.m | 9 | ||||
-rw-r--r-- | Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m | 11 |
2 files changed, 5 insertions, 15 deletions
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m b/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m index 53066c14..84793e44 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m @@ -419,10 +419,7 @@ const OUR_CHARSET our_charsets60[] = if (theRow[i] == NULL) { theCurrentObj = [NSNull null]; } else { - char *theData = calloc(sizeof(char),theLengths[i]+1); - //char *theUselLess; - memcpy(theData, theRow[i],theLengths[i]); - theData[theLengths[i]] = '\0'; + char *theData = theRow[i]; switch (theField[i].type) { case FIELD_TYPE_TINY: @@ -444,7 +441,7 @@ const OUR_CHARSET our_charsets60[] = case FIELD_TYPE_SET: case FIELD_TYPE_ENUM: case FIELD_TYPE_NEWDATE: // Don't know what the format for this type is... - theCurrentObj = [NSString stringWithCString:theData encoding:mEncoding]; + theCurrentObj = [[[NSString alloc] initWithBytes:theData length:theLengths[i] encoding:mEncoding] autorelease]; break; case FIELD_TYPE_BIT: @@ -479,8 +476,6 @@ const OUR_CHARSET our_charsets60[] = break; } - free(theData); - // Some of the creators return nil object... if (theCurrentObj == nil) { theCurrentObj = [NSNull null]; diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m index 465221fe..ec4aa44b 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m @@ -226,14 +226,12 @@ void _bytes2bin(Byte *n, NSUInteger nbytes, NSUInteger len, char *buf); id cellData = nil; char *theData = NULL; - // In fully streaming mode, copy across the data for the MYSQL_ROW + // In fully streaming mode, get a reference to the data for the MYSQL_ROW if (fullyStreaming) { if (theRow[i] == NULL) { cellData = [NSNull null]; } else { - theData = calloc(sizeof(char), fieldLengths[i]+1); - memcpy(theData, theRow[i], fieldLengths[i]); - theData[fieldLengths[i]] = '\0'; + theData = theRow[i]; } // In cached-streaming mode, use a reference to the downloaded data @@ -281,7 +279,7 @@ void _bytes2bin(Byte *n, NSUInteger nbytes, NSUInteger len, char *buf); } // For string data, convert to text else { - cellData = [NSString stringWithCString:theData encoding:mEncoding]; + cellData = [[[NSString alloc] initWithBytes:theData length:fieldLengths[i] encoding:mEncoding] autorelease]; } break; @@ -328,9 +326,6 @@ void _bytes2bin(Byte *n, NSUInteger nbytes, NSUInteger len, char *buf); break; } - // Free the data if it was originally allocated - if (fullyStreaming) free(theData); - // If a creator returned a nil object, replace with NSNull if (cellData == nil) cellData = [NSNull null]; } |