cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From shaz...@apache.org
Subject [2/3] [CB-1946] iOS: Switch JSON serialization to NSJSONSerialization
Date Thu, 10 Jan 2013 23:37:28 GMT
http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/192122fe/CordovaLib/Classes/JSON/JSONKit.m
----------------------------------------------------------------------
diff --git a/CordovaLib/Classes/JSON/JSONKit.m b/CordovaLib/Classes/JSON/JSONKit.m
deleted file mode 100644
index 15a7171..0000000
--- a/CordovaLib/Classes/JSON/JSONKit.m
+++ /dev/null
@@ -1,3061 +0,0 @@
-//
-//  JSONKit.m
-//  http://github.com/johnezang/JSONKit
-//  Dual licensed under either the terms of the BSD License, or alternatively
-//  under the terms of the Apache License, Version 2.0, as specified below.
-//
-
-/*
- Copyright (c) 2011, John Engelhart
- 
- 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 Zang Industries 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.
-*/
-
-/*
- Copyright 2011 John Engelhart
- 
- Licensed 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.
-*/
-
-
-/*
-  Acknowledgments:
-
-  The bulk of the UTF8 / UTF32 conversion and verification comes
-  from ConvertUTF.[hc].  It has been modified from the original sources.
-
-  The original sources were obtained from http://www.unicode.org/.
-  However, the web site no longer seems to host the files.  Instead,
-  the Unicode FAQ http://www.unicode.org/faq//utf_bom.html#gen4
-  points to International Components for Unicode (ICU)
-  http://site.icu-project.org/ as an example of how to write a UTF
-  converter.
-
-  The decision to use the ConvertUTF.[ch] code was made to leverage
-  "proven" code.  Hopefully the local modifications are bug free.
-
-  The code in isValidCodePoint() is derived from the ICU code in
-  utf.h for the macros U_IS_UNICODE_NONCHAR and U_IS_UNICODE_CHAR.
-
-  From the original ConvertUTF.[ch]:
-
- * Copyright 2001-2004 Unicode, Inc.
- * 
- * Disclaimer
- * 
- * This source code is provided as is by Unicode, Inc. No claims are
- * made as to fitness for any particular purpose. No warranties of any
- * kind are expressed or implied. The recipient agrees to determine
- * applicability of information provided. If this file has been
- * purchased on magnetic or optical media from Unicode, Inc., the
- * sole remedy for any claim will be exchange of defective media
- * within 90 days of receipt.
- * 
- * Limitations on Rights to Redistribute This Code
- * 
- * Unicode, Inc. hereby grants the right to freely use the information
- * supplied in this file in the creation of products supporting the
- * Unicode Standard, and to make copies of this file in any form
- * for internal or external distribution as long as this notice
- * remains attached.
-
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <assert.h>
-#include <sys/errno.h>
-#include <math.h>
-#include <limits.h>
-#include <objc/runtime.h>
-
-#import "JSONKit.h"
-
-//#include <CoreFoundation/CoreFoundation.h>
-#include <CoreFoundation/CFString.h>
-#include <CoreFoundation/CFArray.h>
-#include <CoreFoundation/CFDictionary.h>
-#include <CoreFoundation/CFNumber.h>
-
-//#import <Foundation/Foundation.h>
-#import <Foundation/NSArray.h>
-#import <Foundation/NSAutoreleasePool.h>
-#import <Foundation/NSData.h>
-#import <Foundation/NSDictionary.h>
-#import <Foundation/NSException.h>
-#import <Foundation/NSNull.h>
-#import <Foundation/NSObjCRuntime.h>
-
-#ifndef __cdv_has_feature
-#define __cdv_has_feature(x) 0
-#endif
-
-#ifdef CDVJK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS
-#warning As of CDVJSONKit v1.4, CDVJK_ENABLE_CF_TRANSFER_OWNERSHIP_CALLBACKS is no longer required.  It is no longer a valid option.
-#endif
-
-#ifdef __OBJC_GC__
-#error CDVJSONKit does not support Objective-C Garbage Collection
-#endif
-
-#if __has_feature(objc_arc)
-#error CDVJSONKit does not support Objective-C Automatic Reference Counting (ARC)
-#endif
-
-// The following checks are really nothing more than sanity checks.
-// CDVJSONKit technically has a few problems from a "strictly C99 conforming" standpoint, though they are of the pedantic nitpicking variety.
-// In practice, though, for the compilers and architectures we can reasonably expect this code to be compiled for, these pedantic nitpicks aren't really a problem.
-// Since we're limited as to what we can do with pre-processor #if checks, these checks are not nearly as through as they should be.
-
-#if (UINT_MAX != 0xffffffffU) || (INT_MIN != (-0x7fffffff-1)) || (ULLONG_MAX != 0xffffffffffffffffULL) || (LLONG_MIN != (-0x7fffffffffffffffLL-1LL))
-#error CDVJSONKit requires the C 'int' and 'long long' types to be 32 and 64 bits respectively.
-#endif
-
-#if !defined(__LP64__) && ((UINT_MAX != ULONG_MAX) || (INT_MAX != LONG_MAX) || (INT_MIN != LONG_MIN) || (WORD_BIT != LONG_BIT))
-#error CDVJSONKit requires the C 'int' and 'long' types to be the same on 32-bit architectures.
-#endif
-
-// Cocoa / Foundation uses NS*Integer as the type for a lot of arguments.  We make sure that NS*Integer is something we are expecting and is reasonably compatible with size_t / ssize_t
-
-#if (NSUIntegerMax != ULONG_MAX) || (NSIntegerMax != LONG_MAX) || (NSIntegerMin != LONG_MIN)
-#error CDVJSONKit requires NSInteger and NSUInteger to be the same size as the C 'long' type.
-#endif
-
-#if (NSUIntegerMax != SIZE_MAX) || (NSIntegerMax != SSIZE_MAX)
-#error CDVJSONKit requires NSInteger and NSUInteger to be the same size as the C 'size_t' type.
-#endif
-
-
-// For DJB hash.
-#define CDVJK_HASH_INIT           (1402737925UL)
-
-// Use __builtin_clz() instead of trailingBytesForUTF8[] table lookup.
-#define CDVJK_FAST_TRAILING_BYTES
-
-// CDVJK_CACHE_SLOTS must be a power of 2.  Default size is 1024 slots.
-#define CDVJK_CACHE_SLOTS_BITS    (10)
-#define CDVJK_CACHE_SLOTS         (1UL << CDVJK_CACHE_SLOTS_BITS)
-// CDVJK_CACHE_PROBES is the number of probe attempts.
-#define CDVJK_CACHE_PROBES        (4UL)
-// CDVJK_INIT_CACHE_AGE must be (1 << AGE) - 1
-#define CDVJK_INIT_CACHE_AGE      (0)
-
-// CDVJK_TOKENBUFFER_SIZE is the default stack size for the temporary buffer used to hold "non-simple" strings (i.e., contains \ escapes)
-#define CDVJK_TOKENBUFFER_SIZE    (1024UL * 2UL)
-
-// CDVJK_STACK_OBJS is the default number of spaces reserved on the stack for temporarily storing pointers to Obj-C objects before they can be transferred to a NSArray / NSDictionary.
-#define CDVJK_STACK_OBJS          (1024UL * 1UL)
-
-#define CDVJK_JSONBUFFER_SIZE     (1024UL * 4UL)
-#define CDVJK_UTF8BUFFER_SIZE     (1024UL * 16UL)
-
-#define CDVJK_ENCODE_CACHE_SLOTS  (1024UL)
-
-
-#if       defined (__GNUC__) && (__GNUC__ >= 4)
-#define CDVJK_ATTRIBUTES(attr, ...)        __attribute__((attr, ##__VA_ARGS__))
-#define CDVJK_EXPECTED(cond, expect)       __builtin_expect((long)(cond), (expect))
-#define CDVJK_EXPECT_T(cond)               CDVJK_EXPECTED(cond, 1U)
-#define CDVJK_EXPECT_F(cond)               CDVJK_EXPECTED(cond, 0U)
-#define CDVJK_PREFETCH(ptr)                __builtin_prefetch(ptr)
-#else  // defined (__GNUC__) && (__GNUC__ >= 4) 
-#define CDVJK_ATTRIBUTES(attr, ...)
-#define CDVJK_EXPECTED(cond, expect)       (cond)
-#define CDVJK_EXPECT_T(cond)               (cond)
-#define CDVJK_EXPECT_F(cond)               (cond)
-#define CDVJK_PREFETCH(ptr)
-#endif // defined (__GNUC__) && (__GNUC__ >= 4) 
-
-#define CDVJK_STATIC_INLINE                         static __inline__ CDVJK_ATTRIBUTES(always_inline)
-#define CDVJK_ALIGNED(arg)                                            CDVJK_ATTRIBUTES(aligned(arg))
-#define CDVJK_UNUSED_ARG                                              CDVJK_ATTRIBUTES(unused)
-#define CDVJK_WARN_UNUSED                                             CDVJK_ATTRIBUTES(warn_unused_result)
-#define CDVJK_WARN_UNUSED_CONST                                       CDVJK_ATTRIBUTES(warn_unused_result, const)
-#define CDVJK_WARN_UNUSED_PURE                                        CDVJK_ATTRIBUTES(warn_unused_result, pure)
-#define CDVJK_WARN_UNUSED_SENTINEL                                    CDVJK_ATTRIBUTES(warn_unused_result, sentinel)
-#define CDVJK_NONNULL_ARGS(arg, ...)                                  CDVJK_ATTRIBUTES(nonnull(arg, ##__VA_ARGS__))
-#define CDVJK_WARN_UNUSED_NONNULL_ARGS(arg, ...)                      CDVJK_ATTRIBUTES(warn_unused_result, nonnull(arg, ##__VA_ARGS__))
-#define CDVJK_WARN_UNUSED_CONST_NONNULL_ARGS(arg, ...)                CDVJK_ATTRIBUTES(warn_unused_result, const, nonnull(arg, ##__VA_ARGS__))
-#define CDVJK_WARN_UNUSED_PURE_NONNULL_ARGS(arg, ...)                 CDVJK_ATTRIBUTES(warn_unused_result, pure, nonnull(arg, ##__VA_ARGS__))
-
-#if       defined (__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3)
-#define CDVJK_ALLOC_SIZE_NON_NULL_ARGS_WARN_UNUSED(as, nn, ...) CDVJK_ATTRIBUTES(warn_unused_result, nonnull(nn, ##__VA_ARGS__), alloc_size(as))
-#else  // defined (__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3)
-#define CDVJK_ALLOC_SIZE_NON_NULL_ARGS_WARN_UNUSED(as, nn, ...) CDVJK_ATTRIBUTES(warn_unused_result, nonnull(nn, ##__VA_ARGS__))
-#endif // defined (__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3)
-
-
-@class CDVJKArray, CDVJKDictionaryEnumerator, CDVJKDictionary;
-
-enum {
-  CDVJSONNumberStateStart                 = 0,
-  CDVJSONNumberStateFinished              = 1,
-  CDVJSONNumberStateError                 = 2,
-  CDVJSONNumberStateWholeNumberStart      = 3,
-  CDVJSONNumberStateWholeNumberMinus      = 4,
-  CDVJSONNumberStateWholeNumberZero       = 5,
-  CDVJSONNumberStateWholeNumber           = 6,
-  CDVJSONNumberStatePeriod                = 7,
-  CDVJSONNumberStateFractionalNumberStart = 8,
-  CDVJSONNumberStateFractionalNumber      = 9,
-  CDVJSONNumberStateExponentStart         = 10,
-  CDVJSONNumberStateExponentPlusMinus     = 11,
-  CDVJSONNumberStateExponent              = 12,
-};
-
-enum {
-  CDVJSONStringStateStart                           = 0,
-  CDVJSONStringStateParsing                         = 1,
-  CDVJSONStringStateFinished                        = 2,
-  CDVJSONStringStateError                           = 3,
-  CDVJSONStringStateEscape                          = 4,
-  CDVJSONStringStateEscapedUnicode1                 = 5,
-  CDVJSONStringStateEscapedUnicode2                 = 6,
-  CDVJSONStringStateEscapedUnicode3                 = 7,
-  CDVJSONStringStateEscapedUnicode4                 = 8,
-  CDVJSONStringStateEscapedUnicodeSurrogate1        = 9,
-  CDVJSONStringStateEscapedUnicodeSurrogate2        = 10,
-  CDVJSONStringStateEscapedUnicodeSurrogate3        = 11,
-  CDVJSONStringStateEscapedUnicodeSurrogate4        = 12,
-  CDVJSONStringStateEscapedNeedEscapeForSurrogate   = 13,
-  CDVJSONStringStateEscapedNeedEscapedUForSurrogate = 14,
-};
-
-enum {
-  CDVJKParseAcceptValue      = (1 << 0),
-  CDVJKParseAcceptComma      = (1 << 1),
-  CDVJKParseAcceptEnd        = (1 << 2),
-  CDVJKParseAcceptValueOrEnd = (CDVJKParseAcceptValue | CDVJKParseAcceptEnd),
-  CDVJKParseAcceptCommaOrEnd = (CDVJKParseAcceptComma | CDVJKParseAcceptEnd),
-};
-
-enum {
-  CDVJKClassUnknown    = 0,
-  CDVJKClassString     = 1,
-  CDVJKClassNumber     = 2,
-  CDVJKClassArray      = 3,
-  CDVJKClassDictionary = 4,
-  CDVJKClassNull       = 5,
-};
-
-enum {
-  CDVJKManagedBufferOnStack        = 1,
-  CDVJKManagedBufferOnHeap         = 2,
-  CDVJKManagedBufferLocationMask   = (0x3),
-  CDVJKManagedBufferLocationShift  = (0),
-  
-  CDVJKManagedBufferMustFree       = (1 << 2),
-};
-typedef CDVJKFlags CDVJKManagedBufferFlags;
-
-enum {
-  CDVJKObjectStackOnStack        = 1,
-  CDVJKObjectStackOnHeap         = 2,
-  CDVJKObjectStackLocationMask   = (0x3),
-  CDVJKObjectStackLocationShift  = (0),
-  
-  CDVJKObjectStackMustFree       = (1 << 2),
-};
-typedef CDVJKFlags CDVJKObjectStackFlags;
-
-enum {
-  CDVJKTokenTypeInvalid     = 0,
-  CDVJKTokenTypeNumber      = 1,
-  CDVJKTokenTypeString      = 2,
-  CDVJKTokenTypeObjectBegin = 3,
-  CDVJKTokenTypeObjectEnd   = 4,
-  CDVJKTokenTypeArrayBegin  = 5,
-  CDVJKTokenTypeArrayEnd    = 6,
-  CDVJKTokenTypeSeparator   = 7,
-  CDVJKTokenTypeComma       = 8,
-  CDVJKTokenTypeTrue        = 9,
-  CDVJKTokenTypeFalse       = 10,
-  CDVJKTokenTypeNull        = 11,
-  CDVJKTokenTypeWhiteSpace  = 12,
-};
-typedef NSUInteger CDVJKTokenType;
-
-// These are prime numbers to assist with hash slot probing.
-enum {
-  CDVJKValueTypeNone             = 0,
-  CDVJKValueTypeString           = 5,
-  CDVJKValueTypeLongLong         = 7,
-  CDVJKValueTypeUnsignedLongLong = 11,
-  CDVJKValueTypeDouble           = 13,
-};
-typedef NSUInteger CDVJKValueType;
-
-enum {
-  CDVJKEncodeOptionAsData              = 1,
-  CDVJKEncodeOptionAsString            = 2,
-  CDVJKEncodeOptionAsTypeMask          = 0x7,
-  CDVJKEncodeOptionCollectionObj       = (1 << 3),
-  CDVJKEncodeOptionStringObj           = (1 << 4),
-  CDVJKEncodeOptionStringObjTrimQuotes = (1 << 5),
-  
-};
-typedef NSUInteger CDVJKEncodeOptionType;
-
-typedef NSUInteger CDVJKHash;
-
-typedef struct CDVJKTokenCacheItem  CDVJKTokenCacheItem;
-typedef struct CDVJKTokenCache      CDVJKTokenCache;
-typedef struct CDVJKTokenValue      CDVJKTokenValue;
-typedef struct CDVJKParseToken      CDVJKParseToken;
-typedef struct CDVJKPtrRange        CDVJKPtrRange;
-typedef struct CDVJKObjectStack     CDVJKObjectStack;
-typedef struct CDVJKBuffer          CDVJKBuffer;
-typedef struct CDVJKConstBuffer     CDVJKConstBuffer;
-typedef struct CDVJKConstPtrRange   CDVJKConstPtrRange;
-typedef struct CDVJKRange           CDVJKRange;
-typedef struct CDVJKManagedBuffer   CDVJKManagedBuffer;
-typedef struct CDVJKFastClassLookup CDVJKFastClassLookup;
-typedef struct CDVJKEncodeCache     CDVJKEncodeCache;
-typedef struct CDVJKEncodeState     CDVJKEncodeState;
-typedef struct CDVJKObjCImpCache    CDVJKObjCImpCache;
-typedef struct CDVJKHashTableEntry  CDVJKHashTableEntry;
-
-typedef id (*NSNumberAllocImp)(id receiver, SEL selector);
-typedef id (*NSNumberInitWithUnsignedLongLongImp)(id receiver, SEL selector, unsigned long long value);
-typedef id (*CDVJKClassFormatterIMP)(id receiver, SEL selector, id object);
-#ifdef __BLOCKS__
-typedef id (^CDVJKClassFormatterBlock)(id formatObject);
-#endif
-
-
-struct CDVJKPtrRange {
-  unsigned char *ptr;
-  size_t         length;
-};
-
-struct CDVJKConstPtrRange {
-  const unsigned char *ptr;
-  size_t               length;
-};
-
-struct CDVJKRange {
-  size_t location, length;
-};
-
-struct CDVJKManagedBuffer {
-  CDVJKPtrRange           bytes;
-  CDVJKManagedBufferFlags flags;
-  size_t               roundSizeUpToMultipleOf;
-};
-
-struct CDVJKObjectStack {
-  void               **objects, **keys;
-  CFHashCode          *cfHashes;
-  size_t               count, index, roundSizeUpToMultipleOf;
-  CDVJKObjectStackFlags   flags;
-};
-
-struct CDVJKBuffer {
-  CDVJKPtrRange bytes;
-};
-
-struct CDVJKConstBuffer {
-  CDVJKConstPtrRange bytes;
-};
-
-struct CDVJKTokenValue {
-  CDVJKConstPtrRange   ptrRange;
-  CDVJKValueType       type;
-  CDVJKHash            hash;
-  union {
-    long long          longLongValue;
-    unsigned long long unsignedLongLongValue;
-    double             doubleValue;
-  } number;
-  CDVJKTokenCacheItem *cacheItem;
-};
-
-struct CDVJKParseToken {
-  CDVJKConstPtrRange tokenPtrRange;
-  CDVJKTokenType     type;
-  CDVJKTokenValue    value;
-  CDVJKManagedBuffer tokenBuffer;
-};
-
-struct CDVJKTokenCacheItem {
-  void          *object;
-  CDVJKHash         hash;
-  CFHashCode     cfHash;
-  size_t         size;
-  unsigned char *bytes;
-  CDVJKValueType    type;
-};
-
-struct CDVJKTokenCache {
-  CDVJKTokenCacheItem *items;
-  size_t            count;
-  unsigned int      prng_lfsr;
-  unsigned char     age[CDVJK_CACHE_SLOTS];
-};
-
-struct CDVJKObjCImpCache {
-  Class                               NSNumberClass;
-  NSNumberAllocImp                    NSNumberAlloc;
-  NSNumberInitWithUnsignedLongLongImp NSNumberInitWithUnsignedLongLong;
-};
-
-struct CDVJKParseState {
-  CDVJKParseOptionFlags  parseOptionFlags;
-  CDVJKConstBuffer       stringBuffer;
-  size_t              atIndex, lineNumber, lineStartIndex;
-  size_t              prev_atIndex, prev_lineNumber, prev_lineStartIndex;
-  CDVJKParseToken        token;
-  CDVJKObjectStack       objectStack;
-  CDVJKTokenCache        cache;
-  CDVJKObjCImpCache      objCImpCache;
-  NSError            *error;
-  int                 errorIsPrev;
-  BOOL                mutableCollections;
-};
-
-struct CDVJKFastClassLookup {
-  void *stringClass;
-  void *numberClass;
-  void *arrayClass;
-  void *dictionaryClass;
-  void *nullClass;
-};
-
-struct CDVJKEncodeCache {
-  id object;
-  size_t offset;
-  size_t length;
-};
-
-struct CDVJKEncodeState {
-  CDVJKManagedBuffer         utf8ConversionBuffer;
-  CDVJKManagedBuffer         stringBuffer;
-  size_t                  atIndex;
-  CDVJKFastClassLookup       fastClassLookup;
-  CDVJKEncodeCache           cache[CDVJK_ENCODE_CACHE_SLOTS];
-  CDVJKSerializeOptionFlags  serializeOptionFlags;
-  CDVJKEncodeOptionType      encodeOption;
-  size_t                  depth;
-  NSError                *error;
-  id                      classFormatterDelegate;
-  SEL                     classFormatterSelector;
-  CDVJKClassFormatterIMP     classFormatterIMP;
-#ifdef __BLOCKS__
-  CDVJKClassFormatterBlock   classFormatterBlock;
-#endif
-};
-
-// This is a CDVJSONKit private class.
-@interface CDVJKSerializer : NSObject {
-  CDVJKEncodeState *encodeState;
-}
-
-#ifdef __BLOCKS__
-#define CDVJKSERIALIZER_BLOCKS_PROTO id(^)(id object)
-#else
-#define CDVJKSERIALIZER_BLOCKS_PROTO id
-#endif
-
-+ (id)serializeObject:(id)object options:(CDVJKSerializeOptionFlags)optionFlags encodeOption:(CDVJKEncodeOptionType)encodeOption block:(CDVJKSERIALIZER_BLOCKS_PROTO)block delegate:(id)delegate selector:(SEL)selector error:(NSError **)error;
-- (id)serializeObject:(id)object options:(CDVJKSerializeOptionFlags)optionFlags encodeOption:(CDVJKEncodeOptionType)encodeOption block:(CDVJKSERIALIZER_BLOCKS_PROTO)block delegate:(id)delegate selector:(SEL)selector error:(NSError **)error;
-- (void)releaseState;
-
-@end
-
-struct CDVJKHashTableEntry {
-  NSUInteger keyHash;
-  id key, object;
-};
-
-
-typedef uint32_t UTF32; /* at least 32 bits */
-typedef uint16_t UTF16; /* at least 16 bits */
-typedef uint8_t  UTF8;  /* typically 8 bits */
-
-typedef enum {
-  conversionOK,           /* conversion successful */
-  sourceExhausted,        /* partial character in source, but hit end */
-  targetExhausted,        /* insuff. room in target for conversion */
-  sourceIllegal           /* source sequence is illegal/malformed */
-} CDV_ConversionResult;
-
-#define CDV_UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
-#define CDV_UNI_MAX_BMP          (UTF32)0x0000FFFF
-#define CDV_UNI_MAX_UTF16        (UTF32)0x0010FFFF
-#define CDV_UNI_MAX_UTF32        (UTF32)0x7FFFFFFF
-#define CDV_UNI_MAX_LEGAL_UTF32  (UTF32)0x0010FFFF
-#define CDV_UNI_SUR_HIGH_START   (UTF32)0xD800
-#define CDV_UNI_SUR_HIGH_END     (UTF32)0xDBFF
-#define CDV_UNI_SUR_LOW_START    (UTF32)0xDC00
-#define CDV_UNI_SUR_LOW_END      (UTF32)0xDFFF
-
-
-#if !defined(CDVJK_FAST_TRAILING_BYTES)
-static const char trailingBytesForUTF8[256] = {
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
-    2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5
-};
-#endif
-
-static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 0x03C82080UL, 0xFA082080UL, 0x82082080UL };
-static const UTF8  firstByteMark[7]   = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
-
-#define CDVJK_AT_STRING_PTR(x)  (&((x)->stringBuffer.bytes.ptr[(x)->atIndex]))
-#define CDVJK_END_STRING_PTR(x) (&((x)->stringBuffer.bytes.ptr[(x)->stringBuffer.bytes.length]))
-
-
-static CDVJKArray          *_CDVJKArrayCreate(id *objects, NSUInteger count, BOOL mutableCollection);
-static void              _CDVJKArrayInsertObjectAtIndex(CDVJKArray *array, id newObject, NSUInteger objectIndex);
-static void              _CDVJKArrayReplaceObjectAtIndexWithObject(CDVJKArray *array, NSUInteger objectIndex, id newObject);
-static void              _CDVJKArrayRemoveObjectAtIndex(CDVJKArray *array, NSUInteger objectIndex);
-
-
-static NSUInteger        _CDVJKDictionaryCapacityForCount(NSUInteger count);
-static CDVJKDictionary     *_CDVJKDictionaryCreate(id *keys, NSUInteger *keyHashes, id *objects, NSUInteger count, BOOL mutableCollection);
-static CDVJKHashTableEntry *_CDVJKDictionaryHashEntry(CDVJKDictionary *dictionary);
-static NSUInteger        _CDVJKDictionaryCapacity(CDVJKDictionary *dictionary);
-static void              _CDVJKDictionaryResizeIfNeccessary(CDVJKDictionary *dictionary);
-static void              _CDVJKDictionaryRemoveObjectWithEntry(CDVJKDictionary *dictionary, CDVJKHashTableEntry *entry);
-static void              _CDVJKDictionaryAddObject(CDVJKDictionary *dictionary, NSUInteger keyHash, id key, id object);
-static CDVJKHashTableEntry *_CDVJKDictionaryHashTableEntryForKey(CDVJKDictionary *dictionary, id aKey);
-
-
-static void _CDVJSONDecoderCleanup(CDVJSONDecoder *decoder);
-
-static id _CDVNSStringObjectFromJSONString(NSString *jsonString, CDVJKParseOptionFlags parseOptionFlags, NSError **error, BOOL mutableCollection);
-
-
-static void cdvjk_managedBuffer_release(CDVJKManagedBuffer *managedBuffer);
-static void cdvjk_managedBuffer_setToStackBuffer(CDVJKManagedBuffer *managedBuffer, unsigned char *ptr, size_t length);
-static unsigned char *cdvjk_managedBuffer_resize(CDVJKManagedBuffer *managedBuffer, size_t newSize);
-static void cdvjk_objectStack_release(CDVJKObjectStack *objectStack);
-static void cdvjk_objectStack_setToStackBuffer(CDVJKObjectStack *objectStack, void **objects, void **keys, CFHashCode *cfHashes, size_t count);
-static int  cdvjk_objectStack_resize(CDVJKObjectStack *objectStack, size_t newCount);
-
-static void   cdvjk_error(CDVJKParseState *parseState, NSString *format, ...);
-static int    cdvjk_parse_string(CDVJKParseState *parseState);
-static int    cdvjk_parse_number(CDVJKParseState *parseState);
-static size_t cdvjk_parse_is_newline(CDVJKParseState *parseState, const unsigned char *atCharacterPtr);
-CDVJK_STATIC_INLINE int cdvjk_parse_skip_newline(CDVJKParseState *parseState);
-CDVJK_STATIC_INLINE void cdvjk_parse_skip_whitespace(CDVJKParseState *parseState);
-static int    cdvjk_parse_next_token(CDVJKParseState *parseState);
-static void   cdvjk_error_parse_accept_or3(CDVJKParseState *parseState, int state, NSString *or1String, NSString *or2String, NSString *or3String);
-static void  *cdvjk_create_dictionary(CDVJKParseState *parseState, size_t startingObjectIndex);
-static void  *cdvjk_parse_dictionary(CDVJKParseState *parseState);
-static void  *cdvjk_parse_array(CDVJKParseState *parseState);
-static void  *cdvjk_object_for_token(CDVJKParseState *parseState);
-static void  *cdvjk_cachedObjects(CDVJKParseState *parseState);
-CDVJK_STATIC_INLINE void cdvjk_cache_age(CDVJKParseState *parseState);
-CDVJK_STATIC_INLINE void cdvjk_set_parsed_token(CDVJKParseState *parseState, const unsigned char *ptr, size_t length, CDVJKTokenType type, size_t advanceBy);
-
-
-static void cdvjk_encode_error(CDVJKEncodeState *encodeState, NSString *format, ...);
-static int cdvjk_encode_printf(CDVJKEncodeState *encodeState, CDVJKEncodeCache *cacheSlot, size_t startingAtIndex, id object, const char *format, ...);
-static int cdvjk_encode_write(CDVJKEncodeState *encodeState, CDVJKEncodeCache *cacheSlot, size_t startingAtIndex, id object, const char *format);
-static int cdvjk_encode_writePrettyPrintWhiteSpace(CDVJKEncodeState *encodeState);
-static int cdvjk_encode_write1slow(CDVJKEncodeState *encodeState, ssize_t depthChange, const char *format);
-static int cdvjk_encode_write1fast(CDVJKEncodeState *encodeState, ssize_t depthChange CDVJK_UNUSED_ARG, const char *format);
-static int cdvjk_encode_writen(CDVJKEncodeState *encodeState, CDVJKEncodeCache *cacheSlot, size_t startingAtIndex, id object, const char *format, size_t length);
-CDVJK_STATIC_INLINE CDVJKHash cdvjk_encode_object_hash(void *objectPtr);
-CDVJK_STATIC_INLINE void cdvjk_encode_updateCache(CDVJKEncodeState *encodeState, CDVJKEncodeCache *cacheSlot, size_t startingAtIndex, id object);
-static int cdvjk_encode_add_atom_to_buffer(CDVJKEncodeState *encodeState, void *objectPtr);
-
-#define cdvjk_encode_write1(es, dc, f)  (CDVJK_EXPECT_F(_jk_encode_prettyPrint) ? cdvjk_encode_write1slow(es, dc, f) : cdvjk_encode_write1fast(es, dc, f))
-
-
-CDVJK_STATIC_INLINE size_t cdvjk_min(size_t a, size_t b);
-CDVJK_STATIC_INLINE size_t cdvjk_max(size_t a, size_t b);
-CDVJK_STATIC_INLINE CDVJKHash cdvcalculateHash(CDVJKHash currentHash, unsigned char c);
-
-// CDVJSONKit v1.4 used both a CDVJKArray : NSArray and CDVJKMutableArray : NSMutableArray, and the same for the dictionary collection type.
-// However, Louis Gerbarg (via cocoa-dev) pointed out that Cocoa / Core Foundation actually implements only a single class that inherits from the 
-// mutable version, and keeps an ivar bit for whether or not that instance is mutable.  This means that the immutable versions of the collection
-// classes receive the mutating methods, but this is handled by having those methods throw an exception when the ivar bit is set to immutable.
-// We adopt the same strategy here.  It's both cleaner and gets rid of the method swizzling hackery used in CDVJSONKit v1.4.
-
-
-// This is a workaround for issue #23 https://github.com/johnezang/JSONKit/pull/23
-// Basically, there seem to be a problem with using +load in static libraries on iOS.  However, __attribute__ ((constructor)) does work correctly.
-// Since we do not require anything "special" that +load provides, and we can accomplish the same thing using __attribute__ ((constructor)), the +load logic was moved here.
-
-static Class                               _CDVJKArrayClass                           = NULL;
-static size_t                              _CDVJKArrayInstanceSize                    = 0UL;
-static Class                               _CDVJKDictionaryClass                      = NULL;
-static size_t                              _CDVJKDictionaryInstanceSize               = 0UL;
-
-// For CDVJSONDecoder...
-static Class                               _CDVjk_NSNumberClass                       = NULL;
-static NSNumberAllocImp                    _CDVjk_NSNumberAllocImp                    = NULL;
-static NSNumberInitWithUnsignedLongLongImp _CDVjk_NSNumberInitWithUnsignedLongLongImp = NULL;
-
-extern void cdvjk_collectionClassLoadTimeInitialization(void) __attribute__ ((constructor));
-
-void cdvjk_collectionClassLoadTimeInitialization(void) {
-  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Though technically not required, the run time environment at load time initialization may be less than ideal.
-  
-  _CDVJKArrayClass             = objc_getClass("CDVJKArray");
-  _CDVJKArrayInstanceSize      = cdvjk_max(16UL, class_getInstanceSize(_CDVJKArrayClass));
-  
-  _CDVJKDictionaryClass        = objc_getClass("CDVJKDictionary");
-  _CDVJKDictionaryInstanceSize = cdvjk_max(16UL, class_getInstanceSize(_CDVJKDictionaryClass));
-  
-  // For CDVJSONDecoder...
-  _CDVjk_NSNumberClass = [NSNumber class];
-  _CDVjk_NSNumberAllocImp = (NSNumberAllocImp)[NSNumber methodForSelector:@selector(alloc)];
-  
-  // Hacktacular.  Need to do it this way due to the nature of class clusters.
-  id temp_NSNumber = [NSNumber alloc];
-  _CDVjk_NSNumberInitWithUnsignedLongLongImp = (NSNumberInitWithUnsignedLongLongImp)[temp_NSNumber methodForSelector:@selector(initWithUnsignedLongLong:)];
-  [[temp_NSNumber init] release];
-  temp_NSNumber = NULL;
-  
-  [pool release]; pool = NULL;
-}
-
-
-#pragma mark -
-@interface CDVJKArray : NSMutableArray <NSCopying, NSMutableCopying, NSFastEnumeration> {
-  id         *objects;
-  NSUInteger  count, capacity, mutations;
-}
-@end
-
-@implementation CDVJKArray
-
-+ (id)allocWithZone:(NSZone *)zone
-{
-#pragma unused(zone)
-  [NSException raise:NSInvalidArgumentException format:@"*** - [%@ %@]: The %@ class is private to CDVJSONKit and should not be used in this fashion.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), NSStringFromClass([self class])];
-  return(NULL);
-}
-
-static CDVJKArray *_CDVJKArrayCreate(id *objects, NSUInteger count, BOOL mutableCollection) {
-  NSCParameterAssert((objects != NULL) && (_CDVJKArrayClass != NULL) && (_CDVJKArrayInstanceSize > 0UL));
-  CDVJKArray *array = NULL;
-  if(CDVJK_EXPECT_T((array = (CDVJKArray *)calloc(1UL, _CDVJKArrayInstanceSize)) != NULL)) { // Directly allocate the CDVJKArray instance via calloc.
-    array->isa      = _CDVJKArrayClass;
-    if((array = [array init]) == NULL) { return(NULL); }
-    array->capacity = count;
-    array->count    = count;
-    if(CDVJK_EXPECT_F((array->objects = (id *)malloc(sizeof(id) * array->capacity)) == NULL)) { [array autorelease]; return(NULL); }
-    memcpy(array->objects, objects, array->capacity * sizeof(id));
-    array->mutations = (mutableCollection == NO) ? 0UL : 1UL;
-  }
-  return(array);
-}
-
-// Note: The caller is responsible for -retaining the object that is to be added.
-static void _CDVJKArrayInsertObjectAtIndex(CDVJKArray *array, id newObject, NSUInteger objectIndex) {
-  NSCParameterAssert((array != NULL) && (array->objects != NULL) && (array->count <= array->capacity) && (objectIndex <= array->count) && (newObject != NULL));
-  if(!((array != NULL) && (array->objects != NULL) && (objectIndex <= array->count) && (newObject != NULL))) { [newObject autorelease]; return; }
-  if((array->count + 1UL) >= array->capacity) {
-    id *newObjects = NULL;
-    if((newObjects = (id *)realloc(array->objects, sizeof(id) * (array->capacity + 16UL))) == NULL) { [NSException raise:NSMallocException format:@"Unable to resize objects array."]; }
-    array->objects = newObjects;
-    array->capacity += 16UL;
-    memset(&array->objects[array->count], 0, sizeof(id) * (array->capacity - array->count));
-  }
-  array->count++;
-  if((objectIndex + 1UL) < array->count) { memmove(&array->objects[objectIndex + 1UL], &array->objects[objectIndex], sizeof(id) * ((array->count - 1UL) - objectIndex)); array->objects[objectIndex] = NULL; }
-  array->objects[objectIndex] = newObject;
-}
-
-// Note: The caller is responsible for -retaining the object that is to be added.
-static void _CDVJKArrayReplaceObjectAtIndexWithObject(CDVJKArray *array, NSUInteger objectIndex, id newObject) {
-  NSCParameterAssert((array != NULL) && (array->objects != NULL) && (array->count <= array->capacity) && (objectIndex < array->count) && (array->objects[objectIndex] != NULL) && (newObject != NULL));
-  if(!((array != NULL) && (array->objects != NULL) && (objectIndex < array->count) && (array->objects[objectIndex] != NULL) && (newObject != NULL))) { [newObject autorelease]; return; }
-  CFRelease(array->objects[objectIndex]);
-  array->objects[objectIndex] = NULL;
-  array->objects[objectIndex] = newObject;
-}
-
-static void _CDVJKArrayRemoveObjectAtIndex(CDVJKArray *array, NSUInteger objectIndex) {
-  NSCParameterAssert((array != NULL) && (array->objects != NULL) && (array->count > 0UL) && (array->count <= array->capacity) && (objectIndex < array->count) && (array->objects[objectIndex] != NULL));
-  if(!((array != NULL) && (array->objects != NULL) && (array->count > 0UL) && (array->count <= array->capacity) && (objectIndex < array->count) && (array->objects[objectIndex] != NULL))) { return; }
-  CFRelease(array->objects[objectIndex]);
-  array->objects[objectIndex] = NULL;
-  if((objectIndex + 1UL) < array->count) { memmove(&array->objects[objectIndex], &array->objects[objectIndex + 1UL], sizeof(id) * ((array->count - 1UL) - objectIndex)); array->objects[array->count - 1UL] = NULL; }
-  array->count--;
-}
-
-- (void)dealloc
-{
-  if(CDVJK_EXPECT_T(objects != NULL)) {
-    NSUInteger atObject = 0UL;
-    for(atObject = 0UL; atObject < count; atObject++) { if(CDVJK_EXPECT_T(objects[atObject] != NULL)) { CFRelease(objects[atObject]); objects[atObject] = NULL; } }
-    free(objects); objects = NULL;
-  }
-  
-  [super dealloc];
-}
-
-- (NSUInteger)count
-{
-  NSParameterAssert((objects != NULL) && (count <= capacity));
-  return(count);
-}
-
-- (void)getObjects:(id *)objectsPtr range:(NSRange)range
-{
-  NSParameterAssert((objects != NULL) && (count <= capacity));
-  if((objectsPtr     == NULL)  && (NSMaxRange(range) > 0UL))   { [NSException raise:NSRangeException format:@"*** -[%@ %@]: pointer to objects array is NULL but range length is %u", NSStringFromClass([self class]), NSStringFromSelector(_cmd), NSMaxRange(range)];        }
-  if((range.location >  count) || (NSMaxRange(range) > count)) { [NSException raise:NSRangeException format:@"*** -[%@ %@]: index (%u) beyond bounds (%u)",                          NSStringFromClass([self class]), NSStringFromSelector(_cmd), NSMaxRange(range), count]; }
-  if (objectsPtr != NULL) {
-      memcpy(objectsPtr, objects + range.location, range.length * sizeof(id));
-  }
-}
-
-- (id)objectAtIndex:(NSUInteger)objectIndex
-{
-  if(objectIndex >= count) { [NSException raise:NSRangeException format:@"*** -[%@ %@]: index (%u) beyond bounds (%u)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), objectIndex, count]; }
-  NSParameterAssert((objects != NULL) && (count <= capacity) && (objects[objectIndex] != NULL));
-  return(objects[objectIndex]);
-}
-
-- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len
-{
-  NSParameterAssert((state != NULL) && (stackbuf != NULL) && (len > 0UL) && (objects != NULL) && (count <= capacity));
-  if(CDVJK_EXPECT_F(state->state == 0UL))   { state->mutationsPtr = (unsigned long *)&mutations; state->itemsPtr = stackbuf; }
-  if(CDVJK_EXPECT_F(state->state >= count)) { return(0UL); }
-  
-  NSUInteger enumeratedCount  = 0UL;
-  while(CDVJK_EXPECT_T(enumeratedCount < len) && CDVJK_EXPECT_T(state->state < count)) { NSParameterAssert(objects[state->state] != NULL); stackbuf[enumeratedCount++] = objects[state->state++]; }
-  
-  return(enumeratedCount);
-}
-
-- (void)insertObject:(id)anObject atIndex:(NSUInteger)objectIndex
-{
-  if(mutations   == 0UL)   { [NSException raise:NSInternalInconsistencyException format:@"*** -[%@ %@]: mutating method sent to immutable object", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; }
-  if(anObject    == NULL)  { [NSException raise:NSInvalidArgumentException       format:@"*** -[%@ %@]: attempt to insert nil",                    NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; }
-  if(objectIndex >  count) { [NSException raise:NSRangeException                 format:@"*** -[%@ %@]: index (%u) beyond bounds (%lu)",          NSStringFromClass([self class]), NSStringFromSelector(_cmd), objectIndex, count + 1UL]; }
-#ifdef __clang_analyzer__
-  [anObject retain]; // Stupid clang analyzer...  Issue #19.
-#else
-  anObject = [anObject retain];
-#endif
-  _CDVJKArrayInsertObjectAtIndex(self, anObject, objectIndex);
-  mutations = (mutations == NSUIntegerMax) ? 1UL : mutations + 1UL;
-}
-
-- (void)removeObjectAtIndex:(NSUInteger)objectIndex
-{
-  if(mutations   == 0UL)   { [NSException raise:NSInternalInconsistencyException format:@"*** -[%@ %@]: mutating method sent to immutable object", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; }
-  if(objectIndex >= count) { [NSException raise:NSRangeException                 format:@"*** -[%@ %@]: index (%u) beyond bounds (%u)",          NSStringFromClass([self class]), NSStringFromSelector(_cmd), objectIndex, count]; }
-  _CDVJKArrayRemoveObjectAtIndex(self, objectIndex);
-  mutations = (mutations == NSUIntegerMax) ? 1UL : mutations + 1UL;
-}
-
-- (void)replaceObjectAtIndex:(NSUInteger)objectIndex withObject:(id)anObject
-{
-  if(mutations   == 0UL)   { [NSException raise:NSInternalInconsistencyException format:@"*** -[%@ %@]: mutating method sent to immutable object", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; }
-  if(anObject    == NULL)  { [NSException raise:NSInvalidArgumentException       format:@"*** -[%@ %@]: attempt to insert nil",                    NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; }
-  if(objectIndex >= count) { [NSException raise:NSRangeException                 format:@"*** -[%@ %@]: index (%u) beyond bounds (%u)",          NSStringFromClass([self class]), NSStringFromSelector(_cmd), objectIndex, count]; }
-#ifdef __clang_analyzer__
-  [anObject retain]; // Stupid clang analyzer...  Issue #19.
-#else
-  anObject = [anObject retain];
-#endif
-  _CDVJKArrayReplaceObjectAtIndexWithObject(self, objectIndex, anObject);
-  mutations = (mutations == NSUIntegerMax) ? 1UL : mutations + 1UL;
-}
-
-- (id)copyWithZone:(NSZone *)zone
-{
-  NSParameterAssert((objects != NULL) && (count <= capacity));
-  return((mutations == 0UL) ? [self retain] : [(NSArray *)[NSArray allocWithZone:zone] initWithObjects:objects count:count]);
-}
-
-- (id)mutableCopyWithZone:(NSZone *)zone
-{
-  NSParameterAssert((objects != NULL) && (count <= capacity));
-  return([(NSMutableArray *)[NSMutableArray allocWithZone:zone] initWithObjects:objects count:count]);
-}
-
-@end
-
-
-#pragma mark -
-@interface CDVJKDictionaryEnumerator : NSEnumerator {
-  id         collection;
-  NSUInteger nextObject;
-}
-
-- (id)initWithJKDictionary:(CDVJKDictionary *)initDictionary;
-- (NSArray *)allObjects;
-- (id)nextObject;
-
-@end
-
-@implementation CDVJKDictionaryEnumerator
-
-- (id)initWithJKDictionary:(CDVJKDictionary *)initDictionary
-{
-  NSParameterAssert(initDictionary != NULL);
-  if((self = [super init]) == NULL) { return(NULL); }
-  if((collection = (id)CFRetain(initDictionary)) == NULL) { [self autorelease]; return(NULL); }
-  return(self);
-}
-
-- (void)dealloc
-{
-  if(collection != NULL) { CFRelease(collection); collection = NULL; }
-  [super dealloc];
-}
-
-- (NSArray *)allObjects
-{
-  NSParameterAssert(collection != NULL);
-  NSUInteger count = [collection count], atObject = 0UL;
-  id         objects[count];
-
-  while((objects[atObject] = [self nextObject]) != NULL) { NSParameterAssert(atObject < count); atObject++; }
-
-  return([NSArray arrayWithObjects:objects count:atObject]);
-}
-
-- (id)nextObject
-{
-  NSParameterAssert((collection != NULL) && (_CDVJKDictionaryHashEntry(collection) != NULL));
-  CDVJKHashTableEntry *entry        = _CDVJKDictionaryHashEntry(collection);
-  NSUInteger        capacity     = _CDVJKDictionaryCapacity(collection);
-  id                returnObject = NULL;
-
-  if(entry != NULL) { while((nextObject < capacity) && ((returnObject = entry[nextObject++].key) == NULL)) { /* ... */ } }
-  
-  return(returnObject);
-}
-
-@end
-
-#pragma mark -
-@interface CDVJKDictionary : NSMutableDictionary <NSCopying, NSMutableCopying, NSFastEnumeration> {
-  NSUInteger count, capacity, mutations;
-  CDVJKHashTableEntry *entry;
-}
-@end
-
-@implementation CDVJKDictionary
-
-+ (id)allocWithZone:(NSZone *)zone
-{
-#pragma unused(zone)
-  [NSException raise:NSInvalidArgumentException format:@"*** - [%@ %@]: The %@ class is private to CDVJSONKit and should not be used in this fashion.", NSStringFromClass([self class]), NSStringFromSelector(_cmd), NSStringFromClass([self class])];
-  return(NULL);
-}
-
-// These values are taken from Core Foundation CF-550 CFBasicHash.m.  As a bonus, they align very well with our CDVJKHashTableEntry struct too.
-static const NSUInteger cdvjk_dictionaryCapacities[] = {
-  0UL, 3UL, 7UL, 13UL, 23UL, 41UL, 71UL, 127UL, 191UL, 251UL, 383UL, 631UL, 1087UL, 1723UL,
-  2803UL, 4523UL, 7351UL, 11959UL, 19447UL, 31231UL, 50683UL, 81919UL, 132607UL,
-  214519UL, 346607UL, 561109UL, 907759UL, 1468927UL, 2376191UL, 3845119UL,
-  6221311UL, 10066421UL, 16287743UL, 26354171UL, 42641881UL, 68996069UL,
-  111638519UL, 180634607UL, 292272623UL, 472907251UL
-};
-
-static NSUInteger _CDVJKDictionaryCapacityForCount(NSUInteger count) {
-  NSUInteger bottom = 0UL, top = sizeof(cdvjk_dictionaryCapacities) / sizeof(NSUInteger), mid = 0UL, tableSize = lround(floor((count) * 1.33));
-  while(top > bottom) { mid = (top + bottom) / 2UL; if(cdvjk_dictionaryCapacities[mid] < tableSize) { bottom = mid + 1UL; } else { top = mid; } }
-  return(cdvjk_dictionaryCapacities[bottom]);
-}
-
-static void _CDVJKDictionaryResizeIfNeccessary(CDVJKDictionary *dictionary) {
-  NSCParameterAssert((dictionary != NULL) && (dictionary->entry != NULL) && (dictionary->count <= dictionary->capacity));
-
-  NSUInteger capacityForCount = 0UL;
-  if(dictionary->capacity < (capacityForCount = _CDVJKDictionaryCapacityForCount(dictionary->count + 1UL))) { // resize
-    NSUInteger        oldCapacity = dictionary->capacity;
-#ifndef NS_BLOCK_ASSERTIONS
-    NSUInteger oldCount = dictionary->count;
-#endif
-    CDVJKHashTableEntry *oldEntry    = dictionary->entry;
-    if(CDVJK_EXPECT_F((dictionary->entry = (CDVJKHashTableEntry *)calloc(1UL, sizeof(CDVJKHashTableEntry) * capacityForCount)) == NULL)) { [NSException raise:NSMallocException format:@"Unable to allocate memory for hash table."]; }
-    dictionary->capacity = capacityForCount;
-    dictionary->count    = 0UL;
-    
-    NSUInteger idx = 0UL;
-    for(idx = 0UL; idx < oldCapacity; idx++) { if(oldEntry[idx].key != NULL) { _CDVJKDictionaryAddObject(dictionary, oldEntry[idx].keyHash, oldEntry[idx].key, oldEntry[idx].object); oldEntry[idx].keyHash = 0UL; oldEntry[idx].key = NULL; oldEntry[idx].object = NULL; } }
-    NSCParameterAssert((oldCount == dictionary->count));
-    free(oldEntry); oldEntry = NULL;
-  }
-}
-
-static CDVJKDictionary *_CDVJKDictionaryCreate(id *keys, NSUInteger *keyHashes, id *objects, NSUInteger count, BOOL mutableCollection) {
-  NSCParameterAssert((keys != NULL) && (keyHashes != NULL) && (objects != NULL) && (_CDVJKDictionaryClass != NULL) && (_CDVJKDictionaryInstanceSize > 0UL));
-  CDVJKDictionary *dictionary = NULL;
-  if(CDVJK_EXPECT_T((dictionary = (CDVJKDictionary *)calloc(1UL, _CDVJKDictionaryInstanceSize)) != NULL)) { // Directly allocate the CDVJKDictionary instance via calloc.
-    dictionary->isa      = _CDVJKDictionaryClass;
-    if((dictionary = [dictionary init]) == NULL) { return(NULL); }
-    dictionary->capacity = _CDVJKDictionaryCapacityForCount(count);
-    dictionary->count    = 0UL;
-    
-    if(CDVJK_EXPECT_F((dictionary->entry = (CDVJKHashTableEntry *)calloc(1UL, sizeof(CDVJKHashTableEntry) * dictionary->capacity)) == NULL)) { [dictionary autorelease]; return(NULL); }
-
-    NSUInteger idx = 0UL;
-    for(idx = 0UL; idx < count; idx++) { _CDVJKDictionaryAddObject(dictionary, keyHashes[idx], keys[idx], objects[idx]); }
-
-    dictionary->mutations = (mutableCollection == NO) ? 0UL : 1UL;
-  }
-  return(dictionary);
-}
-
-- (void)dealloc
-{
-  if(CDVJK_EXPECT_T(entry != NULL)) {
-    NSUInteger atEntry = 0UL;
-    for(atEntry = 0UL; atEntry < capacity; atEntry++) {
-      if(CDVJK_EXPECT_T(entry[atEntry].key    != NULL)) { CFRelease(entry[atEntry].key);    entry[atEntry].key    = NULL; }
-      if(CDVJK_EXPECT_T(entry[atEntry].object != NULL)) { CFRelease(entry[atEntry].object); entry[atEntry].object = NULL; }
-    }
-  
-    free(entry); entry = NULL;
-  }
-
-  [super dealloc];
-}
-
-static CDVJKHashTableEntry *_CDVJKDictionaryHashEntry(CDVJKDictionary *dictionary) {
-  NSCParameterAssert(dictionary != NULL);
-  return(dictionary->entry);
-}
-
-static NSUInteger _CDVJKDictionaryCapacity(CDVJKDictionary *dictionary) {
-  NSCParameterAssert(dictionary != NULL);
-  return(dictionary->capacity);
-}
-
-static void _CDVJKDictionaryRemoveObjectWithEntry(CDVJKDictionary *dictionary, CDVJKHashTableEntry *entry) {
-  NSCParameterAssert((dictionary != NULL) && (entry != NULL) && (entry->key != NULL) && (entry->object != NULL) && (dictionary->count > 0UL) && (dictionary->count <= dictionary->capacity));
-  CFRelease(entry->key);    entry->key    = NULL;
-  CFRelease(entry->object); entry->object = NULL;
-  entry->keyHash = 0UL;
-  dictionary->count--;
-  // In order for certain invariants that are used to speed up the search for a particular key, we need to "re-add" all the entries in the hash table following this entry until we hit a NULL entry.
-  NSUInteger removeIdx = entry - dictionary->entry, idx = 0UL;
-  NSCParameterAssert((removeIdx < dictionary->capacity));
-  for(idx = 0UL; idx < dictionary->capacity; idx++) {
-    NSUInteger entryIdx = (removeIdx + idx + 1UL) % dictionary->capacity;
-    CDVJKHashTableEntry *atEntry = &dictionary->entry[entryIdx];
-    if(atEntry->key == NULL) { break; }
-    NSUInteger keyHash = atEntry->keyHash;
-    id key = atEntry->key, object = atEntry->object;
-    NSCParameterAssert(object != NULL);
-    atEntry->keyHash = 0UL;
-    atEntry->key     = NULL;
-    atEntry->object  = NULL;
-    NSUInteger addKeyEntry = keyHash % dictionary->capacity, addIdx = 0UL;
-    for(addIdx = 0UL; addIdx < dictionary->capacity; addIdx++) {
-      CDVJKHashTableEntry *atAddEntry = &dictionary->entry[((addKeyEntry + addIdx) % dictionary->capacity)];
-      if(CDVJK_EXPECT_T(atAddEntry->key == NULL)) { NSCParameterAssert((atAddEntry->keyHash == 0UL) && (atAddEntry->object == NULL)); atAddEntry->key = key; atAddEntry->object = object; atAddEntry->keyHash = keyHash; break; }
-    }
-  }
-}
-
-static void _CDVJKDictionaryAddObject(CDVJKDictionary *dictionary, NSUInteger keyHash, id key, id object) {
-  NSCParameterAssert((dictionary != NULL) && (key != NULL) && (object != NULL) && (dictionary->count < dictionary->capacity) && (dictionary->entry != NULL));
-  NSUInteger keyEntry = keyHash % dictionary->capacity, idx = 0UL;
-  for(idx = 0UL; idx < dictionary->capacity; idx++) {
-    NSUInteger entryIdx = (keyEntry + idx) % dictionary->capacity;
-    CDVJKHashTableEntry *atEntry = &dictionary->entry[entryIdx];
-    if(CDVJK_EXPECT_F(atEntry->keyHash == keyHash) && CDVJK_EXPECT_T(atEntry->key != NULL) && (CDVJK_EXPECT_F(key == atEntry->key) || CDVJK_EXPECT_F(CFEqual(atEntry->key, key)))) { _CDVJKDictionaryRemoveObjectWithEntry(dictionary, atEntry); }
-    if(CDVJK_EXPECT_T(atEntry->key == NULL)) { NSCParameterAssert((atEntry->keyHash == 0UL) && (atEntry->object == NULL)); atEntry->key = key; atEntry->object = object; atEntry->keyHash = keyHash; dictionary->count++; return; }
-  }
-
-  // We should never get here.  If we do, we -release the key / object because it's our responsibility.
-  CFRelease(key);
-  CFRelease(object);
-}
-
-- (NSUInteger)count
-{
-  return(count);
-}
-
-static CDVJKHashTableEntry *_CDVJKDictionaryHashTableEntryForKey(CDVJKDictionary *dictionary, id aKey) {
-  NSCParameterAssert((dictionary != NULL) && (dictionary->entry != NULL) && (dictionary->count <= dictionary->capacity));
-  if((aKey == NULL) || (dictionary->capacity == 0UL)) { return(NULL); }
-  NSUInteger        keyHash = CFHash(aKey), keyEntry = (keyHash % dictionary->capacity), idx = 0UL;
-  CDVJKHashTableEntry *atEntry = NULL;
-  for(idx = 0UL; idx < dictionary->capacity; idx++) {
-    atEntry = &dictionary->entry[(keyEntry + idx) % dictionary->capacity];
-    if(CDVJK_EXPECT_T(atEntry->keyHash == keyHash) && CDVJK_EXPECT_T(atEntry->key != NULL) && ((atEntry->key == aKey) || CFEqual(atEntry->key, aKey))) { NSCParameterAssert(atEntry->object != NULL); return(atEntry); break; }
-    if(CDVJK_EXPECT_F(atEntry->key == NULL)) { NSCParameterAssert(atEntry->object == NULL); return(NULL); break; } // If the key was in the table, we would have found it by now.
-  }
-  return(NULL);
-}
-
-- (id)objectForKey:(id)aKey
-{
-  NSParameterAssert((entry != NULL) && (count <= capacity));
-  CDVJKHashTableEntry *entryForKey = _CDVJKDictionaryHashTableEntryForKey(self, aKey);
-  return((entryForKey != NULL) ? entryForKey->object : NULL);
-}
-
-- (void)getObjects:(id *)objects andKeys:(id *)keys
-{
-  NSParameterAssert((entry != NULL) && (count <= capacity));
-  NSUInteger atEntry = 0UL; NSUInteger arrayIdx = 0UL;
-  for(atEntry = 0UL; atEntry < capacity; atEntry++) {
-    if(CDVJK_EXPECT_T(entry[atEntry].key != NULL)) {
-      NSCParameterAssert((entry[atEntry].object != NULL) && (arrayIdx < count));
-      if(CDVJK_EXPECT_T(keys    != NULL)) { keys[arrayIdx]    = entry[atEntry].key;    }
-      if(CDVJK_EXPECT_T(objects != NULL)) { objects[arrayIdx] = entry[atEntry].object; }
-      arrayIdx++;
-    }
-  }
-}
-
-- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len
-{
-  NSParameterAssert((state != NULL) && (stackbuf != NULL) && (len > 0UL) && (entry != NULL) && (count <= capacity));
-  if(CDVJK_EXPECT_F(state->state == 0UL))      { state->mutationsPtr = (unsigned long *)&mutations; state->itemsPtr = stackbuf; }
-  if(CDVJK_EXPECT_F(state->state >= capacity)) { return(0UL); }
-  
-  NSUInteger enumeratedCount  = 0UL;
-  while(CDVJK_EXPECT_T(enumeratedCount < len) && CDVJK_EXPECT_T(state->state < capacity)) { if(CDVJK_EXPECT_T(entry[state->state].key != NULL)) { stackbuf[enumeratedCount++] = entry[state->state].key; } state->state++; }
-    
-  return(enumeratedCount);
-}
-
-- (NSEnumerator *)keyEnumerator
-{
-  return([[[CDVJKDictionaryEnumerator alloc] initWithJKDictionary:self] autorelease]);
-}
-
-- (void)setObject:(id)anObject forKey:(id)aKey
-{
-  if(mutations == 0UL)  { [NSException raise:NSInternalInconsistencyException format:@"*** -[%@ %@]: mutating method sent to immutable object", NSStringFromClass([self class]), NSStringFromSelector(_cmd)];       }
-  if(aKey      == NULL) { [NSException raise:NSInvalidArgumentException       format:@"*** -[%@ %@]: attempt to insert nil key",                NSStringFromClass([self class]), NSStringFromSelector(_cmd)];       }
-  if(anObject  == NULL) { [NSException raise:NSInvalidArgumentException       format:@"*** -[%@ %@]: attempt to insert nil value (key: %@)",    NSStringFromClass([self class]), NSStringFromSelector(_cmd), aKey]; }
-  
-  _CDVJKDictionaryResizeIfNeccessary(self);
-#ifndef __clang_analyzer__
-  aKey     = [aKey     copy];   // Why on earth would clang complain that this -copy "might leak", 
-  anObject = [anObject retain]; // but this -retain doesn't!?
-#endif // __clang_analyzer__
-  _CDVJKDictionaryAddObject(self, CFHash(aKey), aKey, anObject);
-  mutations = (mutations == NSUIntegerMax) ? 1UL : mutations + 1UL;
-}
-
-- (void)removeObjectForKey:(id)aKey
-{
-  if(mutations == 0UL)  { [NSException raise:NSInternalInconsistencyException format:@"*** -[%@ %@]: mutating method sent to immutable object", NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; }
-  if(aKey      == NULL) { [NSException raise:NSInvalidArgumentException       format:@"*** -[%@ %@]: attempt to remove nil key",                NSStringFromClass([self class]), NSStringFromSelector(_cmd)]; }
-  CDVJKHashTableEntry *entryForKey = _CDVJKDictionaryHashTableEntryForKey(self, aKey);
-  if(entryForKey != NULL) {
-    _CDVJKDictionaryRemoveObjectWithEntry(self, entryForKey);
-    mutations = (mutations == NSUIntegerMax) ? 1UL : mutations + 1UL;
-  }
-}
-
-- (id)copyWithZone:(NSZone *)zone
-{
-  NSParameterAssert((entry != NULL) && (count <= capacity));
-  return((mutations == 0UL) ? [self retain] : [[NSDictionary allocWithZone:zone] initWithDictionary:self]);
-}
-
-- (id)mutableCopyWithZone:(NSZone *)zone
-{
-  NSParameterAssert((entry != NULL) && (count <= capacity));
-  return([[NSMutableDictionary allocWithZone:zone] initWithDictionary:self]);
-}
-
-@end
-
-
-
-#pragma mark -
-
-CDVJK_STATIC_INLINE size_t cdvjk_min(size_t a, size_t b) { return((a < b) ? a : b); }
-CDVJK_STATIC_INLINE size_t cdvjk_max(size_t a, size_t b) { return((a > b) ? a : b); }
-
-CDVJK_STATIC_INLINE CDVJKHash cdvcalculateHash(CDVJKHash currentHash, unsigned char c) { return(((currentHash << 5) + currentHash) + c); }
-
-static void cdvjk_error(CDVJKParseState *parseState, NSString *format, ...) {
-  NSCParameterAssert((parseState != NULL) && (format != NULL));
-
-  va_list varArgsList;
-  va_start(varArgsList, format);
-  NSString *formatString = [[[NSString alloc] initWithFormat:format arguments:varArgsList] autorelease];
-  va_end(varArgsList);
-
-#if 0
-  const unsigned char *lineStart      = parseState->stringBuffer.bytes.ptr + parseState->lineStartIndex;
-  const unsigned char *lineEnd        = lineStart;
-  const unsigned char *atCharacterPtr = NULL;
-
-  for(atCharacterPtr = lineStart; atCharacterPtr < CDVJK_END_STRING_PTR(parseState); atCharacterPtr++) { lineEnd = atCharacterPtr; if(cdvjk_parse_is_newline(parseState, atCharacterPtr)) { break; } }
-
-  NSString *lineString = @"", *carretString = @"";
-  if(lineStart < CDVJK_END_STRING_PTR(parseState)) {
-    lineString   = [[[NSString alloc] initWithBytes:lineStart length:(lineEnd - lineStart) encoding:NSUTF8StringEncoding] autorelease];
-    carretString = [NSString stringWithFormat:@"%*.*s^", (int)(parseState->atIndex - parseState->lineStartIndex), (int)(parseState->atIndex - parseState->lineStartIndex), " "];
-  }
-#endif
-
-  if(parseState->error == NULL) {
-    parseState->error = [NSError errorWithDomain:@"CDVJKErrorDomain" code:-1L userInfo:
-                                   [NSDictionary dictionaryWithObjectsAndKeys:
-                                                                              formatString,                                             NSLocalizedDescriptionKey,
-                                                                              [NSNumber numberWithUnsignedLong:parseState->atIndex],    @"CDVJKAtIndexKey",
-                                                                              [NSNumber numberWithUnsignedLong:parseState->lineNumber], @"CDVJKLineNumberKey",
-                                                 //lineString,   @"CDVJKErrorLine0Key",
-                                                 //carretString, @"CDVJKErrorLine1Key",
-                                                                              NULL]];
-  }
-}
-
-#pragma mark -
-#pragma mark Buffer and Object Stack management functions
-
-static void cdvjk_managedBuffer_release(CDVJKManagedBuffer *managedBuffer) {
-  if((managedBuffer->flags & CDVJKManagedBufferMustFree)) {
-    if(managedBuffer->bytes.ptr != NULL) { free(managedBuffer->bytes.ptr); managedBuffer->bytes.ptr = NULL; }
-    managedBuffer->flags &= ~CDVJKManagedBufferMustFree;
-  }
-
-  managedBuffer->bytes.ptr     = NULL;
-  managedBuffer->bytes.length  = 0UL;
-  managedBuffer->flags        &= ~CDVJKManagedBufferLocationMask;
-}
-
-static void cdvjk_managedBuffer_setToStackBuffer(CDVJKManagedBuffer *managedBuffer, unsigned char *ptr, size_t length) {
-  cdvjk_managedBuffer_release(managedBuffer);
-  managedBuffer->bytes.ptr     = ptr;
-  managedBuffer->bytes.length  = length;
-  managedBuffer->flags         = (managedBuffer->flags & ~CDVJKManagedBufferLocationMask) | CDVJKManagedBufferOnStack;
-}
-
-static unsigned char *cdvjk_managedBuffer_resize(CDVJKManagedBuffer *managedBuffer, size_t newSize) {
-  size_t roundedUpNewSize = newSize;
-
-  if(managedBuffer->roundSizeUpToMultipleOf > 0UL) { roundedUpNewSize = newSize + ((managedBuffer->roundSizeUpToMultipleOf - (newSize % managedBuffer->roundSizeUpToMultipleOf)) % managedBuffer->roundSizeUpToMultipleOf); }
-
-  if((roundedUpNewSize != managedBuffer->bytes.length) && (roundedUpNewSize > managedBuffer->bytes.length)) {
-    if((managedBuffer->flags & CDVJKManagedBufferLocationMask) == CDVJKManagedBufferOnStack) {
-      NSCParameterAssert((managedBuffer->flags & CDVJKManagedBufferMustFree) == 0);
-      unsigned char *newBuffer = NULL, *oldBuffer = managedBuffer->bytes.ptr;
-      
-      if((newBuffer = (unsigned char *)malloc(roundedUpNewSize)) == NULL) { return(NULL); }
-      memcpy(newBuffer, oldBuffer, cdvjk_min(managedBuffer->bytes.length, roundedUpNewSize));
-      managedBuffer->flags        = (managedBuffer->flags & ~CDVJKManagedBufferLocationMask) | (CDVJKManagedBufferOnHeap | CDVJKManagedBufferMustFree);
-      managedBuffer->bytes.ptr    = newBuffer;
-      managedBuffer->bytes.length = roundedUpNewSize;
-    } else {
-      NSCParameterAssert(((managedBuffer->flags & CDVJKManagedBufferMustFree) != 0) && ((managedBuffer->flags & CDVJKManagedBufferLocationMask) == CDVJKManagedBufferOnHeap));
-      if((managedBuffer->bytes.ptr = (unsigned char *)reallocf(managedBuffer->bytes.ptr, roundedUpNewSize)) == NULL) { return(NULL); }
-      managedBuffer->bytes.length = roundedUpNewSize;
-    }
-  }
-
-  return(managedBuffer->bytes.ptr);
-}
-
-
-
-static void cdvjk_objectStack_release(CDVJKObjectStack *objectStack) {
-  NSCParameterAssert(objectStack != NULL);
-
-  NSCParameterAssert(objectStack->index <= objectStack->count);
-  size_t atIndex = 0UL;
-  for(atIndex = 0UL; atIndex < objectStack->index; atIndex++) {
-    if(objectStack->objects[atIndex] != NULL) { CFRelease(objectStack->objects[atIndex]); objectStack->objects[atIndex] = NULL; }
-    if(objectStack->keys[atIndex]    != NULL) { CFRelease(objectStack->keys[atIndex]);    objectStack->keys[atIndex]    = NULL; }
-  }
-  objectStack->index = 0UL;
-
-  if(objectStack->flags & CDVJKObjectStackMustFree) {
-    NSCParameterAssert((objectStack->flags & CDVJKObjectStackLocationMask) == CDVJKObjectStackOnHeap);
-    if(objectStack->objects  != NULL) { free(objectStack->objects);  objectStack->objects  = NULL; }
-    if(objectStack->keys     != NULL) { free(objectStack->keys);     objectStack->keys     = NULL; }
-    if(objectStack->cfHashes != NULL) { free(objectStack->cfHashes); objectStack->cfHashes = NULL; }
-    objectStack->flags &= ~CDVJKObjectStackMustFree;
-  }
-
-  objectStack->objects  = NULL;
-  objectStack->keys     = NULL;
-  objectStack->cfHashes = NULL;
-
-  objectStack->count    = 0UL;
-  objectStack->flags   &= ~CDVJKObjectStackLocationMask;
-}
-
-static void cdvjk_objectStack_setToStackBuffer(CDVJKObjectStack *objectStack, void **objects, void **keys, CFHashCode *cfHashes, size_t count) {
-  NSCParameterAssert((objectStack != NULL) && (objects != NULL) && (keys != NULL) && (cfHashes != NULL) && (count > 0UL));
-  cdvjk_objectStack_release(objectStack);
-  objectStack->objects  = objects;
-  objectStack->keys     = keys;
-  objectStack->cfHashes = cfHashes;
-  objectStack->count    = count;
-  objectStack->flags    = (objectStack->flags & ~CDVJKObjectStackLocationMask) | CDVJKObjectStackOnStack;
-#ifndef NS_BLOCK_ASSERTIONS
-  size_t idx;
-  for(idx = 0UL; idx < objectStack->count; idx++) { objectStack->objects[idx] = NULL; objectStack->keys[idx] = NULL; objectStack->cfHashes[idx] = 0UL; }
-#endif
-}
-
-static int cdvjk_objectStack_resize(CDVJKObjectStack *objectStack, size_t newCount) {
-  size_t roundedUpNewCount = newCount;
-  int    returnCode = 0;
-
-  void       **newObjects  = NULL, **newKeys = NULL;
-  CFHashCode  *newCFHashes = NULL;
-
-  if(objectStack->roundSizeUpToMultipleOf > 0UL) { roundedUpNewCount = newCount + ((objectStack->roundSizeUpToMultipleOf - (newCount % objectStack->roundSizeUpToMultipleOf)) % objectStack->roundSizeUpToMultipleOf); }
-
-  if((roundedUpNewCount != objectStack->count) && (roundedUpNewCount > objectStack->count)) {
-    if((objectStack->flags & CDVJKObjectStackLocationMask) == CDVJKObjectStackOnStack) {
-      NSCParameterAssert((objectStack->flags & CDVJKObjectStackMustFree) == 0);
-
-      if((newObjects  = (void **     )calloc(1UL, roundedUpNewCount * sizeof(void *    ))) == NULL) { returnCode = 1; goto errorExit; }
-      memcpy(newObjects, objectStack->objects,   cdvjk_min(objectStack->count, roundedUpNewCount) * sizeof(void *));
-      if((newKeys     = (void **     )calloc(1UL, roundedUpNewCount * sizeof(void *    ))) == NULL) { returnCode = 1; goto errorExit; }
-      memcpy(newKeys,     objectStack->keys,     cdvjk_min(objectStack->count, roundedUpNewCount) * sizeof(void *));
-
-      if((newCFHashes = (CFHashCode *)calloc(1UL, roundedUpNewCount * sizeof(CFHashCode))) == NULL) { returnCode = 1; goto errorExit; }
-      memcpy(newCFHashes, objectStack->cfHashes, cdvjk_min(objectStack->count, roundedUpNewCount) * sizeof(CFHashCode));
-
-      objectStack->flags    = (objectStack->flags & ~CDVJKObjectStackLocationMask) | (CDVJKObjectStackOnHeap | CDVJKObjectStackMustFree);
-      objectStack->objects  = newObjects;  newObjects  = NULL;
-      objectStack->keys     = newKeys;     newKeys     = NULL;
-      objectStack->cfHashes = newCFHashes; newCFHashes = NULL;
-      objectStack->count    = roundedUpNewCount;
-    } else {
-      NSCParameterAssert(((objectStack->flags & CDVJKObjectStackMustFree) != 0) && ((objectStack->flags & CDVJKObjectStackLocationMask) == CDVJKObjectStackOnHeap));
-      if((newObjects  = (void  **    )realloc(objectStack->objects,  roundedUpNewCount * sizeof(void *    ))) != NULL) { objectStack->objects  = newObjects;  newObjects  = NULL; } else { returnCode = 1; goto errorExit; }
-      if((newKeys     = (void  **    )realloc(objectStack->keys,     roundedUpNewCount * sizeof(void *    ))) != NULL) { objectStack->keys     = newKeys;     newKeys     = NULL; } else { returnCode = 1; goto errorExit; }
-      if((newCFHashes = (CFHashCode *)realloc(objectStack->cfHashes, roundedUpNewCount * sizeof(CFHashCode))) != NULL) { objectStack->cfHashes = newCFHashes; newCFHashes = NULL; } else { returnCode = 1; goto errorExit; }
-
-#ifndef NS_BLOCK_ASSERTIONS
-      size_t idx;
-      for(idx = objectStack->count; idx < roundedUpNewCount; idx++) { objectStack->objects[idx] = NULL; objectStack->keys[idx] = NULL; objectStack->cfHashes[idx] = 0UL; }
-#endif
-      objectStack->count = roundedUpNewCount;
-    }
-  }
-
- errorExit:
-  if(newObjects  != NULL) { free(newObjects);  newObjects  = NULL; }
-  if(newKeys     != NULL) { free(newKeys);     newKeys     = NULL; }
-  if(newCFHashes != NULL) { free(newCFHashes); newCFHashes = NULL; }
-
-  return(returnCode);
-}
-
-////////////
-#pragma mark -
-#pragma mark Unicode related functions
-
-CDVJK_STATIC_INLINE CDV_ConversionResult cdvisValidCodePoint(UTF32 *u32CodePoint) {
-  CDV_ConversionResult result = conversionOK;
-  UTF32            ch     = *u32CodePoint;
-
-  if(CDVJK_EXPECT_F(ch >= CDV_UNI_SUR_HIGH_START) && (CDVJK_EXPECT_T(ch <= CDV_UNI_SUR_LOW_END)))                                                        { result = sourceIllegal; ch = CDV_UNI_REPLACEMENT_CHAR; goto finished; }
-  if(CDVJK_EXPECT_F(ch >= 0xFDD0U) && (CDVJK_EXPECT_F(ch <= 0xFDEFU) || CDVJK_EXPECT_F((ch & 0xFFFEU) == 0xFFFEU)) && CDVJK_EXPECT_T(ch <= 0x10FFFFU)) { result = sourceIllegal; ch = CDV_UNI_REPLACEMENT_CHAR; goto finished; }
-  if(CDVJK_EXPECT_F(ch == 0U))                                                                                                                { result = sourceIllegal; ch = CDV_UNI_REPLACEMENT_CHAR; goto finished; }
-
- finished:
-  *u32CodePoint = ch;
-  return(result);
-}
-
-
-static int cdvisLegalUTF8(const UTF8 *source, size_t length) {
-  const UTF8 *srcptr = source + length;
-  UTF8 a;
-
-  switch(length) {
-    default: return(0); // Everything else falls through when "true"...
-    case 4: if(CDVJK_EXPECT_F(((a = (*--srcptr)) < 0x80) || (a > 0xBF))) { return(0); }
-    case 3: if(CDVJK_EXPECT_F(((a = (*--srcptr)) < 0x80) || (a > 0xBF))) { return(0); }
-    case 2: if(CDVJK_EXPECT_F( (a = (*--srcptr)) > 0xBF               )) { return(0); }
-      
-      switch(*source) { // no fall-through in this inner switch
-        case 0xE0: if(CDVJK_EXPECT_F(a < 0xA0)) { return(0); } break;
-        case 0xED: if(CDVJK_EXPECT_F(a > 0x9F)) { return(0); } break;
-        case 0xF0: if(CDVJK_EXPECT_F(a < 0x90)) { return(0); } break;
-        case 0xF4: if(CDVJK_EXPECT_F(a > 0x8F)) { return(0); } break;
-        default:   if(CDVJK_EXPECT_F(a < 0x80)) { return(0); }
-      }
-      
-    case 1: if(CDVJK_EXPECT_F((CDVJK_EXPECT_T(*source < 0xC2)) && CDVJK_EXPECT_F(*source >= 0x80))) { return(0); }
-  }
-
-  if(CDVJK_EXPECT_F(*source > 0xF4)) { return(0); }
-
-  return(1);
-}
-
-static CDV_ConversionResult cdvConvertSingleCodePointInUTF8(const UTF8 *sourceStart, const UTF8 *sourceEnd, UTF8 const **nextUTF8, UTF32 *convertedUTF32) {
-  CDV_ConversionResult result = conversionOK;
-  const UTF8 *source = sourceStart;
-  UTF32 ch = 0UL;
-
-#if !defined(CDVJK_FAST_TRAILING_BYTES)
-  unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
-#else
-  unsigned short extraBytesToRead = __builtin_clz(((*source)^0xff) << 25);
-#endif
-
-  if(CDVJK_EXPECT_F((source + extraBytesToRead + 1) > sourceEnd) || CDVJK_EXPECT_F(!cdvisLegalUTF8(source, extraBytesToRead + 1))) {
-    source++;
-    while((source < sourceEnd) && (((*source) & 0xc0) == 0x80) && ((source - sourceStart) < (extraBytesToRead + 1))) { source++; } 
-    NSCParameterAssert(source <= sourceEnd);
-    result = ((source < sourceEnd) && (((*source) & 0xc0) != 0x80)) ? sourceIllegal : ((sourceStart + extraBytesToRead + 1) > sourceEnd) ? sourceExhausted : sourceIllegal;
-    ch = CDV_UNI_REPLACEMENT_CHAR;
-    goto finished;
-  }
-
-  switch(extraBytesToRead) { // The cases all fall through.
-    case 5: ch += *source++; ch <<= 6;
-    case 4: ch += *source++; ch <<= 6;
-    case 3: ch += *source++; ch <<= 6;
-    case 2: ch += *source++; ch <<= 6;
-    case 1: ch += *source++; ch <<= 6;
-    case 0: ch += *source++;
-  }
-  ch -= offsetsFromUTF8[extraBytesToRead];
-
-  result = cdvisValidCodePoint(&ch);
-  
- finished:
-  *nextUTF8       = source;
-  *convertedUTF32 = ch;
-  
-  return(result);
-}
-
-
-static CDV_ConversionResult cdvConvertUTF32toUTF8 (UTF32 u32CodePoint, UTF8 **targetStart, UTF8 *targetEnd) {
-  const UTF32       byteMask     = 0xBF, byteMark = 0x80;
-  CDV_ConversionResult  result       = conversionOK;
-  UTF8             *target       = *targetStart;
-  UTF32             ch           = u32CodePoint;
-  unsigned short    bytesToWrite = 0;
-
-  result = cdvisValidCodePoint(&ch);
-
-  // Figure out how many bytes the result will require. Turn any illegally large UTF32 things (> Plane 17) into replacement chars.
-       if(ch < (UTF32)0x80)          { bytesToWrite = 1; }
-  else if(ch < (UTF32)0x800)         { bytesToWrite = 2; }
-  else if(ch < (UTF32)0x10000)       { bytesToWrite = 3; }
-  else if(ch <= CDV_UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; }
-  else {                               bytesToWrite = 3; ch = CDV_UNI_REPLACEMENT_CHAR; result = sourceIllegal; }
-        
-  target += bytesToWrite;
-  if (target > targetEnd) { target -= bytesToWrite; result = targetExhausted; goto finished; }
-
-  switch (bytesToWrite) { // note: everything falls through.
-    case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
-    case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
-    case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6;
-    case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]);
-  }
-
-  target += bytesToWrite;
-
- finished:
-  *targetStart = target;
-  return(result);
-}
-
-CDVJK_STATIC_INLINE int cdvjk_string_add_unicodeCodePoint(CDVJKParseState *parseState, uint32_t unicodeCodePoint, size_t *tokenBufferIdx, CDVJKHash *stringHash) {
-  UTF8             *u8s = &parseState->token.tokenBuffer.bytes.ptr[*tokenBufferIdx];
-  CDV_ConversionResult  result;
-
-  if((result = cdvConvertUTF32toUTF8(unicodeCodePoint, &u8s, (parseState->token.tokenBuffer.bytes.ptr + parseState->token.tokenBuffer.bytes.length))) != conversionOK) { if(result == targetExhausted) { return(1); } }
-  size_t utf8len = u8s - &parseState->token.tokenBuffer.bytes.ptr[*tokenBufferIdx], nextIdx = (*tokenBufferIdx) + utf8len;
-  
-  while(*tokenBufferIdx < nextIdx) { *stringHash = cdvcalculateHash(*stringHash, parseState->token.tokenBuffer.bytes.ptr[(*tokenBufferIdx)++]); }
-
-  return(0);
-}
-
-////////////
-#pragma mark -
-#pragma mark Decoding / parsing / deserializing functions
-
-static int cdvjk_parse_string(CDVJKParseState *parseState) {
-  NSCParameterAssert((parseState != NULL) && (CDVJK_AT_STRING_PTR(parseState) <= CDVJK_END_STRING_PTR(parseState)));
-  const unsigned char *stringStart       = CDVJK_AT_STRING_PTR(parseState) + 1;
-  const unsigned char *endOfBuffer       = CDVJK_END_STRING_PTR(parseState);
-  const unsigned char *atStringCharacter = stringStart;
-  unsigned char       *tokenBuffer       = parseState->token.tokenBuffer.bytes.ptr;
-  size_t               tokenStartIndex   = parseState->atIndex;
-  size_t               tokenBufferIdx    = 0UL;
-
-  int      onlySimpleString        = 1,  stringState     = CDVJSONStringStateStart;
-  uint16_t escapedUnicode1         = 0U, escapedUnicode2 = 0U;
-  uint32_t escapedUnicodeCodePoint = 0U;
-  CDVJKHash   stringHash              = CDVJK_HASH_INIT;
-    
-  while(1) {
-    unsigned long currentChar;
-
-    if(CDVJK_EXPECT_F(atStringCharacter == endOfBuffer)) { /* XXX Add error message */ stringState = CDVJSONStringStateError; goto finishedParsing; }
-    
-    if(CDVJK_EXPECT_F((currentChar = *atStringCharacter++) >= 0x80UL)) {
-      const unsigned char *nextValidCharacter = NULL;
-      UTF32                u32ch              = 0U;
-      CDV_ConversionResult     result;
-
-      if(CDVJK_EXPECT_F((result = cdvConvertSingleCodePointInUTF8(atStringCharacter - 1, endOfBuffer, (UTF8 const **)&nextValidCharacter, &u32ch)) != conversionOK)) { goto switchToSlowPath; }
-      stringHash = cdvcalculateHash(stringHash, currentChar);
-      while(atStringCharacter < nextValidCharacter) { NSCParameterAssert(CDVJK_AT_STRING_PTR(parseState) <= CDVJK_END_STRING_PTR(parseState)); stringHash = cdvcalculateHash(stringHash, *atStringCharacter++); }
-      continue;
-    } else {
-      if(CDVJK_EXPECT_F(currentChar == (unsigned long)'"')) { stringState = CDVJSONStringStateFinished; goto finishedParsing; }
-
-      if(CDVJK_EXPECT_F(currentChar == (unsigned long)'\\')) {
-      switchToSlowPath:
-        onlySimpleString = 0;
-        stringState      = CDVJSONStringStateParsing;
-        tokenBufferIdx   = (atStringCharacter - stringStart) - 1L;
-        if(CDVJK_EXPECT_F((tokenBufferIdx + 16UL) > parseState->token.tokenBuffer.bytes.length)) { if((tokenBuffer = cdvjk_managedBuffer_resize(&parseState->token.tokenBuffer, tokenBufferIdx + 1024UL)) == NULL) { cdvjk_error(parseState, @"Internal error: Unable to resize temporary buffer. %@ line #%ld", [NSString stringWithUTF8String:__FILE__], (long)__LINE__); stringState = CDVJSONStringStateError; goto finishedParsing; } }
-        memcpy(tokenBuffer, stringStart, tokenBufferIdx);
-        goto slowMatch;
-      }
-
-      if(CDVJK_EXPECT_F(currentChar < 0x20UL)) { cdvjk_error(parseState, @"Invalid character < 0x20 found in string: 0x%2.2x.", currentChar); stringState = CDVJSONStringStateError; goto finishedParsing; }
-
-      stringHash = cdvcalculateHash(stringHash, currentChar);
-    }
-  }
-
- slowMatch:
-
-  for(atStringCharacter = (stringStart + ((atStringCharacter - stringStart) - 1L)); (atStringCharacter < endOfBuffer) && (tokenBufferIdx < parseState->token.tokenBuffer.bytes.length); atStringCharacter++) {
-    if((tokenBufferIdx + 16UL) > parseState->token.tokenBuffer.bytes.length) { if((tokenBuffer = cdvjk_managedBuffer_resize(&parseState->token.tokenBuffer, tokenBufferIdx + 1024UL)) == NULL) { cdvjk_error(parseState, @"Internal error: Unable to resize temporary buffer. %@ line #%ld", [NSString stringWithUTF8String:__FILE__], (long)__LINE__); stringState = CDVJSONStringStateError; goto finishedParsing; } }
-
-    NSCParameterAssert(tokenBufferIdx < parseState->token.tokenBuffer.bytes.length);
-
-    unsigned long currentChar = (*atStringCharacter), escapedChar;
-
-    if(CDVJK_EXPECT_T(stringState == CDVJSONStringStateParsing)) {
-      if(CDVJK_EXPECT_T(currentChar >= 0x20UL)) {
-        if(CDVJK_EXPECT_T(currentChar < (unsigned long)0x80)) { // Not a UTF8 sequence
-          if(CDVJK_EXPECT_F(currentChar == (unsigned long)'"'))  { stringState = CDVJSONStringStateFinished; atStringCharacter++; goto finishedParsing; }
-          if(CDVJK_EXPECT_F(currentChar == (unsigned long)'\\')) { stringState = CDVJSONStringStateEscape; continue; }
-          stringHash = cdvcalculateHash(stringHash, currentChar);
-          tokenBuffer[tokenBufferIdx++] = currentChar;
-          continue;
-        } else { // UTF8 sequence
-          const unsigned char *nextValidCharacter = NULL;
-          UTF32                u32ch              = 0U;
-          CDV_ConversionResult     result;
-          
-          if(CDVJK_EXPECT_F((result = cdvConvertSingleCodePointInUTF8(atStringCharacter, endOfBuffer, (UTF8 const **)&nextValidCharacter, &u32ch)) != conversionOK)) {
-            if((result == sourceIllegal) && ((parseState->parseOptionFlags & CDVJKParseOptionLooseUnicode) == 0)) { cdvjk_error(parseState, @"Illegal UTF8 sequence found in \"\" string.");              stringState = CDVJSONStringStateError; goto finishedParsing; }
-            if(result == sourceExhausted)                                                                      { cdvjk_error(parseState, @"End of buffer reached while parsing UTF8 in \"\" string."); stringState = CDVJSONStringStateError; goto finishedParsing; }
-            if(cdvjk_string_add_unicodeCodePoint(parseState, u32ch, &tokenBufferIdx, &stringHash))                { cdvjk_error(parseState, @"Internal error: Unable to add UTF8 sequence to internal string buffer. %@ line #%ld", [NSString stringWithUTF8String:__FILE__], (long)__LINE__); stringState = CDVJSONStringStateError; goto finishedParsing; }
-            atStringCharacter = nextValidCharacter - 1;
-            continue;
-          } else {
-            while(atStringCharacter < nextValidCharacter) { tokenBuffer[tokenBufferIdx++] = *atStringCharacter; stringHash = cdvcalculateHash(stringHash, *atStringCharacter++); }
-            atStringCharacter--;
-            continue;
-          }
-        }
-      } else { // currentChar < 0x20
-        cdvjk_error(parseState, @"Invalid character < 0x20 found in string: 0x%2.2x.", currentChar); stringState = CDVJSONStringStateError; goto finishedParsing;
-      }
-
-    } else { // stringState != CDVJSONStringStateParsing
-      int isSurrogate = 1;
-
-      switch(stringState) {
-        case CDVJSONStringStateEscape:
-          switch(currentChar) {
-            case 'u': escapedUnicode1 = 0U; escapedUnicode2 = 0U; escapedUnicodeCodePoint = 0U; stringState = CDVJSONStringStateEscapedUnicode1; break;
-
-            case 'b':  escapedChar = '\b'; goto parsedEscapedChar;
-            case 'f':  escapedChar = '\f'; goto parsedEscapedChar;
-            case 'n':  escapedChar = '\n'; goto parsedEscapedChar;
-            case 'r':  escapedChar = '\r'; goto parsedEscapedChar;
-            case 't':  escapedChar = '\t'; goto parsedEscapedChar;
-            case '\\': escapedChar = '\\'; goto parsedEscapedChar;
-            case '/':  escapedChar = '/';  goto parsedEscapedChar;
-            case '"':  escapedChar = '"';  goto parsedEscapedChar;
-              
-            parsedEscapedChar:
-              stringState = CDVJSONStringStateParsing;
-              stringHash  = cdvcalculateHash(stringHash, escapedChar);
-              tokenBuffer[tokenBufferIdx++] = escapedChar;
-              break;
-              
-            default: cdvjk_error(parseState, @"Invalid escape sequence found in \"\" string."); stringState = CDVJSONStringStateError; goto finishedParsing; break;
-          }
-          break;
-
-        case CDVJSONStringStateEscapedUnicode1:
-        case CDVJSONStringStateEscapedUnicode2:
-        case CDVJSONStringStateEscapedUnicode3:
-        case CDVJSONStringStateEscapedUnicode4:           isSurrogate = 0;
-        case CDVJSONStringStateEscapedUnicodeSurrogate1:
-        case CDVJSONStringStateEscapedUnicodeSurrogate2:
-        case CDVJSONStringStateEscapedUnicodeSurrogate3:
-        case CDVJSONStringStateEscapedUnicodeSurrogate4:
-          {
-            uint16_t hexValue = 0U;
-
-            switch(currentChar) {
-              case '0' ... '9': hexValue =  currentChar - '0';        goto parsedHex;
-              case 'a' ... 'f': hexValue = (currentChar - 'a') + 10U; goto parsedHex;
-              case 'A' ... 'F': hexValue = (currentChar - 'A') + 10U; goto parsedHex;
-                
-              parsedHex:
-              if(!isSurrogate) { escapedUnicode1 = (escapedUnicode1 << 4) | hexValue; } else { escapedUnicode2 = (escapedUnicode2 << 4) | hexValue; }
-                
-              if(stringState == CDVJSONStringStateEscapedUnicode4) {
-                if(((escapedUnicode1 >= 0xD800U) && (escapedUnicode1 < 0xE000U))) {
-                  if((escapedUnicode1 >= 0xD800U) && (escapedUnicode1 < 0xDC00U)) { stringState = CDVJSONStringStateEscapedNeedEscapeForSurrogate; }
-                  else if((escapedUnicode1 >= 0xDC00U) && (escapedUnicode1 < 0xE000U)) { 
-                    if((parseState->parseOptionFlags & CDVJKParseOptionLooseUnicode)) { escapedUnicodeCodePoint = CDV_UNI_REPLACEMENT_CHAR; }
-                    else { cdvjk_error(parseState, @"Illegal \\u Unicode escape sequence."); stringState = CDVJSONStringStateError; goto finishedParsing; }
-                  }
-                }
-                else { escapedUnicodeCodePoint = escapedUnicode1; }
-              }
-
-              if(stringState == CDVJSONStringStateEscapedUnicodeSurrogate4) {
-                if((escapedUnicode2 < 0xdc00) || (escapedUnicode2 > 0xdfff)) {
-                  if((parseState->parseOptionFlags & CDVJKParseOptionLooseUnicode)) { escapedUnicodeCodePoint = CDV_UNI_REPLACEMENT_CHAR; }
-                  else { cdvjk_error(parseState, @"Illegal \\u Unicode escape sequence."); stringState = CDVJSONStringStateError; goto finishedParsing; }
-                }
-                else { escapedUnicodeCodePoint = ((escapedUnicode1 - 0xd800) * 0x400) + (escapedUnicode2 - 0xdc00) + 0x10000; }
-              }
-                
-              if((stringState == CDVJSONStringStateEscapedUnicode4) || (stringState == CDVJSONStringStateEscapedUnicodeSurrogate4)) { 
-                if((cdvisValidCodePoint(&escapedUnicodeCodePoint) == sourceIllegal) && ((parseState->parseOptionFlags & CDVJKParseOptionLooseUnicode) == 0)) { cdvjk_error(parseState, @"Illegal \\u Unicode escape sequence."); stringState = CDVJSONStringStateError; goto finishedParsing; }
-                stringState = CDVJSONStringStateParsing;
-                if(cdvjk_string_add_unicodeCodePoint(parseState, escapedUnicodeCodePoint, &tokenBufferIdx, &stringHash)) { cdvjk_error(parseState, @"Internal error: Unable to add UTF8 sequence to internal string buffer. %@ line #%ld", [NSString stringWithUTF8String:__FILE__], (long)__LINE__); stringState = CDVJSONStringStateError; goto finishedParsing; }
-              }
-              else if((stringState >= CDVJSONStringStateEscapedUnicode1) && (stringState <= CDVJSONStringStateEscapedUnicodeSurrogate4)) { stringState++; }
-              break;
-
-              default: cdvjk_error(parseState, @"Unexpected character found in \\u Unicode escape sequence.  Found '%c', expected [0-9a-fA-F].", currentChar); stringState = CDVJSONStringStateError; goto finishedParsing; break;
-            }
-          }
-          break;
-
-        case CDVJSONStringStateEscapedNeedEscapeForSurrogate:
-          if(currentChar == '\\') { stringState = CDVJSONStringStateEscapedNeedEscapedUForSurrogate; }
-          else { 
-            if((parseState->parseOptionFlags & CDVJKParseOptionLooseUnicode) == 0) { cdvjk_error(parseState, @"Required a second \\u Unicode escape sequence following a surrogate \\u Unicode escape sequence."); stringState = CDVJSONStringStateError; goto finishedParsing; }
-            else { stringState = CDVJSONStringStateParsing; atStringCharacter--;    if(cdvjk_string_add_unicodeCodePoint(parseState, CDV_UNI_REPLACEMENT_CHAR, &tokenBufferIdx, &stringHash)) { cdvjk_error(parseState, @"Internal error: Unable to add UTF8 sequence to internal string buffer. %@ line #%ld", [NSString stringWithUTF8String:__FILE__], (long)__LINE__); stringState = CDVJSONStringStateError; goto finishedParsing; } }
-          }
-          break;
-
-        case CDVJSONStringStateEscapedNeedEscapedUForSurrogate:
-          if(currentChar == 'u') { stringState = CDVJSONStringStateEscapedUnicodeSurrogate1; }
-          else { 
-            if((parseState->parseOptionFlags & CDVJKParseOptionLooseUnicode) == 0) { cdvjk_error(parseState, @"Required a second \\u Unicode escape sequence following a surrogate \\u Unicode escape sequence."); stringState = CDVJSONStringStateError; goto finishedParsing; }
-            else { stringState = CDVJSONStringStateParsing; atStringCharacter -= 2; if(cdvjk_string_add_unicodeCodePoint(parseState, CDV_UNI_REPLACEMENT_CHAR, &tokenBufferIdx, &stringHash)) { cdvjk_error(parseState, @"Internal error: Unable to add UTF8 sequence to internal string buffer. %@ line #%ld", [NSString stringWithUTF8String:__FILE__], (long)__LINE__); stringState = CDVJSONStringStateError; goto finishedParsing; } }
-          }
-          break;
-
-        default: cdvjk_error(parseState, @"Internal error: Unknown stringState. %@ line #%ld", [NSString stringWithUTF8String:__FILE__], (long)__LINE__); stringState = CDVJSONStringStateError; goto finishedParsing; break;
-      }
-    }
-  }
-
-finishedParsing:
-
-  if(CDVJK_EXPECT_T(stringState == CDVJSONStringStateFinished)) {
-    NSCParameterAssert((parseState->stringBuffer.bytes.ptr + tokenStartIndex) < atStringCharacter);
-
-    parseState->token.tokenPtrRange.ptr    = parseState->stringBuffer.bytes.ptr + tokenStartIndex;
-    parseState->token.tokenPtrRange.length = (atStringCharacter - parseState->token.tokenPtrRange.ptr);
-
-    if(CDVJK_EXPECT_T(onlySimpleString)) {
-      NSCParameterAssert(((parseState->token.tokenPtrRange.ptr + 1) < endOfBuffer) && (parseState->token.tokenPtrRange.length >= 2UL) && (((parseState->token.tokenPtrRange.ptr + 1) + (parseState->token.tokenPtrRange.length - 2)) < endOfBuffer));
-      parseState->token.value.ptrRange.ptr    = parseState->token.tokenPtrRange.ptr    + 1;
-      parseState->token.value.ptrRange.length = parseState->token.tokenPtrRange.length - 2UL;
-    } else {
-      parseState->token.value.ptrRange.ptr    = parseState->token.tokenBuffer.bytes.ptr;
-      parseState->token.value.ptrRange.length = tokenBufferIdx;
-    }
-    
-    parseState->token.value.hash = stringHash;
-    parseState->token.value.type = CDVJKValueTypeString;
-    parseState->atIndex          = (atStringCharacter - parseState->stringBuffer.bytes.ptr);
-  }
-
-  if(CDVJK_EXPECT_F(stringState != CDVJSONStringStateFinished)) { cdvjk_error(parseState, @"Invalid string."); }
-  return(CDVJK_EXPECT_T(stringState == CDVJSONStringStateFinished) ? 0 : 1);
-}
-
-static int cdvjk_parse_number(CDVJKParseState *parseState) {
-  NSCParameterAssert((parseState != NULL) && (CDVJK_AT_STRING_PTR(parseState) <= CDVJK_END_STRING_PTR(parseState)));
-  const unsigned char *numberStart       = CDVJK_AT_STRING_PTR(parseState);
-  const unsigned char *endOfBuffer       = CDVJK_END_STRING_PTR(parseState);
-  const unsigned char *atNumberCharacter = NULL;
-  int                  numberState       = CDVJSONNumberStateWholeNumberStart, isFloatingPoint = 0, isNegative = 0, backup = 0;
-  size_t               startingIndex     = parseState->atIndex;
-  
-  for(atNumberCharacter = numberStart; (CDVJK_EXPECT_T(atNumberCharacter < endOfBuffer)) && (CDVJK_EXPECT_T(!(CDVJK_EXPECT_F(numberState == CDVJSONNumberStateFinished) || CDVJK_EXPECT_F(numberState == CDVJSONNumberStateError)))); atNumberCharacter++) {
-    unsigned long currentChar = (unsigned long)(*atNumberCharacter), lowerCaseCC = currentChar | 0x20UL;
-    
-    switch(numberState) {
-      case CDVJSONNumberStateWholeNumberStart: if   (currentChar == '-')                                                                              { numberState = CDVJSONNumberStateWholeNumberMinus;      isNegative      = 1; break; }
-      case CDVJSONNumberStateWholeNumberMinus: if   (currentChar == '0')                                                                              { numberState = CDVJSONNumberStateWholeNumberZero;                            break; }
-                                       else if(  (currentChar >= '1') && (currentChar <= '9'))                                                     { numberState = CDVJSONNumberStateWholeNumber;                                break; }
-                                       else                                                     { /* XXX Add error message */                        numberState = CDVJSONNumberStateError;                                      break; }
-      case CDVJSONNumberStateExponentStart:    if(  (currentChar == '+') || (currentChar == '-'))                                                     { numberState = CDVJSONNumberStateExponentPlusMinus;                          break; }
-      case CDVJSONNumberStateFractionalNumberStart:
-      case CDVJSONNumberStateExponentPlusMinus:if(!((currentChar >= '0') && (currentChar <= '9'))) { /* XXX Add error message */                        numberState = CDVJSONNumberStateError;                                      break; }
-                                       else {                                              if(numberState == CDVJSONNumberStateFractionalNumberStart) { numberState = CDVJSONNumberStateFractionalNumber; }
-                                                                                           else                                                    { numberState = CDVJSONNumberStateExponent;         }                         break; }
-      case CDVJSONNumberStateWholeNumberZero:
-      case CDVJSONNumberStateWholeNumber:      if   (currentChar == '.')                                                                              { numberState = CDVJSONNumberStateFractionalNumberStart; isFloatingPoint = 1; break; }
-      case CDVJSONNumberStateFractionalNumber: if   (lowerCaseCC == 'e')                                                                              { numberState = CDVJSONNumberStateExponentStart;         isFloatingPoint = 1; break; }
-      case CDVJSONNumberStateExponent:         if(!((currentChar >= '0') && (currentChar <= '9')) || (numberState == CDVJSONNumberStateWholeNumberZero)) { numberState = CDVJSONNumberStateFinished;              backup          = 1; break; }
-        break;
-      default:                                                                                    /* XXX Add error message */                        numberState = CDVJSONNumberStateError;                                      break;
-    }
-  }
-  
-  parseState->token.tokenPtrRange.ptr    = parseState->stringBuffer.bytes.ptr + startingIndex;
-  parseState->token.tokenPtrRange.length = (atNumberCharacter - parseState->token.tokenPtrRange.ptr) - backup;
-  parseState->atIndex                    = (parseState->token.tokenPtrRange.ptr + parseState->token.tokenPtrRange.length) - parseState->stringBuffer.bytes.ptr;
-
-  if(CDVJK_EXPECT_T(numberState == CDVJSONNumberStateFinished)) {
-    unsigned char  numberTempBuf[parseState->token.tokenPtrRange.length + 4UL];
-    unsigned char *endOfNumber = NULL;
-
-    memcpy(numberTempBuf, parseState->token.tokenPtrRange.ptr, parseState->token.tokenPtrRange.length);
-    numberTempBuf[parseState->token.tokenPtrRa

<TRUNCATED>

Mime
View raw message