Skip to content

Commit ec440f6

Browse files
author
Yosuke Matsuda
committed
The AWS Mobile SDK for iOS 2.0.17.
1 parent ec2c66d commit ec440f6

File tree

14 files changed

+114
-30
lines changed

14 files changed

+114
-30
lines changed

AWSCore/MobileAnalytics/core/io/AWSMobileAnalyticsBufferedReader.m

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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];

AWSCore/MobileAnalytics/include/core/io/AWSMobileAnalyticsBufferedReader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
FOUNDATION_EXPORT NSString * const AWSBufferedReaderErrorDomain;
1919

2020
typedef NS_ENUM(NSInteger, AWSBufferedReaderErrorCodes) {
21-
AWSBufferedReaderErrorCode_IOStreamClosed = 0
21+
AWSBufferedReaderErrorCode_IOStreamClosed = 0,
22+
AWSBufferedReaderErrorCode_UnableToParseString = 1,
2223
};
2324

2425
@interface AWSMobileAnalyticsBufferedReader : NSObject

AWSCore/Networking/AWSNetworking.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#import "AWSURLSessionManager.h"
2222

2323
NSString *const AWSNetworkingErrorDomain = @"com.amazonaws.AWSNetworkingErrorDomain";
24-
NSString *const AWSiOSSDKVersion = @"2.0.16";
24+
NSString *const AWSiOSSDKVersion = @"2.0.17";
2525

2626
#pragma mark - AWSHTTPMethod
2727

AWSCore/Utility/AWSCategory.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ FOUNDATION_EXPORT NSString *const AWSDateShortDateFormat1;
5353

5454
@end
5555

56+
@interface NSNumber (AWS)
57+
58+
+ (NSNumber *)aws_numberFromString:(NSString *)string;
59+
60+
@end
61+
5662
@interface NSObject (AWS)
5763

5864
- (NSDictionary *)aws_properties;

