GithubHelp home page GithubHelp logo

sbjson / sbjson Goto Github PK

View Code? Open in Web Editor NEW
3.7K 155.0 688.0 4.65 MB

This framework implements a strict JSON parser and generator in Objective-C.

License: BSD 3-Clause "New" or "Revised" License

Objective-C 98.50% Shell 0.22% Ruby 1.28%
sbjson parsing objective-c chunk json carthage

sbjson's Introduction

SBJson 5

Chunk-based JSON parsing and generation in Objective-C.

CircleCI Project Status: Inactive - The project has reached a stable, usable state but is no longer being actively developed; support/maintenance will be provided as time allows. Carthage compatible

Overview

SBJson's number one feature is stream/chunk-based operation. Feed the parser one or more chunks of UTF8-encoded data and it will call a block you provide with each root-level document or array. Or, optionally, for each top-level entry in each root-level array.

With this you can reduce the apparent latency for each download/parse cycle of documents over a slow connection. You can start parsing and return chunks of the parsed document before the full document has downloaded. You can also parse massive documents bit by bit so you don't have to keep them all in memory.

SBJson maps JSON types to Objective-C types in the following way:

JSON Type Objective-C Type
null NSNull
string NSString
array NSMutableArray
object NSMutableDictionary
true -[NSNumber numberWithBool: YES]
false -[NSNumber numberWithBool: NO]
number NSNumber
  • Booleans roundtrip properly even though Objective-C doesn't have a dedicated class for boolean values.
  • Integers use either long long or unsigned long long if they fit, to avoid rounding errors. For all other numbers we use the double type, with all the potential rounding errors that entails.

"Plain" Chunk Based Parsing

First define a simple block & an error handler. (These are just minimal examples. You should strive to do something better that makes sense in your application!)

SBJson5ValueBlock block = ^(id v, BOOL *stop) {
    BOOL isArray = [v isKindOfClass:[NSArray class]];
    NSLog(@"Found: %@", isArray ? @"Array" : @"Object");
};

SBJson5ErrorBlock eh = ^(NSError* err) {
    NSLog(@"OOPS: %@", err);
    exit(1);
};

Then create a parser and add data to it:

id parser = [SBJson5Parser parserWithBlock:block
                              errorHandler:eh];

id data = [@"[true," dataWithEncoding:NSUTF8StringEncoding];
[parser parse:data]; // returns SBJson5ParserWaitingForData

// block is not called yet...

// ok, now we add another value and close the array

data = [@"false]" dataWithEncoding:NSUTF8StringEncoding];
[parser parse:data]; // returns SBJson5ParserComplete

// the above -parse: method calls your block before returning.

Alright! Now let's look at something slightly more interesting.

Handling multiple documents

This is useful for something like Twitter's feed, which gives you one JSON document per line. Here is an example of parsing many consequtive JSON documents, where your block will be called once for each document:

id parser = [SBJson5Parser multiRootParserWithBlock:block
                                       errorHandler:eh];

// Note that this input contains multiple top-level JSON documents
id data = [@"[]{}" dataWithEncoding:NSUTF8StringEncoding];
[parser parse:data];
[parser parse:data];

The above example will print:

Found: Array
Found: Object
Found: Array
Found: Object

Unwrapping a gigantic top-level array

Often you won't have control over the input you're parsing, so can't use a multiRootParser. But, all is not lost: if you are parsing a long array you can get the same effect by using an unwrapRootArrayParser:

id parser = [SBJson5Parser unwrapRootArrayParserWithBlock:block
                                             errorHandler:eh];

// Note that this input contains A SINGLE top-level document
id data = [@"[[],{},[],{}]" dataWithEncoding:NSUTF8StringEncoding];
[parser parse:data];

Other features

  • For safety there is a max nesting level for all input. This defaults to 32, but is configurable.
  • The writer can sort dictionary keys so output is consistent across writes.
  • The writer can create human-readable output, with newlines and indents.
  • You can install SBJson v3, v4 and v5 side-by-side in the same application. (This is possible because all classes & public symbols contains the major version number.)

A word of warning

Stream based parsing does mean that you lose some of the correctness verification you would have with a parser that considered the entire input before returning an answer. It is technically possible to have some parts of a document returned as if they were correct but then encounter an error in a later part of the document. You should keep this in mind when considering whether it would suit your application.

American Fuzzy Lop

