-
Notifications
You must be signed in to change notification settings - Fork 58
Examples
Current example shows how quick and easy validate JSON.
What's New?
- JSON - JavaScript Object Notation
- JSON_DEPTH - maximal depth of JSON nested expressions
- jsonlite_parser_estimate_size - estimates memory usage (in bytes). This value depends on CPU architecture.
- jsonlite_parser_init - initialize parser
- jsonlite_parser_tokenize - process JSON payload
- jsonlite_parser_release - free all resources
#include <assert.h>
#include "jsonlite.h"
int main(int argc, const char * argv[]) {
const int JSON_DEPTH = 4; // Limitation of JSON depth
char json[] = "[-1, 0, 1, true, false, null]"; // JSON to validate
size_t mem_used = jsonlite_parser_estimate_size(JSON_DEPTH); // Estimate memory usage
printf("jsonlite will use %zd bytes of RAM for JSON validation", mem_used);
jsonlite_parser p = jsonlite_parser_init(JSON_DEPTH); // Init parser with specified depth
jsonlite_result result = jsonlite_parser_tokenize(p, json, sizeof(json)); // Check JSON
assert(result == jsonlite_result_ok); // Check result
jsonlite_parser_release(p); // Free resources
return 0;
}
Next example shows how to work with number tokens. jsonlite does not convert any number by itself. That's why you may use strtol or even arbitrary-precision arithmetic.
What's New?
- jsonlite_parser_callbacks - contains addresses of callback functions
- jsonlite_default_callbacks - contains default callback functions (they do nothing).
- jsonlite_parser_set_callback - sets new callback functions
- number_callback - callback function. It converts number token to C type and performs summing.
#include <stdlib.h>
#include <assert.h>
#include "jsonlite.h"
#include "jsonlite_token.h"
long long sum = 0;
static void number_callback(jsonlite_callback_context *ctx, jsonlite_token *token) {
char *end = NULL;
sum += strtoll((const char *)token->start, &end, 10);
assert(end == (char *)token->end);
}
int main(int argc, const char * argv[]) {
const int JSON_DEPTH = 4; // Limitation of JSON depth
char json[] = "[-13453453, 0, 1, 123, 45345, -94534555]"; // Numbers to sum
jsonlite_parser_callbacks cbs = jsonlite_default_callbacks; // Init callbacks with default values
cbs.number_found = &number_callback; // Assign new callback function
jsonlite_parser p = jsonlite_parser_init(JSON_DEPTH); // Init parser with specified depth
jsonlite_parser_set_callback(p, &cbs); // Set callback function(s)
jsonlite_parser_tokenize(p, json, sizeof(json)); // Tokenize/find numbers
jsonlite_parser_release(p); // Free resources
printf("Total sum: %lld", sum);
return 0;
}
The example shows how to quick make JSON pretty. The example is bigger than previous, please, see it here.
Current example shows how to quick tokenize and accumulate results to Cocoa collection.
What's New?
- dataUsingEncoding - buildin Cocoa method. It converts NSString to NSData object.
- JsonLiteAccumulator - convert JSON tokens to Cocoa classes and accumulate results to NSArray or NSDictionary.
- objectFromData - class method of JsonLiteAccumulator, it is helper method - encapsulation of full initialization (see next example).
#import <Foundation/Foundation.h>
#import "JsonLiteAccumulator.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *json = @"[\"hello\", null, 1234567890]";
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
NSArray *result = [JsonLiteAccumulator objectFromData:data withMaxDepth:4];
NSLog(@"%@", result);
}
return 0;
}
A chunk is a fragment of JSON. JsonLite ObjC allows you to process a chunk while other parts of JSON are delivering by network. 'Chunk Oriented' processing style allow developer to improve memory usage and increase program performance, also its' provide ability to work with huge JSON data.
Also this example shows full parsing flow: create parser -> assign delegate -> parse data.
What's New?
- JsonLiteParser - sequential access JSON parser.
- JsonLiteAccumulator - implements JsonLiteParserDelegate protocol. Performs token conversion and accumulates results to Cocoa collections.
#import <Foundation/Foundation.h>
#import "JsonLiteParser.h"
#import "JsonLiteAccumulator.h"
char chuck1[] = "[\"hello\", nu";
char chuck2[] = "ll, 1234567890]";
int main(int argc, const char * argv[]) {
@autoreleasepool {
JsonLiteParser *parser = [JsonLiteParser parserWithDepth:4];
JsonLiteAccumulator *acc = [JsonLiteAccumulator accumulatorWithDepth:4];
parser.delegate = acc;
NSData *data = [[NSData alloc] initWithBytes:chuck1
length:sizeof(chuck1) - 1];
[parser parse:data];
[data release];
data = [[NSData alloc] initWithBytes:chuck2
length:sizeof(chuck2) - 1];
[parser parse:data];
[data release];
NSLog(@"Full object - %@", [acc object]);
}
return 0;
}
It's really hard to deal with Cocoa collections. The best way is to bind JSON to some model.
What's New?
- Model - declaration of application object.
- JsonLiteDeserializer - implements JsonLiteParserDelegate protocol. Performs token conversion and binds results to specified model.
- JsonLiteSerializer - serialize Objective-C model or collection to JSON.
#import <Foundation/Foundation.h>
#import "JsonLiteParser.h"
#import "JsonLiteDeserializer.h"
#import "JsonLiteSerializer.h"
@interface Model : NSObject
@property (nonatomic, copy) NSString *string;
@property (nonatomic, copy) NSNumber *number;
@property (nonatomic, copy) NSArray *array;
@end
@implementation Model
- (void)dealloc {
self.string = nil;
self.number = nil;
self.array = nil;
[super dealloc];
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *json = @"{\"string\": \"hello\", \"number\" : 100, \"array\": [1, 2, 3]}";
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
JsonLiteParser *parser = [JsonLiteParser parserWithDepth:8];
JsonLiteDeserializer *des = [JsonLiteDeserializer deserializerWithRootClass:[Model class]];
parser.delegate = des;
[parser parse:data];
Model *model = [des object];
NSLog(@"String - %@", model.string);
NSLog(@"Number - %@", model.number);
NSLog(@"Array - %@", model.array);
model.string = @"Hello World";
model.number = [NSNumber numberWithInt:256];
model.array = [NSArray arrayWithObjects:@"Test", [NSNull null], nil];
JsonLiteSerializer *serializer = [JsonLiteSerializer serializer];
data = [serializer serializeObject:model];
json = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
NSLog(@"%@", json);
}
return 0;
}
Only JsonLite ObjC can work with NSDecimalNumber object and you can forget about workaround with strings. It's very important feature for finance project.
What's New?
- NSDecimalNumber - class for base-10 arithmetic.
- JsonLiteDecimal - converter used by JsonLiteDeserializer to convert number token to NSDecimalNumber.
#import <Foundation/Foundation.h>
#import <Foundation/Foundation.h>
#import "JsonLiteParser.h"
#import "JsonLiteDeserializer.h"
#import "JsonLiteConverters.h"
@interface Model : NSObject
@property (nonatomic, copy) NSString *string;
@property (nonatomic, copy) NSDecimalNumber *number;
@end
@implementation Model
- (void)dealloc {
self.string = nil;
self.number = nil;
[super dealloc];
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *json = @"{\"string\": \"This is Decimal!\", \"number\" : 95673465936453649563978.99 }";
NSData *data = [json dataUsingEncoding:NSUTF8StringEncoding];
JsonLiteParser *parser = [JsonLiteParser parserWithDepth:8];
JsonLiteDeserializer *des = [JsonLiteDeserializer deserializerWithRootClass:[Model class]];
des.converter = [[[JsonLiteDecimal alloc] init] autorelease];
parser.delegate = des;
[parser parse:data];
Model *model = [des object];
NSLog(@"String - %@", model.string);
NSLog(@"Number - %@", model.number);
}
return 0;
}
JsonLite ObjC can convert base64 directly from JSON payload without additional data structure. Let's calculate memory footprint for 1000 byte binary information.
Most popular JSON parsers use following steps to process base64:
- Encode 1000 bytes to base64 (+1333 bytes)
- Extract NSString from JSON (+2666 bytes, NSString uses UTF16 string encoding)
- Decode string to NSData (+1000 bytes) 1333 + 2666 + 1000 = 4999 bytes
JsonLite:
- Encode 1000 bytes to base64 (+1333 bytes)
- Decode base64 directly from JSON (+1000 bytes) 1333 + 1000 = 2333 bytes
What's New?
- JsonLiteBase64 - converter used by JsonLiteDeserializer to convert base64 to NSData.
#import <Foundation/Foundation.h>
#import "JsonLiteObjC/JsonLiteObjC.h"
static uint8_t BinaryData[] = {
0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x0a,0x08,0x06,0x00,0x00,0x00,0x8d,0x32,0xcf,
0xbd,0x00,0x00,0x00,0x06,0x62,0x4b,0x47,0x44,0x00,0xff,0x00,0xff,0x00,0xff,0xa0,
0xbd,0xa7,0x93,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd6,0x08,0x03,0x0b,
0x03,0x00,0x0d,0x0e,0x0d,0x9f,0x00,0x00,0x00,0x55,0x49,0x44,0x41,0x54,0x18,0x95,
0x8d,0x90,0xc1,0x09,0x00,0x31,0x08,0x04,0x47,0x1b,0x48,0x39,0x17,0x52,0x77,0xd2,
0x82,0x70,0x55,0x79,0x9f,0x0b,0x48,0x08,0xe2,0xc2,0x3c,0x84,0x41,0x74,0x85,0x10,
0x87,0x07,0x18,0xff,0x68,0x02,0x2f,0x87,0xd0,0x1c,0xa6,0x83,0x1f,0x4c,0x87,0x16,
0xc5,0x75,0x91,0x36,0x6b,0x4b,0x3d,0x91,0x36,0x5d,0xc3,0x4d,0x59,0x86,0x16,0x24,
0x00,0x14,0xb0,0x82,0x67,0xf5,0x67,0xaa,0xf5,0x48,0xdc,0x9f,0x15,0xfe,0x01,0x67,
0xe6,0x54,0x13,0x17,0x0d,0x51,0x05,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,
0x42,0x60,0x82
};
@interface Base64Model : NSObject
@property (copy, nonatomic) NSString *message;
@property (copy, nonatomic) NSData *base64;
@end
@implementation Base64Model
- (void)dealloc {
self.message = nil;
self.base64 = nil;
}
@end
NSData *createJsonData() {
Base64Model *model = [[Base64Model alloc] init];
model.message = @"Base64 Example";
model.base64 = [NSData dataWithBytes:BinaryData length:sizeof(BinaryData)];
JsonLiteSerializer *serializer = [JsonLiteSerializer serializer];
serializer.converter = [[JsonLiteBase64 alloc] init];
serializer.indentation = 4;
return [serializer serializeObject:model];
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSData *json = createJsonData();
NSLog(@"%@\n", [[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding]);
JsonLiteParser *parser = [JsonLiteParser parser];
JsonLiteDeserializer *deserializer = [JsonLiteDeserializer deserializerWithRootClass:[Base64Model class]];
deserializer.converter = [[JsonLiteBase64 alloc] init];
parser.delegate = deserializer;
[parser parse:json];
Base64Model *model = [deserializer object];
NSLog(@"Message - %@\n", model.message);
NSLog(@"Data - %@\n", model.base64);
}
return 0;
}