AWSCore/Utility/AWSCategory.m

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,17 @@ -(id) aws_objectForCaseInsensitiveKey:(id)aKey {
142142

143143
@end
144144

145+
@implementation NSNumber (AWS)
146+
147+
+ (NSNumber *)aws_numberFromString:(NSString *)string {
148+
NSNumberFormatter *numberFormatter = [NSNumberFormatter new];
149+
numberFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
150+
151+
return [numberFormatter numberFromString:string];
152+
}
153+
154+
@end
155+
145156
@implementation NSObject (AWS)
146157

147158
- (NSDictionary *)aws_properties {

AWSiOSSDKAnalyticsTests/AIBufferedReaderTests.m

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,42 @@ -(void)test_readingFromInputStream_multipleReadsRequired
137137
[self readFromReader:reader andVerifySuccessWith:NO andVerifyLineWith:nil andVerifyErrorCode:[NSNumber numberWithInt:AWSBufferedReaderErrorCode_IOStreamClosed]];
138138
}
139139

140+
-(void)testReadingFromInputStream_largeMultibytesCharacters {
141+
142+
//create a string with multi bytes characters in it (e.g. Chinese Characters)
143+
NSString *chineseString = @"𐍈今天是个好天气€";
144+
145+
NSMutableString* longChineseString = [NSMutableString stringWithCapacity:100000];
146+
for(int i = 0; i < 100000; i++)
147+
{
148+
[longChineseString appendString:chineseString];
149+
[longChineseString appendString:@"\n"];
150+
151+
}
152+
153+
NSData* mockInput = [longChineseString dataUsingEncoding:NSUTF8StringEncoding];
154+
NSInputStream* inputStream = [NSInputStream inputStreamWithData:mockInput];
155+
[inputStream open];
156+
157+
158+
AWSMobileAnalyticsBufferedReader* reader = [AWSMobileAnalyticsBufferedReader readerWithInputStream:inputStream];
159+
160+
for(int i = 0; i < 100000; i++)
161+
{
162+
[self readFromReader:reader andVerifySuccessWith:YES andVerifyLineWith:chineseString andVerifyErrorCode:nil];
163+
}
164+
165+
// no more data, so we should get a successful call with a nil string to signal end of stream
166+
[self readFromReader:reader andVerifySuccessWith:YES andVerifyLineWith:nil andVerifyErrorCode:nil];
167+
168+
// now that the buffer is at end, we need to close the object
169+
[reader close];
170+
171+
// any calls after this are errors
172+
[self readFromReader:reader andVerifySuccessWith:NO andVerifyLineWith:nil andVerifyErrorCode:[NSNumber numberWithInt:AWSBufferedReaderErrorCode_IOStreamClosed]];
173+
174+
}
175+
140176
-(void)testReadingFromInputStream_largeStream
141177
{
142178
// create a string with all the ascii codes in it

AWSiOSSDKTests/AWSCognitoCredentialsProviderTests.m

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ @implementation AWSCognitoCredentialsProviderTests
115115
#pragma mark - Set up/Tear down
116116

117117
+ (void)setUp {
118-
[AWSLogger defaultLogger].logLevel = AWSLogLevelVerbose;
119118
[super setUp];
120119
[AWSTestUtility setupCognitoCredentialsProvider];
121120

AWSiOSSDKTests/AWSCoreTests.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ - (void)testStringToDate {
7777
XCTAssertEqualWithAccuracy(testTimeAmz, expectedTime, 10, "Failed to create a proper date from string usingAWSDateAmzDateFormat");
7878
}
7979

80+
- (void)testNumberFormatt {
81+
XCTAssertEqualObjects([NSNumber aws_numberFromString:@"12345.67"], @12345.67);
82+
XCTAssertNil([NSNumber aws_numberFromString:@"12345,67"]);
83+
}
84+
8085
- (void)testUrlEncode {
8186
NSString *inputOne = @"test %";
8287
NSString *inputTwo = [NSString stringWithFormat:@"test %%"];

AWSiOSSDKTests/AWSEC2Tests.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ - (void)testDescribeImages {
7373
AWSEC2 *ec2 = [AWSEC2 defaultEC2];
7474

7575
AWSEC2DescribeImagesRequest *describeImagesRequest = [AWSEC2DescribeImagesRequest new];
76-
describeImagesRequest.imageIds = @[@"ami-c4fe9aac"]; // Microsoft Windows Server 2012 R2 Base Image ID
76+
describeImagesRequest.imageIds = @[@"ami-b27830da"]; // Microsoft Windows Server 2012 R2 Base Image ID
7777
[[[ec2 describeImages:describeImagesRequest] continueWithBlock:^id(BFTask *task) {
7878
if (task.error) {
7979
XCTFail(@"Error: [%@]", task.error);
@@ -87,7 +87,7 @@ - (void)testDescribeImages {
8787
BOOL imageExist = NO;
8888

8989
for (AWSEC2Image *image in describeImagesResult.images) {
90-
if ([image.imageId isEqualToString:@"ami-c4fe9aac"]) {
90+
if ([image.imageId isEqualToString:@"ami-b27830da"]) {
9191
imageExist = YES;
9292
XCTAssertEqual(AWSEC2PlatformValuesWindows, image.platform);
9393
}

AWSiOSSDKTests/AWSS3PreSignedURLBuilderTests.m

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ @implementation AWSS3PreSignedURLBuilderTests
4141

4242
- (void)setUp {
4343
[super setUp];
44-
[AWSLogger defaultLogger].logLevel = AWSLogLevelError;
4544
// Put setup code here. This method is called before the invocation of each test method in the class.
4645
[AWSTestUtility setupCognitoCredentialsProvider];
4746
}
@@ -340,7 +339,7 @@ - (void)testPutObjectWithSpecialCharacters {
340339

341340
XCTAssertNotNil(presignedURL);
342341

343-
NSLog(@"(PUT)presigned URL (Put)is: %@",presignedURL.absoluteString);
342+
//NSLog(@"(PUT)presigned URL (Put)is: %@",presignedURL.absoluteString);
344343

345344
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:presignedURL];
346345
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;

0 commit comments

Comments
 (0)