I've run AFL on the sbjson binary for over 24 hours, with no crashes found. (I cannot reproduce the hangs reported when attempting to parse them manually.)

                       american fuzzy lop 2.35b (sbjson)

┌─ process timing ─────────────────────────────────────┬─ overall results ─────┐
│        run time : 1 days, 0 hrs, 45 min, 26 sec      │  cycles done : 2      │
│   last new path : 0 days, 0 hrs, 5 min, 24 sec       │  total paths : 555    │
│ last uniq crash : none seen yet                      │ uniq crashes : 0      │
│  last uniq hang : 0 days, 2 hrs, 11 min, 43 sec      │   uniq hangs : 19     │
├─ cycle progress ────────────────────┬─ map coverage ─┴───────────────────────┤
│  now processing : 250* (45.05%)     │    map density : 0.70% / 1.77%         │
│ paths timed out : 0 (0.00%)         │ count coverage : 3.40 bits/tuple       │
├─ stage progress ────────────────────┼─ findings in depth ────────────────────┤
│  now trying : auto extras (over)    │ favored paths : 99 (17.84%)            │
│ stage execs : 603/35.6k (1.70%)     │  new edges on : 116 (20.90%)           │
│ total execs : 20.4M                 │ total crashes : 0 (0 unique)           │
│  exec speed : 481.9/sec             │   total hangs : 44 (19 unique)         │
├─ fuzzing strategy yields ───────────┴───────────────┬─ path geometry ────────┤
│   bit flips : 320/900k, 58/900k, 5/899k             │    levels : 8          │
│  byte flips : 0/112k, 4/112k, 3/112k                │   pending : 385        │
│ arithmetics : 66/6.24M, 0/412k, 0/35                │  pend fav : 1          │
│  known ints : 5/544k, 0/3.08M, 0/4.93M              │ own finds : 554        │
│  dictionary : 0/0, 0/0, 29/1.83M                    │  imported : n/a        │
│       havoc : 64/300k, 0/0                          │ stability : 100.00%    │
│        trim : 45.19%/56.5k, 0.00%                   ├────────────────────────┘
^C────────────────────────────────────────────────────┘             [cpu: 74%]

+++ Testing aborted by user +++
[+] We're done here. Have a nice day!

API Documentation

Please see the API Documentation for more details.

Installation

CocoaPods

The preferred way to use SBJson is by using CocoaPods. In your Podfile use:

pod 'SBJson', '~> 5.0.0'

Carthage

SBJson is compatible with Carthage. Follow the Getting Started Guide for iOS.

github "SBJson/SBJson" == 5.0.2

Bundle the source files

An alternative that I no longer recommend is to copy all the source files (the contents of the Classes folder) into your own Xcode project.

Examples

Support

  • Review (or create) StackOverflow questions tagged with SBJson if you have questions about how to use the library.
  • Use the issue tracker if you have found a bug.
  • I regret I'm only able to support the current major release.

Philosophy on backwards compatibility

SBJson practice Semantic Versioning, which means we do not break the API in major releases. If something requires a backwards-incompatible change, we release a new major version. (Hence why a library of less than 1k lines has more major versions than Emacs.)

I also try support a gradual migration from one major version to the other by allowing the last three major versions to co-exist in the same app without conflicts. The way to do this is putting the major version number in all the library's symbols and file names. So if v6 ever comes out, the SBJson5Parser class would become SBJson6Parser, etc.

License

BSD. See LICENSE for details.

sbjson's People

Contributors

adonoho avatar amrutsaba avatar andrewpbrett avatar brycebostwick avatar cary avatar dagerydoo avatar hagerhu avatar hiroshi avatar hotbott avatar itruf avatar johnezang avatar kimmomyllyoja avatar lukef avatar mikeabdullah avatar mikekppp avatar mmmbiscuits avatar nark avatar noscript avatar phillbaker avatar pilif avatar robb avatar robin avatar soffes avatar sps avatar stig avatar stigi avatar tlg avatar tyrone-sudeium avatar upsuper avatar waffle-with-pears avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sbjson's Issues

Stream-based API: Parser

Big JSON structures take some time to download. I want to implement an NSStream-based parser that will allow one to start parsing the JSON before all of it is downloaded.

Review, suggestions, and patches welcome!

Need to add more escape characters while parsing string

Following cases need to be added:

