1 #include "foxtoken.h"
2 #include "foxobjtab.h"
3 #include "foxreport.h"
4
5 #define OBJ_TABLE_NUM_ENTRIES 4111 //Prime number
6
7 static ObjTableEntry *table[OBJ_TABLE_NUM_ENTRIES];
8
9 /*
10 * Table Definition and Declaration
11 */
12 typedef struct _PDFObjectTable {
13 uint32_t numEntries;
14 uint32_t tableSize;
15 ObjTableEntry **table;
16 } PDFObjectTable;
17
18 static PDFObjectTable ObjTable;
19
20 /*
21 * Constructor
22 *
23 * Initialized Object Table
24 */
initObjTable()25 __attribute__ ((constructor)) void initObjTable () {
26 int i;
27 for (i = 0; i < OBJ_TABLE_NUM_ENTRIES; i++) {
28 table[i] = NULL;
29 }
30
31 ObjTable.table = table;
32 ObjTable.numEntries = 0;
33 ObjTable.tableSize = OBJ_TABLE_NUM_ENTRIES;
34 }
35
36 /*
37 * Find slot for object
38 */
hashObj(ObjTableEntry * entry)39 static uint32_t hashObj (ObjTableEntry *entry) {
40 return (entry->refnum % OBJ_TABLE_NUM_ENTRIES);
41 }
42
43 /*
44 *
45 * Initializes new object table entry
46 *
47 */
getNewObjTabEntry()48 ObjTableEntry *getNewObjTabEntry() {
49 ObjTableEntry *entry;
50
51 if ((entry = calloc(1, sizeof(ObjTableEntry))) == NULL) {
52 foxLog(FATAL, "%s: Could not allocate memory.\n", __func__);
53 return NULL;
54 }
55
56 return entry;
57 }
58
59 /*
60 *
61 * Adds an entry to the table by ref, then rev
62 *
63 */
addPDFObjEntry(ObjTableEntry * entry)64 int addPDFObjEntry (ObjTableEntry *entry) {
65
66 uint32_t index;
67 ObjTableEntry *temp;
68
69 index = hashObj(entry);
70
71 if (table[index] == NULL) {
72 table[index] = entry;
73 }
74 else {
75 temp = table[index];
76
77 if (temp->refnum == entry->refnum && temp->revnum == entry->revnum) {
78 foxLog(NONFATAL, "%s: Entry already exists with that ref/rev.\n", __func__);
79 return 0;
80 }
81
82 while (temp->next != NULL) {
83 temp = temp->next;
84
85 if (temp->refnum == entry->refnum && temp->revnum == entry->revnum) {
86 foxLog(NONFATAL, "%s: Entry already exists with that ref/rev.\n", __func__);
87 return 0;
88 }
89 }
90
91 temp->next = entry;
92 }
93
94 return 1;
95
96 }
97
98 /*
99 * Retrieve entry by ref and rev
100 *
101 */
getPDFObjEntry(uint32_t refnum,uint32_t revnum)102 ObjTableEntry *getPDFObjEntry (uint32_t refnum, uint32_t revnum) {
103 ObjTableEntry *entry;
104
105 entry = table[refnum];
106
107 while (entry != NULL) {
108 if (entry->refnum == refnum && entry->revnum == revnum)
109 return entry;
110
111 entry = entry->next;
112 }
113
114 return NULL;
115 }
116
117 /*
118 * Cycle through table and pass by the next
119 * unresolved object on the table.
120 *
121 */
getNextUnresolved()122 ObjTableEntry *getNextUnresolved() {
123 static unsigned int index = 0, ready = 1;
124 static ObjTableEntry *temp, *entry;
125
126 for (;index < ObjTable.tableSize; index++) {
127 if (ready)
128 temp = ObjTable.table[index];
129 while (temp != NULL) {
130 if (temp->fullyResolved == 0) {
131 ready = 0;
132 entry = temp;
133 temp = temp->next;
134 return entry;
135 }
136 temp = temp->next;
137 }
138 index++;
139 ready = 1;
140 }
141
142 return NULL;
143 }
144
145 /*
146 * This is for DEBUG purposes
147 *
148 * Do one final check to see if we missed any indirect
149 * references.
150 *
151 */
countUnresolved()152 __attribute__ ((destructor)) void countUnresolved() {
153
154 ObjTableEntry *temp, *entry;
155 #ifdef PDF_FOX_SHOW_DEBUG
156 unsigned int index;
157 uint32_t count = 0;
158
159 for (index = 0; index < ObjTable.tableSize; index++) {
160 temp = ObjTable.table[index];
161 while (temp != NULL) {
162 if (temp->fullyResolved == 0) {
163 count++;
164 }
165 temp = temp->next;
166 }
167 index++;
168 }
169
170 foxLog(PDF_DEBUG, "Remaining unresolved references = %d\n.", count);
171 #endif
172 uint32_t i;
173
174 for (i = 0; i < ObjTable.tableSize; i++) {
175 temp = ObjTable.table[i];
176 while (temp != NULL) {
177 entry = temp->next;
178 free(temp);
179 temp = entry;
180 }
181 i++;
182 }
183
184 }
185