You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by mr...@apache.org on 2016/09/02 17:40:15 UTC
[34/45] usergrid git commit: Moving older SDKs to a difference
location and updating main README to link to new SDK locations.
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ios/UGAPI/SBJson/SBJsonStreamWriterState.h
----------------------------------------------------------------------
diff --git a/sdks/other/ios/UGAPI/SBJson/SBJsonStreamWriterState.h b/sdks/other/ios/UGAPI/SBJson/SBJsonStreamWriterState.h
new file mode 100755
index 0000000..90d442a
--- /dev/null
+++ b/sdks/other/ios/UGAPI/SBJson/SBJsonStreamWriterState.h
@@ -0,0 +1,69 @@
+/*
+ Copyright (c) 2010, Stig Brautaset.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ Neither the name of the the author nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Foundation/Foundation.h>
+
+@class SBJsonStreamWriter;
+
+@interface SBJsonStreamWriterState : NSObject
++ (id)sharedInstance;
+- (BOOL)isInvalidState:(SBJsonStreamWriter*)writer;
+- (void)appendSeparator:(SBJsonStreamWriter*)writer;
+- (BOOL)expectingKey:(SBJsonStreamWriter*)writer;
+- (void)transitionState:(SBJsonStreamWriter*)writer;
+- (void)appendWhitespace:(SBJsonStreamWriter*)writer;
+@end
+
+@interface SBJsonStreamWriterStateObjectStart : SBJsonStreamWriterState
+@end
+
+@interface SBJsonStreamWriterStateObjectKey : SBJsonStreamWriterStateObjectStart
+@end
+
+@interface SBJsonStreamWriterStateObjectValue : SBJsonStreamWriterState
+@end
+
+@interface SBJsonStreamWriterStateArrayStart : SBJsonStreamWriterState
+@end
+
+@interface SBJsonStreamWriterStateArrayValue : SBJsonStreamWriterState
+@end
+
+@interface SBJsonStreamWriterStateStart : SBJsonStreamWriterState
+@end
+
+@interface SBJsonStreamWriterStateComplete : SBJsonStreamWriterState
+@end
+
+@interface SBJsonStreamWriterStateError : SBJsonStreamWriterState
+@end
+
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ios/UGAPI/SBJson/SBJsonStreamWriterState.m
----------------------------------------------------------------------
diff --git a/sdks/other/ios/UGAPI/SBJson/SBJsonStreamWriterState.m b/sdks/other/ios/UGAPI/SBJson/SBJsonStreamWriterState.m
new file mode 100755
index 0000000..9f04cac
--- /dev/null
+++ b/sdks/other/ios/UGAPI/SBJson/SBJsonStreamWriterState.m
@@ -0,0 +1,139 @@
+/*
+ Copyright (c) 2010, Stig Brautaset.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ Neither the name of the the author nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SBJsonStreamWriterState.h"
+#import "SBJsonStreamWriter.h"
+
+#define SINGLETON \
++ (id)sharedInstance { \
+ static id state; \
+ if (!state) state = [[self alloc] init]; \
+ return state; \
+}
+
+
+@implementation SBJsonStreamWriterState
++ (id)sharedInstance { return nil; }
+- (BOOL)isInvalidState:(SBJsonStreamWriter*)writer { return NO; }
+- (void)appendSeparator:(SBJsonStreamWriter*)writer {}
+- (BOOL)expectingKey:(SBJsonStreamWriter*)writer { return NO; }
+- (void)transitionState:(SBJsonStreamWriter *)writer {}
+- (void)appendWhitespace:(SBJsonStreamWriter*)writer {
+ [writer appendBytes:"\n" length:1];
+ for (NSUInteger i = 0; i < writer.stateStack.count; i++)
+ [writer appendBytes:" " length:2];
+}
+@end
+
+@implementation SBJsonStreamWriterStateObjectStart
+
+SINGLETON
+
+- (void)transitionState:(SBJsonStreamWriter *)writer {
+ writer.state = [SBJsonStreamWriterStateObjectValue sharedInstance];
+}
+- (BOOL)expectingKey:(SBJsonStreamWriter *)writer {
+ writer.error = @"JSON object key must be string";
+ return YES;
+}
+@end
+
+@implementation SBJsonStreamWriterStateObjectKey
+
+SINGLETON
+
+- (void)appendSeparator:(SBJsonStreamWriter *)writer {
+ [writer appendBytes:"," length:1];
+}
+@end
+
+@implementation SBJsonStreamWriterStateObjectValue
+
+SINGLETON
+
+- (void)appendSeparator:(SBJsonStreamWriter *)writer {
+ [writer appendBytes:":" length:1];
+}
+- (void)transitionState:(SBJsonStreamWriter *)writer {
+ writer.state = [SBJsonStreamWriterStateObjectKey sharedInstance];
+}
+- (void)appendWhitespace:(SBJsonStreamWriter *)writer {
+ [writer appendBytes:" " length:1];
+}
+@end
+
+@implementation SBJsonStreamWriterStateArrayStart
+
+SINGLETON
+
+- (void)transitionState:(SBJsonStreamWriter *)writer {
+ writer.state = [SBJsonStreamWriterStateArrayValue sharedInstance];
+}
+@end
+
+@implementation SBJsonStreamWriterStateArrayValue
+
+SINGLETON
+
+- (void)appendSeparator:(SBJsonStreamWriter *)writer {
+ [writer appendBytes:"," length:1];
+}
+@end
+
+@implementation SBJsonStreamWriterStateStart
+
+SINGLETON
+
+
+- (void)transitionState:(SBJsonStreamWriter *)writer {
+ writer.state = [SBJsonStreamWriterStateComplete sharedInstance];
+}
+- (void)appendSeparator:(SBJsonStreamWriter *)writer {
+}
+@end
+
+@implementation SBJsonStreamWriterStateComplete
+
+SINGLETON
+
+- (BOOL)isInvalidState:(SBJsonStreamWriter*)writer {
+ writer.error = @"Stream is closed";
+ return YES;
+}
+@end
+
+@implementation SBJsonStreamWriterStateError
+
+SINGLETON
+
+@end
+
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ios/UGAPI/SBJson/SBJsonTokeniser.h
----------------------------------------------------------------------
diff --git a/sdks/other/ios/UGAPI/SBJson/SBJsonTokeniser.h b/sdks/other/ios/UGAPI/SBJson/SBJsonTokeniser.h
new file mode 100755
index 0000000..e484a94
--- /dev/null
+++ b/sdks/other/ios/UGAPI/SBJson/SBJsonTokeniser.h
@@ -0,0 +1,67 @@
+/*
+ Copyright (c) 2010, Stig Brautaset.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ Neither the name of the the author nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Foundation/Foundation.h>
+
+typedef enum {
+ sbjson_token_error = -1,
+ sbjson_token_eof,
+
+ sbjson_token_array_start,
+ sbjson_token_array_end,
+
+ sbjson_token_object_start,
+ sbjson_token_object_end,
+
+ sbjson_token_separator,
+ sbjson_token_keyval_separator,
+
+ sbjson_token_number,
+ sbjson_token_string,
+ sbjson_token_true,
+ sbjson_token_false,
+ sbjson_token_null,
+
+} sbjson_token_t;
+
+@class SBJsonUTF8Stream;
+
+@interface SBJsonTokeniser : NSObject
+
+@property (strong) SBJsonUTF8Stream *stream;
+@property (copy) NSString *error;
+
+- (void)appendData:(NSData*)data_;
+
+- (sbjson_token_t)getToken:(NSObject**)token;
+
+@end
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ios/UGAPI/SBJson/SBJsonTokeniser.m
----------------------------------------------------------------------
diff --git a/sdks/other/ios/UGAPI/SBJson/SBJsonTokeniser.m b/sdks/other/ios/UGAPI/SBJson/SBJsonTokeniser.m
new file mode 100755
index 0000000..75d3268
--- /dev/null
+++ b/sdks/other/ios/UGAPI/SBJson/SBJsonTokeniser.m
@@ -0,0 +1,453 @@
+/*
+ Copyright (c) 2010-2011, Stig Brautaset. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ Neither the name of the the author nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SBJsonTokeniser.h"
+#import "SBJsonUTF8Stream.h"
+
+#define SBStringIsIllegalSurrogateHighCharacter(character) (((character) >= 0xD800UL) && ((character) <= 0xDFFFUL))
+#define SBStringIsSurrogateLowCharacter(character) ((character >= 0xDC00UL) && (character <= 0xDFFFUL))
+#define SBStringIsSurrogateHighCharacter(character) ((character >= 0xD800UL) && (character <= 0xDBFFUL))
+
+@implementation SBJsonTokeniser
+
+@synthesize error = _error;
+@synthesize stream = _stream;
+
+- (id)init {
+ self = [super init];
+ if (self) {
+ _stream = [[SBJsonUTF8Stream alloc] init];
+
+ }
+
+ return self;
+}
+
+
+- (void)appendData:(NSData *)data_ {
+ [_stream appendData:data_];
+}
+
+
+- (sbjson_token_t)match:(const char *)pattern length:(NSUInteger)len retval:(sbjson_token_t)token {
+ if (![_stream haveRemainingCharacters:len])
+ return sbjson_token_eof;
+
+ if ([_stream skipCharacters:pattern length:len])
+ return token;
+
+ self.error = [NSString stringWithFormat:@"Expected '%s' after initial '%.1s'", pattern, pattern];
+ return sbjson_token_error;
+}
+
+- (BOOL)decodeEscape:(unichar)ch into:(unichar*)decoded {
+ switch (ch) {
+ case '\\':
+ case '/':
+ case '"':
+ *decoded = ch;
+ break;
+
+ case 'b':
+ *decoded = '\b';
+ break;
+
+ case 'n':
+ *decoded = '\n';
+ break;
+
+ case 'r':
+ *decoded = '\r';
+ break;
+
+ case 't':
+ *decoded = '\t';
+ break;
+
+ case 'f':
+ *decoded = '\f';
+ break;
+
+ default:
+ self.error = @"Illegal escape character";
+ return NO;
+ break;
+ }
+ return YES;
+}
+
+- (BOOL)decodeHexQuad:(unichar*)quad {
+ unichar c, tmp = 0;
+
+ for (int i = 0; i < 4; i++) {
+ (void)[_stream getNextUnichar:&c];
+ tmp *= 16;
+ switch (c) {
+ case '0' ... '9':
+ tmp += c - '0';
+ break;
+
+ case 'a' ... 'f':
+ tmp += 10 + c - 'a';
+ break;
+
+ case 'A' ... 'F':
+ tmp += 10 + c - 'A';
+ break;
+
+ default:
+ return NO;
+ }
+ }
+ *quad = tmp;
+ return YES;
+}
+
+- (sbjson_token_t)getStringToken:(NSObject**)token {
+ NSMutableString *acc = nil;
+
+ for (;;) {
+ [_stream skip];
+
+ unichar ch;
+ {
+ NSMutableString *string = nil;
+
+ if (![_stream getStringFragment:&string])
+ return sbjson_token_eof;
+
+ if (!string) {
+ self.error = @"Broken Unicode encoding";
+ return sbjson_token_error;
+ }
+
+ if (![_stream getUnichar:&ch])
+ return sbjson_token_eof;
+
+ if (acc) {
+ [acc appendString:string];
+
+ } else if (ch == '"') {
+ *token = [string copy];
+ [_stream skip];
+ return sbjson_token_string;
+
+ } else {
+ acc = [string mutableCopy];
+ }
+ }
+
+
+ switch (ch) {
+ case 0 ... 0x1F:
+ self.error = [NSString stringWithFormat:@"Unescaped control character [0x%0.2X]", (int)ch];
+ return sbjson_token_error;
+ break;
+
+ case '"':
+ *token = acc;
+ [_stream skip];
+ return sbjson_token_string;
+ break;
+
+ case '\\':
+ if (![_stream getNextUnichar:&ch])
+ return sbjson_token_eof;
+
+ if (ch == 'u') {
+ if (![_stream haveRemainingCharacters:5])
+ return sbjson_token_eof;
+
+ unichar hi;
+ if (![self decodeHexQuad:&hi]) {
+ self.error = @"Invalid hex quad";
+ return sbjson_token_error;
+ }
+
+ if (SBStringIsSurrogateHighCharacter(hi)) {
+ unichar lo;
+
+ if (![_stream haveRemainingCharacters:6])
+ return sbjson_token_eof;
+
+ (void)[_stream getNextUnichar:&ch];
+ (void)[_stream getNextUnichar:&lo];
+ if (ch != '\\' || lo != 'u' || ![self decodeHexQuad:&lo]) {
+ self.error = @"Missing low character in surrogate pair";
+ return sbjson_token_error;
+ }
+
+ if (!SBStringIsSurrogateLowCharacter(lo)) {
+ self.error = @"Invalid low character in surrogate pair";
+ return sbjson_token_error;
+ }
+
+ [acc appendFormat:@"%C%C", hi, lo];
+ } else if (SBStringIsIllegalSurrogateHighCharacter(hi)) {
+ self.error = @"Invalid high character in surrogate pair";
+ return sbjson_token_error;
+ } else {
+ [acc appendFormat:@"%C", hi];
+ }
+
+
+ } else {
+ unichar decoded;
+ if (![self decodeEscape:ch into:&decoded])
+ return sbjson_token_error;
+ [acc appendFormat:@"%C", decoded];
+ }
+
+ break;
+
+ default: {
+ self.error = [NSString stringWithFormat:@"Invalid UTF-8: '%x'", (int)ch];
+ return sbjson_token_error;
+ break;
+ }
+ }
+ }
+ return sbjson_token_eof;
+}
+
+- (sbjson_token_t)getNumberToken:(NSObject**)token {
+
+ NSUInteger numberStart = _stream.index;
+ NSCharacterSet *digits = [NSCharacterSet decimalDigitCharacterSet];
+
+ unichar ch;
+ if (![_stream getUnichar:&ch])
+ return sbjson_token_eof;
+
+ BOOL isNegative = NO;
+ if (ch == '-') {
+ isNegative = YES;
+ if (![_stream getNextUnichar:&ch])
+ return sbjson_token_eof;
+ }
+
+ unsigned long long mantissa = 0;
+ int mantissa_length = 0;
+
+ if (ch == '0') {
+ mantissa_length++;
+ if (![_stream getNextUnichar:&ch])
+ return sbjson_token_eof;
+
+ if ([digits characterIsMember:ch]) {
+ self.error = @"Leading zero is illegal in number";
+ return sbjson_token_error;
+ }
+ }
+
+ while ([digits characterIsMember:ch]) {
+ mantissa *= 10;
+ mantissa += (ch - '0');
+ mantissa_length++;
+
+ if (![_stream getNextUnichar:&ch])
+ return sbjson_token_eof;
+ }
+
+ short exponent = 0;
+ BOOL isFloat = NO;
+
+ if (ch == '.') {
+ isFloat = YES;
+ if (![_stream getNextUnichar:&ch])
+ return sbjson_token_eof;
+
+ while ([digits characterIsMember:ch]) {
+ mantissa *= 10;
+ mantissa += (ch - '0');
+ mantissa_length++;
+ exponent--;
+
+ if (![_stream getNextUnichar:&ch])
+ return sbjson_token_eof;
+ }
+
+ if (!exponent) {
+ self.error = @"No digits after decimal point";
+ return sbjson_token_error;
+ }
+ }
+
+ BOOL hasExponent = NO;
+ if (ch == 'e' || ch == 'E') {
+ hasExponent = YES;
+
+ if (![_stream getNextUnichar:&ch])
+ return sbjson_token_eof;
+
+ BOOL expIsNegative = NO;
+ if (ch == '-') {
+ expIsNegative = YES;
+ if (![_stream getNextUnichar:&ch])
+ return sbjson_token_eof;
+
+ } else if (ch == '+') {
+ if (![_stream getNextUnichar:&ch])
+ return sbjson_token_eof;
+ }
+
+ short explicit_exponent = 0;
+ short explicit_exponent_length = 0;
+ while ([digits characterIsMember:ch]) {
+ explicit_exponent *= 10;
+ explicit_exponent += (ch - '0');
+ explicit_exponent_length++;
+
+ if (![_stream getNextUnichar:&ch])
+ return sbjson_token_eof;
+ }
+
+ if (explicit_exponent_length == 0) {
+ self.error = @"No digits in exponent";
+ return sbjson_token_error;
+ }
+
+ if (expIsNegative)
+ exponent -= explicit_exponent;
+ else
+ exponent += explicit_exponent;
+ }
+
+ if (!mantissa_length && isNegative) {
+ self.error = @"No digits after initial minus";
+ return sbjson_token_error;
+
+ } else if (mantissa_length >= 19) {
+
+ NSString *number = [_stream stringWithRange:NSMakeRange(numberStart, _stream.index - numberStart)];
+ *token = [NSDecimalNumber decimalNumberWithString:number];
+
+ } else if (!isFloat && !hasExponent) {
+ if (!isNegative)
+ *token = [NSNumber numberWithUnsignedLongLong:mantissa];
+ else
+ *token = [NSNumber numberWithLongLong:-mantissa];
+ } else {
+ *token = [NSDecimalNumber decimalNumberWithMantissa:mantissa
+ exponent:exponent
+ isNegative:isNegative];
+ }
+
+ return sbjson_token_number;
+}
+
+- (sbjson_token_t)getToken:(NSObject **)token {
+
+ [_stream skipWhitespace];
+
+ unichar ch;
+ if (![_stream getUnichar:&ch])
+ return sbjson_token_eof;
+
+ NSUInteger oldIndexLocation = _stream.index;
+ sbjson_token_t tok;
+
+ switch (ch) {
+ case '[':
+ tok = sbjson_token_array_start;
+ [_stream skip];
+ break;
+
+ case ']':
+ tok = sbjson_token_array_end;
+ [_stream skip];
+ break;
+
+ case '{':
+ tok = sbjson_token_object_start;
+ [_stream skip];
+ break;
+
+ case ':':
+ tok = sbjson_token_keyval_separator;
+ [_stream skip];
+ break;
+
+ case '}':
+ tok = sbjson_token_object_end;
+ [_stream skip];
+ break;
+
+ case ',':
+ tok = sbjson_token_separator;
+ [_stream skip];
+ break;
+
+ case 'n':
+ tok = [self match:"null" length:4 retval:sbjson_token_null];
+ break;
+
+ case 't':
+ tok = [self match:"true" length:4 retval:sbjson_token_true];
+ break;
+
+ case 'f':
+ tok = [self match:"false" length:5 retval:sbjson_token_false];
+ break;
+
+ case '"':
+ tok = [self getStringToken:token];
+ break;
+
+ case '0' ... '9':
+ case '-':
+ tok = [self getNumberToken:token];
+ break;
+
+ case '+':
+ self.error = @"Leading + is illegal in number";
+ tok = sbjson_token_error;
+ break;
+
+ default:
+ self.error = [NSString stringWithFormat:@"Illegal start of token [%c]", ch];
+ tok = sbjson_token_error;
+ break;
+ }
+
+ if (tok == sbjson_token_eof) {
+ // We ran out of bytes in the middle of a token.
+ // We don't know how to restart in mid-flight, so
+ // rewind to the start of the token for next attempt.
+ // Hopefully we'll have more data then.
+ _stream.index = oldIndexLocation;
+ }
+
+ return tok;
+}
+
+
+@end
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ios/UGAPI/SBJson/SBJsonUTF8Stream.h
----------------------------------------------------------------------
diff --git a/sdks/other/ios/UGAPI/SBJson/SBJsonUTF8Stream.h b/sdks/other/ios/UGAPI/SBJson/SBJsonUTF8Stream.h
new file mode 100755
index 0000000..a26f032
--- /dev/null
+++ b/sdks/other/ios/UGAPI/SBJson/SBJsonUTF8Stream.h
@@ -0,0 +1,58 @@
+/*
+ Copyright (c) 2011, Stig Brautaset. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ Neither the name of the the author nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Foundation/Foundation.h>
+
+
+@interface SBJsonUTF8Stream : NSObject {
+@private
+ const char *_bytes;
+ NSMutableData *_data;
+ NSUInteger _length;
+}
+
+@property (assign) NSUInteger index;
+
+- (void)appendData:(NSData*)data_;
+
+- (BOOL)haveRemainingCharacters:(NSUInteger)chars;
+
+- (void)skip;
+- (void)skipWhitespace;
+- (BOOL)skipCharacters:(const char *)chars length:(NSUInteger)len;
+
+- (BOOL)getUnichar:(unichar*)ch;
+- (BOOL)getNextUnichar:(unichar*)ch;
+- (BOOL)getStringFragment:(NSString**)string;
+
+- (NSString*)stringWithRange:(NSRange)range;
+
+@end
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ios/UGAPI/SBJson/SBJsonUTF8Stream.m
----------------------------------------------------------------------
diff --git a/sdks/other/ios/UGAPI/SBJson/SBJsonUTF8Stream.m b/sdks/other/ios/UGAPI/SBJson/SBJsonUTF8Stream.m
new file mode 100755
index 0000000..f57015d
--- /dev/null
+++ b/sdks/other/ios/UGAPI/SBJson/SBJsonUTF8Stream.m
@@ -0,0 +1,141 @@
+/*
+ Copyright (c) 2011, Stig Brautaset. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ Neither the name of the the author nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SBJsonUTF8Stream.h"
+
+
+@implementation SBJsonUTF8Stream
+
+@synthesize index = _index;
+
+- (id)init {
+ self = [super init];
+ if (self) {
+ _data = [[NSMutableData alloc] initWithCapacity:4096u];
+ }
+ return self;
+}
+
+
+- (void)appendData:(NSData *)data_ {
+
+ if (_index) {
+ // Discard data we've already parsed
+ [_data replaceBytesInRange:NSMakeRange(0, _index) withBytes:"" length:0];
+
+ // Reset index to point to current position
+ _index = 0;
+ }
+
+ [_data appendData:data_];
+
+ // This is an optimisation.
+ _bytes = (const char*)[_data bytes];
+ _length = [_data length];
+}
+
+
+- (BOOL)getUnichar:(unichar*)ch {
+ if (_index < _length) {
+ *ch = (unichar)_bytes[_index];
+ return YES;
+ }
+ return NO;
+}
+
+- (BOOL)getNextUnichar:(unichar*)ch {
+ if (++_index < _length) {
+ *ch = (unichar)_bytes[_index];
+ return YES;
+ }
+ return NO;
+}
+
+- (BOOL)getStringFragment:(NSString **)string {
+ NSUInteger start = _index;
+ while (_index < _length) {
+ switch (_bytes[_index]) {
+ case '"':
+ case '\\':
+ case 0 ... 0x1f:
+ *string = [[NSString alloc] initWithBytes:(_bytes + start)
+ length:(_index - start)
+ encoding:NSUTF8StringEncoding];
+ return YES;
+ break;
+ default:
+ _index++;
+ break;
+ }
+ }
+ return NO;
+}
+
+- (void)skip {
+ _index++;
+}
+
+- (void)skipWhitespace {
+ while (_index < _length) {
+ switch (_bytes[_index]) {
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ _index++;
+ break;
+ default:
+ return;
+ break;
+ }
+ }
+}
+
+- (BOOL)haveRemainingCharacters:(NSUInteger)chars {
+ return [_data length] - _index >= chars;
+}
+
+- (BOOL)skipCharacters:(const char *)chars length:(NSUInteger)len {
+ const void *bytes = ((const char*)[_data bytes]) + _index;
+ if (!memcmp(bytes, chars, len)) {
+ _index += len;
+ return YES;
+ }
+ return NO;
+}
+
+- (NSString*)stringWithRange:(NSRange)range {
+ return [[NSString alloc] initWithBytes:_bytes + range.location length:range.length encoding:NSUTF8StringEncoding];
+
+}
+
+
+@end
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ios/UGAPI/SBJson/SBJsonWriter.h
----------------------------------------------------------------------
diff --git a/sdks/other/ios/UGAPI/SBJson/SBJsonWriter.h b/sdks/other/ios/UGAPI/SBJson/SBJsonWriter.h
new file mode 100755
index 0000000..640816c
--- /dev/null
+++ b/sdks/other/ios/UGAPI/SBJson/SBJsonWriter.h
@@ -0,0 +1,117 @@
+/*
+ Copyright (C) 2009 Stig Brautaset. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of the author nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Foundation/Foundation.h>
+
+/**
+ @brief The JSON writer class.
+
+ This uses SBJsonStreamWriter internally.
+
+ @see @ref json2objc
+ */
+
+@interface SBJsonWriter : NSObject
+
+/**
+ @brief The maximum recursing depth.
+
+ Defaults to 32. If the input is nested deeper than this the input will be deemed to be
+ malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can
+ turn off this security feature by setting the maxDepth value to 0.
+ */
+@property NSUInteger maxDepth;
+
+/**
+ @brief Return an error trace, or nil if there was no errors.
+
+ Note that this method returns the trace of the last method that failed.
+ You need to check the return value of the call you're making to figure out
+ if the call actually failed, before you know call this method.
+ */
+@property (readonly, copy) NSString *error;
+
+/**
+ @brief Whether we are generating human-readable (multiline) JSON.
+
+ Set whether or not to generate human-readable JSON. The default is NO, which produces
+ JSON without any whitespace. (Except inside strings.) If set to YES, generates human-readable
+ JSON with linebreaks after each array value and dictionary key/value pair, indented two
+ spaces per nesting level.
+ */
+@property BOOL humanReadable;
+
+/**
+ @brief Whether or not to sort the dictionary keys in the output.
+
+ If this is set to YES, the dictionary keys in the JSON output will be in sorted order.
+ (This is useful if you need to compare two structures, for example.) The default is NO.
+ */
+@property BOOL sortKeys;
+
+/**
+ @brief An optional comparator to be used if sortKeys is YES.
+
+ If this is nil, sorting will be done via @selector(compare:).
+ */
+@property (copy) NSComparator sortKeysComparator;
+
+/**
+ @brief Return JSON representation for the given object.
+
+ Returns a string containing JSON representation of the passed in value, or nil on error.
+ If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
+
+ @param value any instance that can be represented as JSON text.
+ */
+- (NSString*)stringWithObject:(id)value;
+
+/**
+ @brief Return JSON representation for the given object.
+
+ Returns an NSData object containing JSON represented as UTF8 text, or nil on error.
+
+ @param value any instance that can be represented as JSON text.
+ */
+- (NSData*)dataWithObject:(id)value;
+
+/**
+ @brief Return JSON representation (or fragment) for the given object.
+
+ Returns a string containing JSON representation of the passed in value, or nil on error.
+ If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
+
+ @param value any instance that can be represented as a JSON fragment
+ @param error pointer to object to be populated with NSError on failure
+
+ */- (NSString*)stringWithObject:(id)value
+ error:(NSError**)error;
+
+
+@end
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ios/UGAPI/SBJson/SBJsonWriter.m
----------------------------------------------------------------------
diff --git a/sdks/other/ios/UGAPI/SBJson/SBJsonWriter.m b/sdks/other/ios/UGAPI/SBJson/SBJsonWriter.m
new file mode 100755
index 0000000..d200f9c
--- /dev/null
+++ b/sdks/other/ios/UGAPI/SBJson/SBJsonWriter.m
@@ -0,0 +1,112 @@
+/*
+ Copyright (C) 2009 Stig Brautaset. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name of the author nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "SBJsonWriter.h"
+#import "SBJsonStreamWriter.h"
+#import "SBJsonStreamWriterAccumulator.h"
+
+
+@interface SBJsonWriter ()
+@property (copy) NSString *error;
+@end
+
+@implementation SBJsonWriter
+
+@synthesize sortKeys;
+@synthesize humanReadable;
+
+@synthesize error;
+@synthesize maxDepth;
+
+@synthesize sortKeysComparator;
+
+- (id)init {
+ self = [super init];
+ if (self) {
+ self.maxDepth = 32u;
+ }
+ return self;
+}
+
+
+- (NSString*)stringWithObject:(id)value {
+ NSData *data = [self dataWithObject:value];
+ if (data)
+ return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+ return nil;
+}
+
+- (NSString*)stringWithObject:(id)value error:(NSError**)error_ {
+ NSString *tmp = [self stringWithObject:value];
+ if (tmp)
+ return tmp;
+
+ if (error_) {
+ NSDictionary *ui = [NSDictionary dictionaryWithObjectsAndKeys:error, NSLocalizedDescriptionKey, nil];
+ *error_ = [NSError errorWithDomain:@"org.brautaset.SBJsonWriter.ErrorDomain" code:0 userInfo:ui];
+ }
+
+ return nil;
+}
+
+- (NSData*)dataWithObject:(id)object {
+ self.error = nil;
+
+ SBJsonStreamWriterAccumulator *accumulator = [[SBJsonStreamWriterAccumulator alloc] init];
+
+ SBJsonStreamWriter *streamWriter = [[SBJsonStreamWriter alloc] init];
+ streamWriter.sortKeys = self.sortKeys;
+ streamWriter.maxDepth = self.maxDepth;
+ streamWriter.sortKeysComparator = self.sortKeysComparator;
+ streamWriter.humanReadable = self.humanReadable;
+ streamWriter.delegate = accumulator;
+
+ BOOL ok = NO;
+ if ([object isKindOfClass:[NSDictionary class]])
+ ok = [streamWriter writeObject:object];
+
+ else if ([object isKindOfClass:[NSArray class]])
+ ok = [streamWriter writeArray:object];
+
+ else if ([object respondsToSelector:@selector(proxyForJson)])
+ return [self dataWithObject:[object proxyForJson]];
+ else {
+ self.error = @"Not valid type for JSON";
+ return nil;
+ }
+
+ if (ok)
+ return accumulator.data;
+
+ self.error = streamWriter.error;
+ return nil;
+}
+
+
+@end
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ios/UGAPI/SSKeychain.h
----------------------------------------------------------------------
diff --git a/sdks/other/ios/UGAPI/SSKeychain.h b/sdks/other/ios/UGAPI/SSKeychain.h
new file mode 100644
index 0000000..23093b6
--- /dev/null
+++ b/sdks/other/ios/UGAPI/SSKeychain.h
@@ -0,0 +1,357 @@
+//
+// SSKeychain.h
+// SSToolkit
+//
+// Created by Sam Soffes on 5/19/10.
+// Copyright (c) 2009-2011 Sam Soffes. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import <Security/Security.h>
+
+/** Error codes that can be returned in NSError objects. */
+typedef enum {
+ /** No error. */
+ SSKeychainErrorNone = noErr,
+
+ /** Some of the arguments were invalid. */
+ SSKeychainErrorBadArguments = -1001,
+
+ /** There was no password. */
+ SSKeychainErrorNoPassword = -1002,
+
+ /** One or more parameters passed internally were not valid. */
+ SSKeychainErrorInvalidParameter = errSecParam,
+
+ /** Failed to allocate memory. */
+ SSKeychainErrorFailedToAllocated = errSecAllocate,
+
+ /** No trust results are available. */
+ SSKeychainErrorNotAvailable = errSecNotAvailable,
+
+ /** Authorization/Authentication failed. */
+ SSKeychainErrorAuthorizationFailed = errSecAuthFailed,
+
+ /** The item already exists. */
+ SSKeychainErrorDuplicatedItem = errSecDuplicateItem,
+
+ /** The item cannot be found.*/
+ SSKeychainErrorNotFound = errSecItemNotFound,
+
+ /** Interaction with the Security Server is not allowed. */
+ SSKeychainErrorInteractionNotAllowed = errSecInteractionNotAllowed,
+
+ /** Unable to decode the provided data. */
+ SSKeychainErrorFailedToDecode = errSecDecode
+} SSKeychainErrorCode;
+
+extern NSString *const kSSKeychainErrorDomain;
+
+/** Account name. */
+extern NSString *const kSSKeychainAccountKey;
+
+/**
+ Time the item was created.
+
+ The value will be a string.
+ */
+extern NSString *const kSSKeychainCreatedAtKey;
+
+/** Item class. */
+extern NSString *const kSSKeychainClassKey;
+
+/** Item description. */
+extern NSString *const kSSKeychainDescriptionKey;
+
+/** Item label. */
+extern NSString *const kSSKeychainLabelKey;
+
+/** Time the item was last modified.
+
+ The value will be a string.
+ */
+extern NSString *const kSSKeychainLastModifiedKey;
+
+/** Where the item was created. */
+extern NSString *const kSSKeychainWhereKey;
+
+/**
+ Simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system
+ Keychain on Mac OS X and iOS.
+
+ This was originally inspired by EMKeychain and SDKeychain (both of which are now gone). Thanks to the authors.
+ SSKeychain has since switched to a simpler implementation that was abstracted from [SSToolkit](http://sstoolk.it).
+ */
+@interface SSKeychain : NSObject
+
+///-----------------------
+/// @name Getting Accounts
+///-----------------------
+
+/**
+ Returns an array containing the Keychain's accounts, or `nil` if the Keychain has no accounts.
+
+ See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the
+ dictionaries returned by this method.
+
+ @return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any
+ accounts. The order of the objects in the array isn't defined.
+
+ @see allAccounts:
+ */
++ (NSArray *)allAccounts;
+
+/**
+ Returns an array containing the Keychain's accounts, or `nil` if the Keychain doesn't have any
+ accounts.
+
+ See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the
+ dictionaries returned by this method.
+
+ @param error If accessing the accounts fails, upon return contains an error that describes the problem.
+
+ @return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any
+ accounts. The order of the objects in the array isn't defined.
+
+ @see allAccounts
+ */
++ (NSArray *)allAccounts:(NSError **)error;
+
+/**
+ Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any
+ accounts for the given service.
+
+ See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the
+ dictionaries returned by this method.
+
+ @param serviceName The service for which to return the corresponding accounts.
+
+ @return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain
+ doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined.
+
+ @see accountsForService:error:
+ */
++ (NSArray *)accountsForService:(NSString *)serviceName;
+
+/**
+ Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any
+ accounts for the given service.
+
+ @param serviceName The service for which to return the corresponding accounts.
+
+ @param error If accessing the accounts fails, upon return contains an error that describes the problem.
+
+ @return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain
+ doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined.
+
+ @see accountsForService:
+ */
++ (NSArray *)accountsForService:(NSString *)serviceName error:(NSError **)error;
+
+
+///------------------------
+/// @name Getting Passwords
+///------------------------
+
+/**
+ Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a
+ password for the given parameters.
+
+ @param serviceName The service for which to return the corresponding password.
+
+ @param account The account for which to return the corresponding password.
+
+ @return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't
+ have a password for the given parameters.
+
+ @see passwordForService:account:error:
+ */
++ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account;
+
+/**
+ Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a
+ password for the given parameters.
+
+ @param serviceName The service for which to return the corresponding password.
+
+ @param account The account for which to return the corresponding password.
+
+ @param error If accessing the password fails, upon return contains an error that describes the problem.
+
+ @return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't
+ have a password for the given parameters.
+
+ @see passwordForService:account:
+ */
++ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
+
+/**
+ Returns the password data for a given account and service, or `nil` if the Keychain doesn't have data
+ for the given parameters.
+
+ @param serviceName The service for which to return the corresponding password.
+
+ @param account The account for which to return the corresponding password.
+
+ @param error If accessing the password fails, upon return contains an error that describes the problem.
+
+ @return Returns a the password data for the given account and service, or `nil` if the Keychain doesn't
+ have data for the given parameters.
+
+ @see passwordDataForService:account:error:
+ */
++ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account;
+
+/**
+ Returns the password data for a given account and service, or `nil` if the Keychain doesn't have data
+ for the given parameters.
+
+ @param serviceName The service for which to return the corresponding password.
+
+ @param account The account for which to return the corresponding password.
+
+ @param error If accessing the password fails, upon return contains an error that describes the problem.
+
+ @return Returns a the password data for the given account and service, or `nil` if the Keychain doesn't
+ have a password for the given parameters.
+
+ @see passwordDataForService:account:
+ */
++ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
+
+
+///-------------------------
+/// @name Deleting Passwords
+///-------------------------
+
+/**
+ Deletes a password from the Keychain.
+
+ @param serviceName The service for which to delete the corresponding password.
+
+ @param account The account for which to delete the corresponding password.
+
+ @return Returns `YES` on success, or `NO` on failure.
+
+ @see deletePasswordForService:account:error:
+ */
++ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account;
+
+/**
+ Deletes a password from the Keychain.
+
+ @param serviceName The service for which to delete the corresponding password.
+
+ @param account The account for which to delete the corresponding password.
+
+ @param error If deleting the password fails, upon return contains an error that describes the problem.
+
+ @return Returns `YES` on success, or `NO` on failure.
+
+ @see deletePasswordForService:account:
+ */
++ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
+
+
+///------------------------
+/// @name Setting Passwords
+///------------------------
+
+/**
+ Sets a password in the Keychain.
+
+ @param password The password to store in the Keychain.
+
+ @param serviceName The service for which to set the corresponding password.
+
+ @param account The account for which to set the corresponding password.
+
+ @return Returns `YES` on success, or `NO` on failure.
+
+ @see setPassword:forService:account:error:
+ */
++ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account;
+
+/**
+ Sets a password in the Keychain.
+
+ @param password The password to store in the Keychain.
+
+ @param serviceName The service for which to set the corresponding password.
+
+ @param account The account for which to set the corresponding password.
+
+ @param error If setting the password fails, upon return contains an error that describes the problem.
+
+ @return Returns `YES` on success, or `NO` on failure.
+
+ @see setPassword:forService:account:
+ */
++ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
+
+/**
+ Sets arbirary data in the Keychain.
+
+ @param password The data to store in the Keychain.
+
+ @param serviceName The service for which to set the corresponding password.
+
+ @param account The account for which to set the corresponding password.
+
+ @param error If setting the password fails, upon return contains an error that describes the problem.
+
+ @return Returns `YES` on success, or `NO` on failure.
+
+ @see setPasswordData:forService:account:error:
+ */
++ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account;
+
+/**
+ Sets arbirary data in the Keychain.
+
+ @param password The data to store in the Keychain.
+
+ @param serviceName The service for which to set the corresponding password.
+
+ @param account The account for which to set the corresponding password.
+
+ @param error If setting the password fails, upon return contains an error that describes the problem.
+
+ @return Returns `YES` on success, or `NO` on failure.
+
+ @see setPasswordData:forService:account:
+ */
++ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
+
+
+///--------------------
+/// @name Configuration
+///--------------------
+
+#if __IPHONE_4_0 && TARGET_OS_IPHONE
+/**
+ Returns the accessibility type for all future passwords saved to the Keychain.
+
+ @return Returns the accessibility type.
+
+ The return value will be `NULL` or one of the "Keychain Item Accessibility Constants" used for determining when a
+ keychain item should be readable.
+
+ @see accessibilityType
+ */
++ (CFTypeRef)accessibilityType;
+
+/**
+ Sets the accessibility type for all future passwords saved to the Keychain.
+
+ @param accessibilityType One of the "Keychain Item Accessibility Constants" used for determining when a keychain item
+ should be readable.
+
+ If the value is `NULL` (the default), the Keychain default will be used.
+
+ @see accessibilityType
+ */
++ (void)setAccessibilityType:(CFTypeRef)accessibilityType;
+#endif
+
+@end
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ios/UGAPI/SSKeychain.m
----------------------------------------------------------------------
diff --git a/sdks/other/ios/UGAPI/SSKeychain.m b/sdks/other/ios/UGAPI/SSKeychain.m
new file mode 100644
index 0000000..1267b5e
--- /dev/null
+++ b/sdks/other/ios/UGAPI/SSKeychain.m
@@ -0,0 +1,262 @@
+//
+// SSKeychain.m
+// SSToolkit
+//
+// Created by Sam Soffes on 5/19/10.
+// Copyright (c) 2009-2011 Sam Soffes. All rights reserved.
+//
+
+#import "SSKeychain.h"
+
+NSString *const kSSKeychainErrorDomain = @"com.samsoffes.sskeychain";
+
+NSString *const kSSKeychainAccountKey = @"acct";
+NSString *const kSSKeychainCreatedAtKey = @"cdat";
+NSString *const kSSKeychainClassKey = @"labl";
+NSString *const kSSKeychainDescriptionKey = @"desc";
+NSString *const kSSKeychainLabelKey = @"labl";
+NSString *const kSSKeychainLastModifiedKey = @"mdat";
+NSString *const kSSKeychainWhereKey = @"svce";
+
+#if __IPHONE_4_0 && TARGET_OS_IPHONE
+CFTypeRef SSKeychainAccessibilityType = NULL;
+#endif
+
+@interface SSKeychain ()
++ (NSMutableDictionary *)_queryForService:(NSString *)service account:(NSString *)account;
+@end
+
+@implementation SSKeychain
+
+#pragma mark - Getting Accounts
+
++ (NSArray *)allAccounts {
+ return [self accountsForService:nil error:nil];
+}
+
+
++ (NSArray *)allAccounts:(NSError **)error {
+ return [self accountsForService:nil error:error];
+}
+
+
++ (NSArray *)accountsForService:(NSString *)service {
+ return [self accountsForService:service error:nil];
+}
+
+
++ (NSArray *)accountsForService:(NSString *)service error:(NSError **)error {
+ OSStatus status = SSKeychainErrorBadArguments;
+ NSMutableDictionary *query = [self _queryForService:service account:nil];
+#if __has_feature(objc_arc)
+ [query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];
+ [query setObject:(__bridge id)kSecMatchLimitAll forKey:(__bridge id)kSecMatchLimit];
+#else
+ [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
+ [query setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit];
+#endif
+
+ CFTypeRef result = NULL;
+#if __has_feature(objc_arc)
+ status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
+#else
+ status = SecItemCopyMatching((CFDictionaryRef)query, &result);
+#endif
+ if (status != noErr && error != NULL) {
+ *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
+ return nil;
+ }
+
+#if __has_feature(objc_arc)
+ return (__bridge_transfer NSArray *)result;
+#else
+ return [(NSArray *)result autorelease];
+#endif
+}
+
+
+#pragma mark - Getting Passwords
+
++ (NSString *)passwordForService:(NSString *)service account:(NSString *)account {
+ return [self passwordForService:service account:account error:nil];
+}
+
+
++ (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
+ NSData *data = [self passwordDataForService:service account:account error:error];
+ if (data.length > 0) {
+ NSString *string = [[NSString alloc] initWithData:(NSData *)data encoding:NSUTF8StringEncoding];
+#if !__has_feature(objc_arc)
+ [string autorelease];
+#endif
+ return string;
+ }
+
+ return nil;
+}
+
+
++ (NSData *)passwordDataForService:(NSString *)service account:(NSString *)account {
+ return [self passwordDataForService:service account:account error:nil];
+}
+
+
++ (NSData *)passwordDataForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
+ OSStatus status = SSKeychainErrorBadArguments;
+ if (!service || !account) {
+ if (error) {
+ *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
+ }
+ return nil;
+ }
+
+ CFTypeRef result = NULL;
+ NSMutableDictionary *query = [self _queryForService:service account:account];
+#if __has_feature(objc_arc)
+ [query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
+ [query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
+ status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result);
+#else
+ [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
+ [query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
+ status = SecItemCopyMatching((CFDictionaryRef)query, &result);
+#endif
+
+ if (status != noErr && error != NULL) {
+ *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
+ return nil;
+ }
+
+#if __has_feature(objc_arc)
+ return (__bridge_transfer NSData *)result;
+#else
+ return [(NSData *)result autorelease];
+#endif
+}
+
+
+#pragma mark - Deleting Passwords
+
++ (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account {
+ return [self deletePasswordForService:service account:account error:nil];
+}
+
+
++ (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
+ OSStatus status = SSKeychainErrorBadArguments;
+ if (service && account) {
+ NSMutableDictionary *query = [self _queryForService:service account:account];
+#if __has_feature(objc_arc)
+ status = SecItemDelete((__bridge CFDictionaryRef)query);
+#else
+ status = SecItemDelete((CFDictionaryRef)query);
+#endif
+ }
+ if (status != noErr && error != NULL) {
+ *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
+ }
+ return (status == noErr);
+
+}
+
+
+#pragma mark - Setting Passwords
+
++ (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account {
+ return [self setPassword:password forService:service account:account error:nil];
+}
+
+
++ (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error {
+ NSData *data = [password dataUsingEncoding:NSUTF8StringEncoding];
+ return [self setPasswordData:data forService:service account:account error:error];
+}
+
+
++ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)service account:(NSString *)account {
+ return [self setPasswordData:password forService:service account:account error:nil];
+}
+
+
++ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error {
+ OSStatus status = SSKeychainErrorBadArguments;
+ if (password && service && account) {
+ [self deletePasswordForService:service account:account];
+ NSMutableDictionary *query = [self _queryForService:service account:account];
+#if __has_feature(objc_arc)
+ [query setObject:password forKey:(__bridge id)kSecValueData];
+#else
+ [query setObject:password forKey:(id)kSecValueData];
+#endif
+
+#if __IPHONE_4_0 && TARGET_OS_IPHONE
+ if (SSKeychainAccessibilityType) {
+#if __has_feature(objc_arc)
+ [query setObject:(id)[self accessibilityType] forKey:(__bridge id)kSecAttrAccessible];
+#else
+ [query setObject:(id)[self accessibilityType] forKey:(id)kSecAttrAccessible];
+#endif
+ }
+#endif
+
+#if __has_feature(objc_arc)
+ status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);
+#else
+ status = SecItemAdd((CFDictionaryRef)query, NULL);
+#endif
+ }
+ if (status != noErr && error != NULL) {
+ *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
+ }
+ return (status == noErr);
+}
+
+
+#pragma mark - Configuration
+
+#if __IPHONE_4_0 && TARGET_OS_IPHONE
++ (CFTypeRef)accessibilityType {
+ return SSKeychainAccessibilityType;
+}
+
+
++ (void)setAccessibilityType:(CFTypeRef)accessibilityType {
+ CFRetain(accessibilityType);
+ if (SSKeychainAccessibilityType) {
+ CFRelease(SSKeychainAccessibilityType);
+ }
+ SSKeychainAccessibilityType = accessibilityType;
+}
+#endif
+
+
+#pragma mark - Private
+
++ (NSMutableDictionary *)_queryForService:(NSString *)service account:(NSString *)account {
+ NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:3];
+#if __has_feature(objc_arc)
+ [dictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
+#else
+ [dictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
+#endif
+
+ if (service) {
+#if __has_feature(objc_arc)
+ [dictionary setObject:service forKey:(__bridge id)kSecAttrService];
+#else
+ [dictionary setObject:service forKey:(id)kSecAttrService];
+#endif
+ }
+
+ if (account) {
+#if __has_feature(objc_arc)
+ [dictionary setObject:account forKey:(__bridge id)kSecAttrAccount];
+#else
+ [dictionary setObject:account forKey:(id)kSecAttrAccount];
+#endif
+ }
+
+ return dictionary;
+}
+
+@end
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ios/UGAPI/UGActivity.h
----------------------------------------------------------------------
diff --git a/sdks/other/ios/UGAPI/UGActivity.h b/sdks/other/ios/UGAPI/UGActivity.h
new file mode 100755
index 0000000..1139518
--- /dev/null
+++ b/sdks/other/ios/UGAPI/UGActivity.h
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import <Foundation/Foundation.h>
+
+@interface UGActivity : NSObject
+
+// In order for an activity to be valid, you must call setBasics and one of the setActor functions.
+// In all cases, the return value will be YES if the function succeeded and NO if there
+// was a problem with the set. A response of NO will usually mean you sent nil for a required field.
+
+// these are the basics of the activity.
+// verb: the action being taken
+// category: The type of activity it is
+// content: The content of this activity. The format is defined by the category
+// title: The title of this category.
+-(BOOL) setBasics: (NSString *)verb category:(NSString *)category content:(NSString *)content title:(NSString *)title;
+
+// actorUserName: The username of the entity doing this activity
+// actorDisplayName: The visible name of the entity doing this activity
+// actorUUID: The UUID of the entity doing this activity
+-(BOOL) setActorInfo: (NSString *)actorUserName actorDisplayName:(NSString *)actorDisplayName actorUUID:(NSString *)actorUUID;
+
+// actorUserName: The username of the entity doing this activity
+// actorDisplayName: The visible name of the entity doing this activity
+// actorUUID: The UUID of the entity doing this activity
+-(BOOL) setActorInfo: (NSString *)actorUserName actorDisplayName:(NSString *)actorDisplayName actorEmail:(NSString *)actorEmail;
+
+// Associating an object with the Activity is optional. You don't have to supply an object at all.
+
+// objectType: the type of the object associated with this activity
+// displayName: The visible name of the object associated with this activity
+// entityType: the entity type of this object within UserGrid. The actual type that it is stored under
+// entityUUID: The uuid of the object associated with this activity
+-(BOOL)setObjectInfo: (NSString *)objectType displayName:(NSString *)displayName entityType:(NSString *)entityType entityUUID:(NSString *)entityUUID;
+
+// similar to the function above, but it takes an arbitrary object content (which can be new and unique) instead of an already-defined object
+-(BOOL)setObjectInfo: (NSString *)objectType displayName:(NSString *)displayName objectContent:(NSString *)objectContent;
+
+// similar to the other two functions, but simply has the type and displayName. In this case, the
+// "content" value supplied in setBasics will be used as the object content.
+-(BOOL)setObjectInfo: (NSString *)objectType displayName:(NSString *)displayName;
+
+// returns YES if this is properly set up. NO if it has not been properly set up
+-(BOOL)isValid;
+
+// turn this object in to an NSDictionary. Used internally by UGClient
+-(NSDictionary *)toNSDictionary;
+
+@end
http://git-wip-us.apache.org/repos/asf/usergrid/blob/867060fa/sdks/other/ios/UGAPI/UGActivity.m
----------------------------------------------------------------------
diff --git a/sdks/other/ios/UGAPI/UGActivity.m b/sdks/other/ios/UGAPI/UGActivity.m
new file mode 100755
index 0000000..3eaea00
--- /dev/null
+++ b/sdks/other/ios/UGAPI/UGActivity.m
@@ -0,0 +1,263 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "UGActivity.h"
+
+// the way they have set up the object info
+enum
+{
+ kUGActivityNoObject = 0,
+ kUGActivityObjectEntity = 1,
+ kUGActivityObjectContent = 2,
+ kUGActivityObjectNameOnly = 3
+};
+
+@implementation UGActivity
+{
+ // basic stats
+ NSString *m_verb;
+ NSString *m_category;
+ NSString *m_content;
+ NSString *m_title;
+
+ // stats related to the actor
+ NSString *m_actorUserName;
+ NSString *m_actorDisplayName;
+ NSString *m_actorUUID;
+ NSString *m_actorEmail;
+
+ // stats related to the object
+ NSString *m_objectType;
+ NSString *m_objectDisplayName;
+
+ // for the object, either these must be set...
+ NSString *m_entityType;
+ NSString *m_entityUUID;
+
+ // ...or this must be set
+ NSString *m_objectContent;
+
+ // or it will use the content field as the content for the object
+
+ // tracking how the object is currently set up
+ int m_objectDataType;
+}
+
+-(id)init
+{
+ self = [super init];
+ if ( self )
+ {
+ m_objectDataType = kUGActivityNoObject;
+ }
+ return self;
+}
+
+-(BOOL) setBasics: (NSString *)verb category:(NSString *)category content:(NSString *)content title:(NSString *)title
+{
+ // input validation
+ if ( !verb || !category || !content || !title ) return NO;
+
+ m_verb = verb;
+ m_category = category;
+ m_content = content;
+ m_title = title;
+
+ return YES;
+}
+
+-(BOOL) setActorInfo: (NSString *)actorUserName actorDisplayName:(NSString *)actorDisplayName actorUUID:(NSString *)actorUUID
+{
+ // input validation
+ if ( !actorUserName || !actorDisplayName || !actorUUID ) return NO;
+
+ m_actorUserName = actorUserName;
+ m_actorDisplayName = actorDisplayName;
+ m_actorUUID = actorUUID;
+ m_actorEmail = nil;
+
+ return YES;
+}
+
+-(BOOL) setActorInfo: (NSString *)actorUserName actorDisplayName:(NSString *)actorDisplayName actorEmail:(NSString *)actorEmail
+{
+ // input validation
+ if ( !actorUserName || !actorDisplayName || !actorEmail ) return NO;
+
+ m_actorUserName = actorUserName;
+ m_actorDisplayName = actorDisplayName;
+ m_actorEmail = actorEmail;
+ m_actorUUID = nil;
+
+ return YES;
+}
+
+-(BOOL)setObjectInfo: (NSString *)objectType displayName:(NSString *)displayName entityType:(NSString *)entityType entityUUID:(NSString *)entityUUID
+{
+ // input validation
+ if ( !objectType || !displayName || !entityType || !entityUUID ) return NO;
+
+ m_objectType = objectType;
+ m_objectDisplayName = displayName;
+ m_entityType = entityType;
+ m_entityUUID = entityUUID;
+ m_objectDataType = kUGActivityObjectEntity;
+
+ // clear out the unused value
+ m_objectContent = nil;
+
+ return YES;
+}
+
+-(BOOL)setObjectInfo: (NSString *)objectType displayName:(NSString *)displayName objectContent:(NSString *)objectContent
+{
+ // input validation
+ if ( !objectType || !displayName || !objectContent ) return NO;
+
+ m_objectType = objectType;
+ m_objectDisplayName = displayName;
+ m_objectContent = objectContent;
+ m_objectDataType = kUGActivityObjectContent;
+
+ // clear out the unused values
+ m_entityType = nil;
+ m_entityUUID = nil;
+
+ return YES;
+}
+
+-(BOOL)setObjectInfo: (NSString *)objectType displayName:(NSString *)displayName
+{
+ // input validation
+ if ( !objectType || !displayName ) return NO;
+
+ m_objectType = objectType;
+ m_objectDisplayName = displayName;
+ m_objectDataType = kUGActivityObjectNameOnly;
+
+ // we'll use m_content when the time comes. But we don't want to
+ // assume they've set it yet. They can call the setup functions in any order.
+ m_objectContent = nil;
+ m_entityType = nil;
+ m_entityUUID = nil;
+
+ return YES;
+}
+
+-(BOOL)isValid
+{
+ // if any of the required values are nil, it's not valid
+ if ( !m_verb || !m_category || !m_content || !m_title || !m_actorUserName || !m_actorDisplayName )
+ {
+ return NO;
+ }
+
+ // either the uuid or the email of the user must be valid
+ if ( !m_actorUUID && !m_actorEmail )
+ {
+ return NO;
+ }
+
+ // the object data requirements are based on the object setup
+ switch ( m_objectDataType )
+ {
+ case kUGActivityObjectEntity:
+ {
+ if ( !m_objectType || !m_objectDisplayName || !m_entityType || !m_entityUUID ) return NO;
+ }
+ break;
+
+ case kUGActivityObjectContent:
+ {
+ if ( !m_objectType || !m_objectDisplayName || !m_objectContent ) return NO;
+ }
+ break;
+
+ case kUGActivityObjectNameOnly:
+ {
+ if ( !m_objectType || !m_objectDisplayName ) return NO;
+ }
+ break;
+
+ // kUGActivityNoObject has no requirements.
+ }
+
+ // if we're here, we're valid.
+ return YES;
+}
+
+-(NSDictionary *)toNSDictionary
+{
+ NSMutableDictionary *ret = [NSMutableDictionary new];
+
+ // add all the fields in
+ [ret setObject:@"activity" forKey:@"type"];
+ [ret setObject:m_verb forKey:@"verb"];
+ [ret setObject:m_category forKey:@"category"];
+ [ret setObject:m_content forKey:@"content"];
+ [ret setObject:m_title forKey:@"title"];
+
+ // make the actor's subdictionary
+ NSMutableDictionary *actor = [NSMutableDictionary new];
+ [actor setObject:@"person" forKey:@"type"];
+ [actor setObject:@"user" forKey:@"entityType"];
+ [actor setObject:m_actorDisplayName forKey:@"displayName"];
+
+ if ( m_actorUUID )
+ {
+ [actor setObject:m_actorUUID forKey:@"uuid"];
+ }
+ if ( m_actorEmail )
+ {
+ [actor setObject:m_actorEmail forKey:@"email"];
+ }
+
+ // add the actor to the main dict
+ [ret setObject:actor forKey:@"actor"];
+
+ if ( m_objectDataType != kUGActivityNoObject )
+ {
+ // there is an associated object. Prep a dict for it
+ NSMutableDictionary *object = [NSMutableDictionary new];
+
+ // these fields are involved in all cases
+ [object setObject:m_objectType forKey:@"type"];
+ [object setObject:m_objectDisplayName forKey:@"displayName"];
+
+ if ( m_objectDataType == kUGActivityObjectContent )
+ {
+ [object setObject:m_objectContent forKey:@"content"];
+ }
+ else if ( m_objectDataType == kUGActivityObjectNameOnly )
+ {
+ [object setObject:m_content forKey:@"content"];
+ }
+ else if ( m_objectDataType == kUGActivityObjectEntity )
+ {
+ [object setObject:m_entityType forKey:@"entityType"];
+ [object setObject:m_entityUUID forKey:@"entityUUID"];
+ }
+
+ // add to the dict
+ [ret setObject:object forKey:@"object"];
+ }
+
+ // done with the assembly
+ return ret;
+}
+
+@end