str = [str stringByReplacingOccurrencesOfString:@"\\x3c" withString:@"<"];
str = [str stringByReplacingOccurrencesOfString:@"\\x3e" withString:@">"];
str = [str stringByReplacingOccurrencesOfString:@"\\x26" withString:@"&"];
str = [str stringByReplacingOccurrencesOfString:@"\\x22" withString:@"\""];
str = [str stringByReplacingOccurrencesOfString:@"\\x27" withString:@"'"];
str = [str stringByReplacingOccurrencesOfString:@"\\'" withString:@"'"];
str = [str stringByReplacingOccurrencesOfString:@"\\v" withString:@""];

Package as static framework for iOS

I've got a patch I'd be happy to submit that will build a static framework version of the project for iOS. Let me know if you're interested.

-Bob

Crash in [SBJsonParser scanNumber:] ?

When parsing a JSON string multiple times I sometimes receive an EXC_BAD_ACCESS error in the method [SBJsonParser scanNumber:] at the following line:

*o = [NSNumber numberWithLongLong:negate ? -val : val];

Other times, when parsing the exact same string, everything runs perfectly fine.

The stack trace:
#0 0x014bdc6f in prepareForMethodLookup
#1 0x014b76ad in lookUpMethod
#2 0x014b781a in _class_lookupMethodAndLoadCache
#3 0x014c5aa3 in objc_msgSend
#4 0x012909d1 in CFNumberCreate
#5 0x000d90df in -[NSPlaceholderNumber initWithLongLong:]
#6 0x000d9058 in +[NSNumber numberWithLongLong:]
#7 0x0000e9b8 in -[SBJsonParser scanNumber:] at SBJsonParser.m:489
#8 0x0000d0c6 in -[SBJsonParser scanValue:] at SBJsonParser.m:143
#9 0x0000d9f3 in -[SBJsonParser scanRestOfDictionary:] at SBJsonParser.m:263
#10 0x0000cfcb in -[SBJsonParser scanValue:] at SBJsonParser.m:123
#11 0x0000d5bf in -[SBJsonParser scanRestOfArray:] at SBJsonParser.m:212
#12 0x0000cff1 in -[SBJsonParser scanValue:] at SBJsonParser.m:126
#13 0x0000cc70 in -[SBJsonParser objectWithString:] at SBJsonParser.m:82
#14 0x0000c75f in -[NSString(NSString_SBJSON) JSONValue] at NSString+SBJSON.m:38

Thousands of memory leaks when using sbjson framework on repeated usage

Hi stig,

I am using JSON framework (SBJson) for my applicaition.

parsing the value by

NSDictionary *results = [responseString JSONValue] ;
For parsing first time in controller with this code has no problem. when i call again for same controller it shows thousands of memory leaks.

I went through many forums but in vain. can anybody please tell me what i went wrong?

Full Code:
NSString *response = [[NSString alloc] initWithData:webData encoding:NSUTF8StringEncoding];

//NSDictionary *results =[[response JSONValue] retain] ;

if (results) {
[results release];
results=nil;
}

results =[[response JSONValue] retain] ;
[response release];

Please see the pic for Instrument leaks:
http://i.imgur.com/2avo3.png

Thanks in advance.

Regards,
Sathish

Unable to open 'Targets'

If I try open the 'Targets' section of the Xcode project in 3.2.4 or 3.2.5, Xcode crashes with an 'Internal Error' about a Mutable object.

Is this an error with the project file, or with Xcode?

NSAssert used for required statements

I noticed two uses of NSAssert with vital method calls. These will not be called if asserts are disabled for compilation. One is in SBJsonStreamParser.m:

NSAssert([tokeniser getToken:&buf length:&len], @"failed to get token");

and the other is in SBJsonTokeniser.m:

NSAssert([self getToken:&bytes length:&len], @"Failed to get token");

Moving the result into a BOOL and using that inside the NSAssert took care of a round of EXC_BAD_ACCESS troubleshooting for me.

Great library, thanks for investing the time into it!

Addition of setMaxDepth method causing build error.

Build and Analyse with Xcode 3.2.5 on latest commit raises a build error on line 266 of SBJsonStreamParser.m of:

error: writable atomic property 'maxDepth' cannot pair a synthesized setter/getter with a user defined setter/getter

From http://osdir.com/ml/xcode-users/2010-06/msg00196.html by ‘bbum’.

"If you declare an @Property that is atomic -- the default -- you must either
use @dynamic, let the compiler @synthesize everything or provide an
implementation of both the setter and getter.

If you want to mix a manual implementation of, say, the setter with an
@synthesize, declare the @Property to be nonatomic."

