Permalink
Browse files

Make the TOC a tree.

  • Loading branch information...
neror committed Nov 6, 2012
1 parent b3953c5 commit a52cabc61af2d9d800fc1641507342780e7a47d7
Showing with 54 additions and 12 deletions.
  1. +42 −5 EPUB3.c
  2. +7 −2 EPUB3_private.h
  3. +5 −5 TestEPUB3Processor/check_EPUB3.c
View
47 EPUB3.c
@@ -305,7 +305,7 @@ EPUB3TocRef EPUB3TocCreate()
{
EPUB3TocRef memory = malloc(sizeof(struct EPUB3Toc));
memory = EPUB3ObjectInitWithTypeID(memory, kEPUB3TocTypeID);
- memory->itemCount = 0;
+ memory->rootItemCount = 0;
memory->rootItemsHead = NULL;
memory->rootItemsTail = NULL;
return memory;
@@ -327,7 +327,7 @@ void EPUB3TocRelease(EPUB3TocRef toc)
if(toc == NULL) return;
if(toc->_type.refCount == 1) {
EPUB3TocItemChildListItemPtr itemPtr = toc->rootItemsHead;
- int totalItemsToFree = toc->itemCount;
+ int totalItemsToFree = toc->rootItemCount;
while(itemPtr != NULL) {
assert(--totalItemsToFree >= 0);
EPUB3TocItemRelease(itemPtr->item);
@@ -336,7 +336,7 @@ void EPUB3TocRelease(EPUB3TocRef toc)
toc->rootItemsHead = itemPtr;
EPUB3_FREE_AND_NULL(tmp);
}
- toc->itemCount = 0;
+ toc->rootItemCount = 0;
}
EPUB3ObjectRelease(toc);
}
@@ -347,6 +347,9 @@ EPUB3TocItemRef EPUB3TocItemCreate()
memory = EPUB3ObjectInitWithTypeID(memory, kEPUB3TocItemTypeID);
memory->idref = NULL;
memory->manifestItem = NULL;
+ memory->childCount = 0;
+ memory->childrenHead = NULL;
+ memory->childrenTail = NULL;
return memory;
}
@@ -362,7 +365,19 @@ void EPUB3TocItemRelease(EPUB3TocItemRef item)
if(item->_type.refCount == 1) {
item->manifestItem = NULL; // zero weak ref
+ item->parent = NULL; // zero weak ref
EPUB3_FREE_AND_NULL(item->idref);
+ int totalItemsToFree = item->childCount;
+ EPUB3TocItemChildListItemPtr itemPtr = item->childrenHead;
+ while(itemPtr != NULL) {
+ assert(--totalItemsToFree >= 0);
+ EPUB3TocItemRelease(itemPtr->item);
+ EPUB3TocItemChildListItemPtr tmp = itemPtr;
+ itemPtr = itemPtr->next;
+ item->childrenHead = itemPtr;
+ EPUB3_FREE_AND_NULL(tmp);
+ }
+ item->childCount = 0;
}
EPUB3ObjectRelease(item);
@@ -375,7 +390,7 @@ void EPUB3TocItemSetManifestItem(EPUB3TocItemRef tocItem, EPUB3ManifestItemRef m
tocItem->idref = strdup(manifestItem->itemId);
}
-void EPUB3TocAppendItem(EPUB3TocRef toc, EPUB3TocItemRef item)
+void EPUB3TocAddRootItem(EPUB3TocRef toc, EPUB3TocItemRef item)
{
assert(toc != NULL);
assert(item != NULL);
@@ -392,7 +407,28 @@ void EPUB3TocAppendItem(EPUB3TocRef toc, EPUB3TocItemRef item)
toc->rootItemsTail->next = itemPtr;
toc->rootItemsTail = itemPtr;
}
- toc->itemCount++;
+ toc->rootItemCount++;
+}
+
+void EPUB3TocItemAppendChild(EPUB3TocItemRef parent, EPUB3TocItemRef child)
+{
+ assert(parent != NULL);
+ assert(child != NULL);
+
+ EPUB3TocItemRetain(child);
+ EPUB3TocItemChildListItemPtr itemPtr = (EPUB3TocItemChildListItemPtr) calloc(1, sizeof(struct EPUB3TocItemChildListItem));
+ itemPtr->item = child;
+
+ if(parent->childrenHead == NULL) {
+ // First item
+ parent->childrenHead = itemPtr;
+ parent->childrenTail = itemPtr;
+ } else {
+ parent->childrenTail->next = itemPtr;
+ parent->childrenTail = itemPtr;
+ }
+ child->parent = parent;
+ parent->childCount++;
}
#pragma mark - Metadata
@@ -1477,6 +1513,7 @@ EPUB3Error EPUB3CopyFileIntoBuffer(EPUB3Ref epub, void **buffer, uint32_t *buffe
error = kEPUB3Success;
} else {
free(*buffer);
+ *buffer = NULL;
error = kEPUB3FileReadFromArchiveError;
}
}
View
@@ -152,14 +152,18 @@ typedef struct EPUB3TocItemChildListItem {
struct EPUB3Toc {
EPUB3Type _type;
- int32_t itemCount;
+ int32_t rootItemCount;
EPUB3TocItemChildListItemPtr rootItemsHead;
EPUB3TocItemChildListItemPtr rootItemsTail;
};
struct EPUB3TocItem {
EPUB3Type _type;
char * idref;
+ EPUB3TocItemRef parent; //weak ref
+ int32_t childCount;
+ EPUB3TocItemChildListItemPtr childrenHead;
+ EPUB3TocItemChildListItemPtr childrenTail;
EPUB3ManifestItemRef manifestItem; //weak ref
};
@@ -223,7 +227,8 @@ void EPUB3TocRetain(EPUB3TocRef toc);
void EPUB3TocRelease(EPUB3TocRef toc);
void EPUB3TocItemRetain(EPUB3TocItemRef item);
void EPUB3TocItemRelease(EPUB3TocItemRef item);
-void EPUB3TocAppendItem(EPUB3TocRef toc, EPUB3TocItemRef item);
+void EPUB3TocAddRootItem(EPUB3TocRef toc, EPUB3TocItemRef item);
+void EPUB3TocItemAppendChild(EPUB3TocItemRef parent, EPUB3TocItemRef child);
void EPUB3TocItemSetManifestItem(EPUB3TocItemRef tocItem, EPUB3ManifestItemRef manifestItem);
#pragma mark - XML Parsing
@@ -149,7 +149,7 @@ START_TEST(test_epub3_toc)
EPUB3TocRef toc = EPUB3TocCreate();
ck_assert_int_eq(toc->_type.refCount, 1);
ck_assert_str_eq(toc->_type.typeID, kEPUB3TocTypeID);
- fail_unless(toc->itemCount == 0);
+ fail_unless(toc->rootItemCount == 0);
EPUB3TocItemRef item = EPUB3TocItemCreate();
ck_assert_int_eq(item->_type.refCount, 1);
@@ -170,15 +170,15 @@ END_TEST
START_TEST(test_epub3_toc_list)
{
EPUB3TocRef toc = EPUB3TocCreate();
- fail_unless(toc->itemCount == 0);
+ fail_unless(toc->rootItemCount == 0);
int itemCount = 20;
EPUB3TocItemRef firstItem = EPUB3TocItemCreate();
fail_unless(toc->rootItemsHead == NULL);
fail_unless(toc->rootItemsTail == NULL);
- EPUB3TocAppendItem(toc, firstItem);
+ EPUB3TocAddRootItem(toc, firstItem);
ck_assert_int_eq(firstItem->_type.refCount, 2);
EPUB3TocItemRelease(firstItem);
ck_assert_int_eq(firstItem->_type.refCount, 1);
@@ -190,15 +190,15 @@ START_TEST(test_epub3_toc_list)
for(int i = 1; i < itemCount; i++) {
EPUB3TocItemRef item = EPUB3TocItemCreate();
- EPUB3TocAppendItem(toc, item);
+ EPUB3TocAddRootItem(toc, item);
fail_unless(toc->rootItemsTail->item == item);
prev = toc->rootItemsTail;
EPUB3TocItemRelease(item);
}
- ck_assert_int_eq(toc->itemCount, itemCount);
+ ck_assert_int_eq(toc->rootItemCount, itemCount);
fail_unless(toc->rootItemsHead->item == firstItem);
fail_unless(toc->rootItemsTail == prev);
fail_if(toc->rootItemsHead == toc->rootItemsTail);

0 comments on commit a52cabc

Please sign in to comment.