Skip to content

Commit

Permalink
Some memory management updates
Browse files Browse the repository at this point in the history
  • Loading branch information
Mirek Rusin authored and Mirek Rusin committed Feb 18, 2011
1 parent f158336 commit 42e5417
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 48 deletions.
2 changes: 2 additions & 0 deletions CoreJSON.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
EB7354C2130E688300D6C2D8 /* Readme.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = Readme.md; sourceTree = "<group>"; };
EBB81049130BEC3E00CF5EF8 /* CoreJSON.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CoreJSON.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EBB81054130BEC3E00CF5EF8 /* CoreJSON-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "CoreJSON-Info.plist"; sourceTree = "<group>"; };
EBB81056130BEC3E00CF5EF8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
Expand Down Expand Up @@ -78,6 +79,7 @@
EBB81063130BEC3E00CF5EF8 /* CoreJSONTests */,
EBB8104B130BEC3E00CF5EF8 /* Frameworks */,
EBB8104A130BEC3E00CF5EF8 /* Products */,
EB7354C2130E688300D6C2D8 /* Readme.md */,
);
sourceTree = "<group>";
};
Expand Down
130 changes: 89 additions & 41 deletions CoreJSON/CoreJSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,20 @@ inline void __JSONUTF8StringDestroy(__JSONUTF8String utf8String) {

#pragma Internal stack

inline __JSONStackEntryRef __JSONStackEntryCreate(CFAllocatorRef allocator, CFIndex index, CFIndex valuesLength, CFIndex keysLength) {
inline __JSONStackEntryRef __JSONStackEntryCreate(CFAllocatorRef allocator, CFIndex index, CFIndex valuesInitialSize, CFIndex keysInitialSize) {
__JSONStackEntryRef entry = CFAllocatorAllocate(allocator, sizeof(__JSONStackEntry), 0);
if (entry) {
entry->allocator = allocator;
entry->allocator = allocator ? CFRetain(allocator) : NULL;
entry->retainCount = 1;
entry->index = index;
entry->valuesIndex = 0;
if ((entry->valuesLength = valuesLength))
entry->values = CFAllocatorAllocate(entry->allocator, valuesLength, 0);
if ((entry->valuesSize = valuesInitialSize))
entry->values = CFAllocatorAllocate(entry->allocator, entry->valuesSize, 0);
else
entry->values = NULL;
entry->keysIndex = 0;
if ((entry->keysLength = keysLength))
entry->keys = CFAllocatorAllocate(entry->allocator, keysLength, 0);
if ((entry->keysSize = keysInitialSize))
entry->keys = CFAllocatorAllocate(entry->allocator, entry->keysSize, 0);
else
entry->keys = NULL;
}
Expand All @@ -68,32 +68,63 @@ inline __JSONStackEntryRef __JSONStackEntryRetain(__JSONStackEntryRef entry) {
}

inline CFIndex __JSONStackEntryRelease(__JSONStackEntryRef entry) {
// TODO: Deallocate stack entry arrays
return --entry->retainCount;
}

inline __JSONStackEntryRef __JSONStackEntryReleaseRef(__JSONStackEntryRef *entry) {
if (0 == __JSONStackEntryRelease(*entry))
entry = NULL;
return *entry;
if (--entry->retainCount == 0) {
CFAllocatorRef allocator = entry->allocator;
if (entry->values)
CFAllocatorDeallocate(allocator, entry->values);
if (entry->keys)
CFAllocatorDeallocate(allocator, entry->keys);
CFAllocatorDeallocate(allocator, entry);
if (allocator)
CFRelease(allocator);
}
return entry->retainCount;
}

inline void __JSONStackEntryAppendValue(__JSONStackEntryRef entry, CFTypeRef value) {
// TODO: Reallocate when out of bounds
entry->values[entry->valuesIndex++] = value;
inline bool __JSONStackEntryAppendValue(__JSONStackEntryRef entry, CFTypeRef value) {
bool success = 0;
if (entry) {
if (entry->valuesIndex == entry->valuesSize) { // Reallocate more space
CFIndex largerSize = entry->valuesSize ? entry->valuesSize << 1 : 1024;
CFTypeRef *largerValues = CFAllocatorReallocate(entry->allocator, entry->values, largerSize, 0);
if (largerValues) {
entry->valuesSize = largerSize;
entry->values = largerValues;
}
}
if (entry->valuesIndex < entry->valuesSize) {
entry->values[entry->valuesIndex++] = value;
success = 1;
}
}
return success;
}

inline void __JSONStackEntryAppendKey(__JSONStackEntryRef entry, CFTypeRef key) {
// TODO: Reallocate when out of bounds
entry->keys[entry->keysIndex++] = key;
inline bool __JSONStackEntryAppendKey(__JSONStackEntryRef entry, CFTypeRef key) {
bool success = 0;
if (entry) {
if (entry->keysIndex == entry->keysSize) { // Reallocate more space
CFIndex largerSize = entry->keysSize ? entry->keysSize << 1 : 1024;
CFTypeRef *largerKeys = CFAllocatorReallocate(entry->allocator, entry->keys, largerSize, 0);
if (largerKeys) {
entry->keysSize = largerSize;
entry->keys = largerKeys;
}
}
if (entry->keysIndex < entry->keysSize) {
entry->keys[entry->keysIndex++] = key;
success = 1;
}
}
return success;
}

inline __JSONStackRef __JSONStackCreate(CFAllocatorRef allocator, CFIndex maxDepth) {
inline __JSONStackRef __JSONStackCreate(CFAllocatorRef allocator, CFIndex initialSize) {
__JSONStackRef stack = CFAllocatorAllocate(allocator, sizeof(__JSONStack), 0);
if (stack) {
stack->allocator = allocator;
stack->allocator = allocator ? CFRetain(allocator) : NULL;
stack->retainCount = 1;
stack->size = maxDepth;
stack->size = initialSize;
stack->index = 0;
stack->stack = CFAllocatorAllocate(stack->allocator, sizeof(__JSONStackEntryRef) * stack->size, 0);
memset(stack->stack, 0, sizeof(__JSONStackEntryRef) * stack->size);
Expand All @@ -102,8 +133,17 @@ inline __JSONStackRef __JSONStackCreate(CFAllocatorRef allocator, CFIndex maxDep
}

inline CFIndex __JSONStackRelease(__JSONStackRef stack) {
// TODO: Stack deallocator
return --stack->retainCount;
CFIndex retainCount = 0;
if (stack) {
if ((retainCount = --stack->retainCount) == 0) {
CFAllocatorRef allocator = stack->allocator;
if (stack->stack)
CFAllocatorDeallocate(allocator, stack->stack);
if (allocator)
CFRelease(allocator);
}
}
return retainCount;
}

inline __JSONStackEntryRef __JSONStackGetTop(__JSONStackRef stack) {
Expand All @@ -116,11 +156,19 @@ inline __JSONStackEntryRef __JSONStackGetTop(__JSONStackRef stack) {
inline bool __JSONStackPush(__JSONStackRef stack, __JSONStackEntryRef entry) {
bool success = 0;
if (stack && entry) {

// Do we need more space? Reallocate to 2 * current size.
if (stack->index == stack->size) {
CFIndex largerSize = stack->size ? stack->size << 1 : 1024;
__JSONStackEntryRef *largerStack = CFAllocatorReallocate(stack->allocator, stack->stack, largerSize, 0);
if (largerStack) {
stack->size = largerSize;
stack->stack = largerStack;
}
}
if (stack->index < stack->size) {
stack->stack[stack->index++] = __JSONStackEntryRetain(entry);
success = 1;
} else {
// TODO: Out of bounds, reallocate more space
}
}
return success;
Expand Down Expand Up @@ -309,7 +357,7 @@ inline int __JSONParserAppendArrayEnd(void *context) {
inline CoreJSONRef JSONCreate(CFAllocatorRef allocator) {
CoreJSONRef json = CFAllocatorAllocate(allocator, sizeof(CoreJSON), 0);
if (json) {
json->allocator = allocator;
json->allocator = allocator ? CFRetain(allocator) : NULL;

json->yajlParserCallbacks.yajl_null = __JSONParserAppendNull;
json->yajlParserCallbacks.yajl_boolean = __JSONParserAppendBooleanWithInteger;
Expand Down Expand Up @@ -343,20 +391,20 @@ inline CoreJSONRef JSONCreate(CFAllocatorRef allocator) {
}

inline CFIndex JSONRelease(CoreJSONRef json) {
CFIndex retainCount = -1;
CFIndex retainCount = 0;
if (json) {
if (json->retainCount > 0) {
if ((retainCount = --json->retainCount) == 0) {
CFAllocatorRef allocator = json->allocator;
yajl_free(json->yajlParser);
// yajl_free(json->yajlGenerator);
CFRelease(json->elements);
__JSONStackRelease(json->stack);

CFAllocatorDeallocate(allocator, json);
}
if ((retainCount = --json->retainCount) == 0) {
CFAllocatorRef allocator = json->allocator;

yajl_free(json->yajlParser);
// TODO: release generator

CFRelease(json->elements);
__JSONStackRelease(json->stack);
CFAllocatorDeallocate(allocator, json);
if (allocator)
CFRelease(allocator);
}
}
return retainCount;
Expand Down
13 changes: 6 additions & 7 deletions CoreJSON/CoreJSON.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,20 @@ typedef struct {

CFTypeRef *values;
CFIndex valuesIndex;
CFIndex valuesLength;
CFIndex valuesSize;

CFTypeRef *keys;
CFIndex keysIndex;
CFIndex keysLength;
CFIndex keysSize;
} __JSONStackEntry;

typedef __JSONStackEntry *__JSONStackEntryRef;

__JSONStackEntryRef __JSONStackEntryCreate (CFAllocatorRef allocator, CFIndex index, CFIndex valuesLength, CFIndex keysLength);
__JSONStackEntryRef __JSONStackEntryCreate (CFAllocatorRef allocator, CFIndex index, CFIndex valuesInitialSize, CFIndex keysInitialSize);
__JSONStackEntryRef __JSONStackEntryRetain (__JSONStackEntryRef entry);
CFIndex __JSONStackEntryRelease (__JSONStackEntryRef entry);
__JSONStackEntryRef __JSONStackEntryReleaseRef (__JSONStackEntryRef *entry);
void __JSONStackEntryAppendValue (__JSONStackEntryRef entry, CFTypeRef value);
void __JSONStackEntryAppendKey (__JSONStackEntryRef entry, CFTypeRef key);
bool __JSONStackEntryAppendValue (__JSONStackEntryRef entry, CFTypeRef value);
bool __JSONStackEntryAppendKey (__JSONStackEntryRef entry, CFTypeRef key);

typedef struct {
CFAllocatorRef allocator;
Expand All @@ -96,7 +95,7 @@ typedef struct {

typedef __JSONStack *__JSONStackRef;

__JSONStackRef __JSONStackCreate (CFAllocatorRef allocator, CFIndex maxDepth);
__JSONStackRef __JSONStackCreate (CFAllocatorRef allocator, CFIndex initialSize);
CFIndex __JSONStackRelease (__JSONStackRef stack);
__JSONStackEntryRef __JSONStackGetTop (__JSONStackRef stack);
bool __JSONStackPush (__JSONStackRef stack, __JSONStackEntryRef entry);
Expand Down

0 comments on commit 42e5417

Please sign in to comment.