I have all warnings turned on for Clang, and check with both built-in and external latest build, which is perhaps why you may not be seeing these.

Cheers, Andy

Stream-based API: Writer

Big JSON structures take some time to download/upload. I want to implement an NSStream-based API that will allow one to start parsing the JSON before all of it is downloaded. Similarly, the writer could write to disk or a socket without having to create a gigantic structure in memory first.

I've created a branch, stream-writer, with some initial work. It passes many tests (writing valid JSON) but fails for a lot of the error-condition tests. Basically, the error handling is shot in that branch. It uses exceptions, which is not really recommended in Cocoa.

Review, suggestions, and patches welcome!

decoding "\\x3c"

Thanks for the library. It really helps my work.
I'm using JSON library for Drupal interface.
Sometimes, it returns string like '\x3cem\x3e' and I found that '\x3c' is a prefix for hexadecimal number. i.e. '\x3c', So, the string stands for ''.
I'm not sure whether '\x' is a standard character in JSON.
Anyway using the following code I could parse it.

I'm using an old version, but I found that the latest version still does not include decoding routine for '\x'.

  • (BOOL)scanRestOfString:(NSMutableString **)o
    ....
    case 'x': // bhtak 2011/1/9
    c++;
    if (![self scanHexDual:&uc]) {
    [self addErrorWithCode:EUNICODE description: @"Missing hex dual"];
    return NO;
    }
    c--; // hack.
    break;
    ....
  • (BOOL)scanHexDual:(unichar *)x

{
*x = 0;
for (int i = 0; i < 2; i++) {
unichar uc = *c;
c++;
int d = (uc >= '0' && uc <= '9')
? uc - '0' : (uc >= 'a' && uc <= 'f')
? (uc - 'a' + 10) : (uc >= 'A' && uc <= 'F')
? (uc - 'A' + 10) : -1;
if (d == -1) {
[self addErrorWithCode:EUNICODE description:@"Missing hex digit in dual"];
return NO;
}
*x *= 16;
*x += d;
}
return YES;
}

@"\\/Date(tick)\\/" issue

From larry.by, on the old issue tracker:

SBJsonWriter converts the object value @"\\/Date(10101)\\/" string (10101 is a just example value) to the string with two backslashes but expected string is "\/Date(10101)\/".

How can I generate JSON object with the "/Date(10101)/" string by the SBJsonWriter?

Parsers are required to treat "/" and "/" the same, i.e. to produce the same native string of "/". Which means that the following two strings should produce the exact same native string when parsed:

"\/Date(123)\/"
"/Date(123)/"

However, according to Charles Cherry ASP.Net relies on the "/" construct in to represent dates.

I don't plan to add special-case support for dates, but an option to escape "/" in strings to allow embedding it in HTML might be in order.

SBJsonStreamWriter stringCache

hi,

I am using JSON v3.0beta1 (iOS) for iOS 4.2 and have a memory issue when serializing arrays or dictionaries with (id)JSONValue. Consider the following snippet:

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    while(TRUE)
    {
        NSString *aString = [NSString stringWithFormat:@"dummyUUID %i", rand()];
        NSArray *array = [NSArray arrayWithObjects:aString, nil];
        
        NSString *serializedArray = [array JSONRepresentation];
        
        [pool drain];
        pool = [[NSAutoreleasePool alloc] init];
    }

When running this code with Instruments and the Allocations tool there is a steep increase of live bytes that are not freed despite the autoreleasePool.

I think that the stringCache in SBJsonStreamWriter is the reason for this issue. It is created in the SBJsonStreamWriter's initialize method but never released. If I use the following macro, the steep memory increase disappears:

#define FULL_CACHE_FIXED 1

+ (void)initialize {
    notANumber = [NSDecimalNumber notANumber];
    
    #if !FULL_CACHE_FIXED
    stringCache = [NSMutableDictionary new];
    #endif
}

#pragma mark Housekeeping

- (id)init {
    self = [super init];
    if (self) {
        data = [[NSMutableData alloc] initWithCapacity:1024u];
        maxDepth = 512;
        states = calloc(maxDepth, sizeof(SBJsonStreamWriterState*));
        NSAssert(states, @"States not initialised");
        
        states[0] = [SBJsonStreamWriterStateStart sharedInstance];
        
        #if FULL_CACHE_FIXED
        stringCache = [NSMutableDictionary new];
        #endif
    }
    return self;
}

