@@ -53,7 +53,7 @@ -(id)initWithInputStream:(NSInputStream*)stream
5353 self.inputStream = stream;
5454 self.bufferLength = bufferLength;
5555 self.readFromStream = [[NSMutableString alloc ] initWithCapacity: bufferLength];
56- self.streamBuffer = [NSMutableData dataWithLength: bufferLength ];
56+ self.streamBuffer = [NSMutableData new ];
5757 self.lockObject = [[NSObject alloc ] init ];
5858 }
5959 return self;
@@ -82,14 +82,45 @@ -(BOOL)readLine:(NSString**)line withError:(NSError**)readError
8282 NSRange newlineOccurence = [self .readFromStream rangeOfCharacterFromSet: [NSCharacterSet newlineCharacterSet ]];
8383 while (newlineOccurence.location == NSNotFound && [self .inputStream hasBytesAvailable ])
8484 {
85- uint8_t * dataBuffer = ( uint8_t *) [self .streamBuffer mutableBytes ];
85+ uint8_t dataBuffer[self .bufferLength ];
8686 NSInteger readAmount = [self .inputStream read: dataBuffer maxLength: self .bufferLength];
8787
8888 if (readAmount > 0 )
8989 {
90- NSString * readString = [[NSString alloc ] initWithBytes: dataBuffer
91- length: readAmount
92- encoding: NSUTF8StringEncoding];
90+ [self .streamBuffer setLength: 0 ];
91+ [self .streamBuffer appendBytes: (const void *)dataBuffer length: readAmount];
92+
93+ /* if readString is nil, we probably are reading a multibytes characters
94+ (e.g. Euro Sign "U+20AC" is 3 bytes char, "U+10348" is a 4 bytes char) and encounter a partial character. We need to continue
95+ read byte by byte to a max of 4 bytes until the whole character has been read from inputStream
96+ */
97+ NSString * readString = nil ;
98+ NSInteger count = 1 ;
99+ while ((readString = [[NSString alloc ] initWithData: self .streamBuffer encoding: NSUTF8StringEncoding]) == nil ) {
100+ uint8_t aByteBuff[1 ];
101+ NSInteger len = [self .inputStream read: aByteBuff maxLength: 1 ];
102+ if (len > 0 ) {
103+ [self .streamBuffer appendBytes: (const void *)aByteBuff length: len];
104+ } else {
105+ // break if it is end of stream or any error occured.
106+ break ;
107+ }
108+
109+ // according to RFC3629, no UTF8 encoded character has a length larger than 4 bytes.
110+ if (count < 4 ) {
111+ count++;
112+ } else {
113+ break ;
114+ }
115+ }
116+
117+ if (readString == nil ) {
118+ error = [AWSMobileAnalyticsErrorUtils errorWithDomain: AWSBufferedReaderErrorDomain
119+ withDescription: @" unable to parse string, make sure it is a valid UTF8 string"
120+ withErrorCode: AWSBufferedReaderErrorCode_UnableToParseString];
121+ break ;
122+ }
123+
93124
94125 // append the new chunck of data to what we've read and re-evaluate the loop
95126 [self .readFromStream appendString: readString];
0 commit comments