- (void)dealloc {
    self.error = nil;
    free(states);
    [data release];
    
    #if FULL_CACHE_FIXED
    [stringCache release];
    #endif
    
    [super dealloc];
}

So, allocating and releasing the stringCache for each SBJsonStreamWriter instance solves the memory issue but I did not investigate in how far performance is affected.

What was the idea behind using a static stringCache?

regards,

steven

Unnecessary script phase in build

I noticed that JSON.h has conditional compilation based on a hardcoded "1" which is replaced via a shell script build phase. Maybe I'm missing something here, but couldn't you just have it be #ifdef SOMETHING and add -DSOMETHING to the CFLAGS in the build settings for the appropriate targets? Seems less error-prone (especially since I'm seeing another issue concerning the script).

Leak in SBJsonStreamParser

Stig, thanks for fixing the NSAssert problem. This library is really getting hot! :)

Instruments is indicating a leak in SBJsonStreamParser, and the source appears to be:

states = calloc(maxDepth, sizeof(SBJsonStreamParserState*));

in the init method. There doesn't appear to be any corresponding line in dealloc.

Quote behavior seems incorrect

[Edit: Please ignore this error, it looks like I was reaching an older copy of the library through an external static lib. I had been testing the latest build to see if this issue still existed. Apologies.]

I haven't found any discussion of this issue or how to handle it so I'm raising it as a bug either so correct usage is documented or to have it resolved.

With JSON:
{ "URL":"http://www.google.com" }

If you read this in as an NSString and then convert to NSDictionary:
NSString* jsonString = [NSString stringWithContentsOfFile:@"myfile.json" encoding:NSASCIIStringEncoding error:&error];
NSDictionary* jsonDict = [jsonString JSONValue];

The resulting dictionary will have:
key: @"URL" value: @""http://www.google.com\\""

The NSString in value retains the delimiting quotes required for JSON Formatting even though they are not part of the actual value but only intended to safely wrap the string for encoding/decoding. This also happens if you use the parser directly.

Several web-sites suggest using NSString to replace the quotes, but this is not a practical solution. If done before decoding then the decoding will fail. If done after the decoding a suitably complex object tree would be impossible to correctly process, particularly if there are actual quotes embedded within the string.

I'd like to see this case documented on the Wiki with proper solution or get the parser properly decoding the string condition so JSON syntax is filtered out of the value results.

Apologies if I'm deciphering any of this incorrectly and I welcome any feedback.

- (id)JSONValue causing EXC_BAD_ACCESS [fix]

Hi there,
When I try to run the JSON-framework in an app on my iPhone (not the simulator), - (id)JSONValue is causing an EXC_BAD_ACCESS crash.
Below is the fix I use:

Replace #import "SBJsonParser.h" (at the top) by "SBJsonParser.m" (note the .h -> .m).

Kind regards,
Tim

Edit: this also happens in 3.0b1, probably the same thing.

Simplify error handling

The stack of errors seems to confuse people. So let's just try to get as much information about the error as possible, and return that as a string.

NSObject+JSON.h doesn't apply category method to NSObject

There was a recent refactoring to NSObject+JSON.h that isn't adding the category to NSObject. This produces compiler warnings on custom objects implementing proxyForJson as the JSONRepresentation method is only getting added to NSArray and NSDictionary.

String cache is not thread-safe

SBJsonStreamWriter is currently safe to use only from one thread, due to the shared stringCache variable. A few possible solutions in my favorite order:

  1. Move the cache into the instance. This makes sense since it frees up the memory as soon as it is done (as suggested in https://github.com/stig/json-framework/issues#issue/55).
  2. Use NSCache instead of NSMutableDictionary. It is explicitly thread-safe, though requires iOS >= 4.0 / OS X >= 10.6.
  3. Use OSSpinLock or a mutex around dictionary accesses. This makes the cache thread-safe, though imposes a performance penalty.
  4. Use a per-thread dictionary (e.g. using pthread_key_t). This will have about the same performance as the current implementation, with additional memory overhead.

SBJsonWriter infinity check

Presently, infinity is checked in appendValue: into: using
[fragment isEqualToNumber:[NSNumber numberWithDouble:INFINITY]]

This can cause problems because it's possible for
[[NSNumber numberWithFloat: 0] isEqualToNumber: [NSNumber numberWithDouble: INFINITY]]
to return YES. To check for infinity, you should change this line (line 109, SBJsonWriter.m) from:

 } else if ([fragment isEqualToNumber:[NSNumber numberWithDouble:INFINITY]] || [fragment isEqualToNumber:[NSNumber numberWithDouble:-INFINITY]]) {

to
} else if (isinf([fragment doubleValue])) {

SBJSON returning 'undeclared' during testing?

Hi guys

I doubt this is actually an issue, more me being a newb. I was working through Dan Grigsby's Lucky Numbers example of using the JSON framework and noticed that it worked perfectly when I used an older version of the frameset he included (stored in a seperate JSON directory) but when I created a project using the new version, dropping the files in the root of classes it still performed the check he used:

    NSString *jsonString = [NSString stringWithString:@"{\"foo\": \"bar\"}"];
NSDictionary *dictionary = [jsonString JSONValue];
NSLog(@"Dictionary value for \"foo\" is \"%@\"", [dictionary objectForKey:@"foo"]);

but if I try to use:

    SBJSON *json = [[SBJSON new] autorelease];

When I try to run it tells me that it is undeclared. It detects it when I am typing it in (and pressing tab completes it) but it doesn't change colour to blue in xcode to suggest it has recognised it. Once again, adding the older library makes it work fine.

Am I missing something here?

Kind regards,
Robsa

Thousands of memory leaks when using sbjson framework on repeated usage

Hi stig,

I am using JSON framework (SBJson) for my applicaition.

parsing the value by

NSDictionary *results = [responseString JSONValue] ;
For parsing first time in controller with this code has no problem. when i call again for same controller it shows thousands of memory leaks.

I went through many forums but in vain. can anybody please tell me what i went wrong?

Full Code:
NSString *response = [[NSString alloc] initWithData:webData encoding:NSUTF8StringEncoding];

//NSDictionary *results =[[response JSONValue] retain] ;

if (results) {
    [results release];
    results=nil;
}


results =[[response JSONValue] retain] ;
[response release];

Please see the pic for Instrument leaks:
http://i.imgur.com/2avo3.png

Thanks in advance

Regards,
Sathish

Double Number BUG

When to convert timestamp (double) to JSON, the last nember lost.

Please fix SBJsonStreamWriter.m Line.347

        len = sprintf(num, "%g", [number doubleValue]);

to
len = sprintf(num, "%f", [number doubleValue]);

Possible leak

I seem to be getting a leak in my iPhone App in -[SBJsonStreamParser init], Instruments believes it has to do with the states array. I am using iOS 4.1 as base SDK and iOS 3.2 as deployment target.
screenshot
No sure if this is really a framework problem or perhaps iOS or Instruments issue

Encoding issue

Firstly, thank you for the library, it's really helped with my iPhone dev. I've got a feeling that this is my problem rather than this libraries, but I've noticed when using strings that contain ™ or £ for example the I get the following JSON returned:

{"id":null,"error":{"name":"JSONRPCError","message":"Unterminated string.","errors":[{"name":"JsonException","message":"Unterminated string."},{"name":"FormatException","message":"Unterminated string."}]}}

Do I have to add some form of encoding myself to these type of characters? If so do you have any pointers?

Thanks again!

Framework not in DMG

Hey all,

Just an FYI the framework, nor any of the files required to build the framework are included with the latest 2.3 DMG, I am not sure if this was deliberate but its very confusing to me that the source is only the .h and .m files and not the actual XCode project you would use to build the framework too?

Framework & library build script

$SRCROOT needs to be put in double quotes so that the path to JSON.h is parsed correctly when it contains white space.

The script executes correctly in Xcode when it is like this:
/usr/bin/perl -pi -e 's/#if 1/#if 0/' "$SRCROOT"/Classes/JSON.h

This does parse

Hi,
I have this string: {'testEx': {'code': 400, 'message': "test string"}} and I haven't been able to parse it.
Using a JSON viewer like: http://jsonviewer.stack.hu/ seems to parse this just right.

I tried parsing down to the simplest way:
id object = [parser objectWithString:@"{'testEx': {'code': 400, 'message': "test string"}}" error:&error];

But it fails for an unknown reason.

Thanks

Delegate method implementation is not optional

When implementing the protocols for the StreamParser (or StreamParserAdapter) delegate protocols, there is an issue where the protocol methods are not deemed to be optional. There is no check to determine if the delegate object responds to the defined delegate selector (resulting in unrecognized selector exceptions).

My thought is that these should be optional as you may not want to implement every delegate method within your application.

I'm happy to submit a patch if required. Sorry if this is by design.

Parsing failed when I had a text "\p"

json-framework assumed that when you have a character "\p" somewhere in the middle, it assumes that it's an escape sequence and we get error:

Illegal character ... for \par

My content was:

{
"body":
{
"lang":
"en",
"text":
"

BEIJING (Reuters) - China raised its interest rates twice this year and increased the reserve ratio six times for banks in a bid to mop up excess liquidity in the market. Below is a timeline of the rate changes in 2010, and market reaction.

\n\n

December 25: China's central bank lifts benchmark one-year deposit and lending rates by 25 basis points on Christmas Day in a bid to head off price pressures which have raced to a 28-month high.

\n\n

- Chinese investors went from relief to apprehension of more tightening ahead, pushing the Shanghai stock market down 1.9 percent on Monday after earlier gains. Stock market punters initially piled into sectors seen as potentially benefiting from higher interest rates, including banks and insurers, but those bets reversed in the last hour of trade.

\n\n

Chinese equities have been generally resilient to interest rate rises. Before Saturday, A shares had risen on average 2.9 percent in the week after the past 10 benchmark interest rate increases in China and 7.8 percent a month later. The Hang Seng Chinese Enterprises index had risen on average 2.2 percent after a week and 6.3 percent after a month.

\n\n

- Offshore yuan forwards reflected expectations for greater appreciation in coming months.

\n\n

- The Australian dollar and commodities pared early losses as investors bet China's latest interest rate hike would not change the optimistic outlook for the global economy in 2011.

\n\n

- While commodity markets had expected a rate rise following a recent shift in monetary policy, the timing was a surprise, but markets recovered from early losses on expectations the measures would do little to curb China's appetite for industrial raw materials, energy, grains and other agricultural products.

\n\n

\par

\n\n

October 19: China's central bank raises its benchmark one-year lending and deposit rates by 25 basis points, its first rate hike since 2007.

\n\n

The quarter point increase was also the first time in modern history that Beijing adjusted deposit and lending levels by a number that was not a multiple of nine. In the past, the central bank typically raised rates by 27 basis points. On the abacus, adding multiples of nine was much easier than adding multiples of 10.

\n\n

- World stocks and commodity prices fell sharply. Crude oil slid more than 4 percent, its biggest single-day percentage decline in eight months, while copper tumbled from 27-month highs and gold shed as much as 2.7 percent, its largest one-day drop since early July. The dollar rallied broadly, while the Australian dollar, which had just risen above parity with the U.S. currency for the first time since 1983, was hit hardest, slipping 1.5 percent.

\n\n

- China's bond yields surged to an eight-month high after the central bank's surprise rate rise sparked fears of a sustained tightening campaign, but authorities kept a lid on the yuan to ward off hot money inflows.

\n\n

- China's stock market closed nearly flat after a day of volatile trading during which it lost as much as 2.0 percent but also gained as much as 1.3 percent at one point. The Shanghai Composite Index ultimately inched up 0.1 percent for the day, as liquidity in the financial sector remains ample despite the marginal increase in the cost of funds.

\n\n

_Shifts in Reserve Ratio Requirements of Chinese banks_

\n\n

December 10 : China's central bank raises lenders' required reserves by 50 basis points to 19 percent, a record high.

\n\n

- Marginal effect in financial markets dominated by other factors like U.S. and Chinese economic data.

\n\n

November 19 : The People's Bank of China lifts required reserve ratios by 50 basis points to 18.5 percent for big banks.

\n\n

- Stocks inched lower and commodities fell, but a tense market remained more focused on hopes of an Irish bailout and its broader implications for euro zone debt.\par

\n\n

November 10: China's central bank has ordered some banks to lift their required reserve ratios by 50 basis points in an apparent effort to curb rapid credit growth, three industry sources told Reuters.

\n\n

- Stocks and copper prices fell, but more because of slower-than-expected China import data, and continued worries over the Irish debt problem and its fallout on the euro.

\n\n

October 11: China has raised reserve requirements for six large commercial banks on a temporary basis, a surprise move to drain cash from the economy but avoid over-tightening. The 50-basis-point increase, which takes required reserve ratios to 17.5 percent for the country's biggest lenders, is the first since May.

\n\n

- Global markets tumbled earlier this year when China raised reserve requirements, but on this occasion investors took the news in their stride. The Australian dollar, which is sensitive to the strength of the Chinese economy -- the top Australian export destination -- came under brief selling pressure before paring its losses.

\n\n

May 2: PBOC raises lenders' reserve requirement ratio by 50 basis points to 17 percent.

\n\n",
"type":
"html"
},
"category":
"topNews",
"description":
"BEIJING (Reuters) - China raised its interest rates twice this year and increased the reserve ratio six times for banks in a bid to mop up excess liquidity in the market. Below is a timeline of the rate changes in 2010, and market reaction.",
"guid":
"USTRE6BR0KQ20101228",
"keywords":
[
"Online Report text item",
"U.S. domestic, non-Washington, general news",
"Financial pages",
"Canada"
],
"link":
"http://www.reuters.com/article/topNews/idUSTRE6BR0KQ20101228",
"published":
"2010-12-28T08:24:35Z",
"sources":
[],
"tickers":
[],
"title":
"Timeline: China rate changes in 2010, and market reaction",
"updated":
""
}

Does not correctly parse surrogate pairs

The following is not parsed correctly:

{ "MATHEMATICAL ITALIC CAPITAL ALPHA": "\uD835\uDEE2" }

Expected result:

{ "MATHEMATICAL ITALIC CAPITAL ALPHA": "𝛢" }

(note: github seems to have problems dealing with unicode characters > U+10000. This is why it looks funky, I did my best with what I could.)

Using the following code:

NSString *json = [NSString stringWithUTF8String:"{ \"MATHEMATICAL ITALIC CAPITAL ALPHA\": \"\\uD835\\uDEE2\" }"];
id obj = [json JSONValue];
NSLog(@"stringWithObject: %@", [writer stringWithObject:obj]);

... produces the following:

stringWithObject: {"MATHEMATICAL ITALIC CAPITAL ALPHA":"훢"}

Also, the code in parseUnicodeEscape and decodeHexQuad "may" (on a zero order approximation) have corner cases that "read past the end of the array", in particular when dealing with surrogate pairs. The code that calls parseUnicodeEscape seems to have an explicit length variable, while the unicode parsing code does not, instead relying on \0 termination. It's not clear to me if this assumption is guaranteed to be valid, looks very suspicious to me.

Unicode escape sequences

Great work apart from one little issue: when using the framework I recognized that unicode escape sequences are not unescaped properly, or did I miss out on something there, like calling a special method that would do that?

reported memory leak

Reposted from Issue 13 on google code:

I get a memory leak in OS 4.02 when requesting data more than once in a screen (with button) and parsing it with JSONValue, but not the first time.

NSError *error;
NSURLResponse *response;
NSData *dataReply;

NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://company.xxx.com/tabweb?get=Ligensuche&put=Suchwert:%@", searchBar.text]];


NSURLRequest *request = [NSURLRequest requestWithURL:url];
dataReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

NSString *responseString = [[NSString alloc] initWithData:dataReply encoding:NSUTF8StringEncoding];

NSDictionary *results = [responseString JSONValue]; <-- Hier leak occurs
if (results)
{
    tableData = [[NSArray alloc] initWithArray:[results objectForKey:@"data"]];
}
[responseString release];
responseString = nil;

[self.tableView reloadData];

Add NSData-based parser API

Very often, when obtaining JSON over HTTP for example, you have an NSData containing utf8-encoded JSON. It would be nice not having to translate this into an NSString, especially since the parser translates the string to a char * immediately anyway.

Problems parsing UTF-8

Using the following code (and the very special uuencoded file embedded in this ticket):

NSError *error = NULL;
SBJsonParser *parser = [SBJsonParser new];
NSData *json = [NSData dataWithContentsOfFile:@"UTF-8-test.json" options:0 error:&error];
id obj = [parser objectWithData:json];

... crashes. Expected result is obviously no crashing, but to _correctly_ deal with UTF-8 errors as specified in The Unicode 5.2 standard, Chapter 3, section 3.9 Unicode Encoding Forms.

---------------------------------------

The following can be turned back in to a file by selecting all the pre lines and then using

shell% pbpaste | openssl enc -d -base64 | bunzip2 > UTF-8-test.json; md5 UTF-8-test.json
MD5 (UTF-8-test.json) = 32d1547bd128a4278abeafbdd011396b

This will create a file UTF-8-test.json. The reason for all this is that the file contains JSON with _very_ specific UTF-8 encoding errors that are likely to be stripped or mutilated. It requires bit perfect binary replication. Even editing with something like TextEdit.app is likely to destroy the UTF-8 errors contained within.

QlpoOTFBWSZTWSw1iJcACbL////7YXn/////f//Orj////X/////////////////
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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.