summaryrefslogtreecommitdiff
path: root/fitz/obj_array.c
diff options
context:
space:
mode:
Diffstat (limited to 'fitz/obj_array.c')
-rw-r--r--fitz/obj_array.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/fitz/obj_array.c b/fitz/obj_array.c
new file mode 100644
index 00000000..3953470a
--- /dev/null
+++ b/fitz/obj_array.c
@@ -0,0 +1,230 @@
+#include "fitz-base.h"
+#include "fitz-stream.h"
+
+void fz_droparray(fz_obj *obj);
+
+fz_error *
+fz_newarray(fz_obj **op, int initialcap)
+{
+ fz_obj *obj;
+ int i;
+
+ obj = *op = fz_malloc(sizeof (fz_obj));
+ if (!obj)
+ return fz_throw("outofmem: array struct");
+
+ obj->refs = 1;
+ obj->kind = FZ_ARRAY;
+
+ obj->u.a.len = 0;
+ obj->u.a.cap = initialcap > 0 ? initialcap : 6;
+
+ obj->u.a.items = fz_malloc(sizeof (fz_obj*) * obj->u.a.cap);
+ if (!obj->u.a.items)
+ {
+ fz_free(obj);
+ return fz_throw("outofmem: array item buffer");
+ }
+
+ for (i = 0; i < obj->u.a.cap; i++)
+ obj->u.a.items[i] = nil;
+
+ return fz_okay;
+}
+
+fz_error *
+fz_copyarray(fz_obj **op, fz_obj *obj)
+{
+ fz_error *error;
+ fz_obj *new;
+ int i;
+
+ if (!fz_isarray(obj))
+ return fz_throw("assert: not an array (%s)", fz_objkindstr(obj));
+
+ error = fz_newarray(&new, fz_arraylen(obj));
+ if (error)
+ return fz_rethrow(error, "cannot create new array");
+
+ for (i = 0; i < fz_arraylen(obj); i++)
+ {
+ error = fz_arraypush(new, fz_arrayget(obj, i));
+ if (error)
+ {
+ fz_droparray(new);
+ return fz_rethrow(error, "cannot add item to array");
+ }
+ }
+
+ *op = new;
+
+ return fz_okay;
+}
+
+fz_error *
+fz_deepcopyarray(fz_obj **op, fz_obj *obj)
+{
+ fz_error *error;
+ fz_obj *new;
+ fz_obj *val;
+ int i;
+
+ if (!fz_isarray(obj))
+ return fz_throw("assert: not an array (%s)", fz_objkindstr(obj));
+
+ error = fz_newarray(&new, fz_arraylen(obj));
+ if (error)
+ return fz_rethrow(error, "cannot create new array");
+
+ for (i = 0; i < fz_arraylen(obj); i++)
+ {
+ val = fz_arrayget(obj, i);
+
+ if (fz_isarray(val))
+ {
+ error = fz_deepcopyarray(&val, val);
+ if (error)
+ {
+ fz_droparray(new);
+ return fz_rethrow(error, "cannot deep copy item");
+ }
+
+ error = fz_arraypush(new, val);
+ if (error)
+ {
+ fz_dropobj(val);
+ fz_droparray(new);
+ return fz_rethrow(error, "cannot add copied item to array");
+ }
+
+ fz_dropobj(val);
+ }
+
+ else if (fz_isdict(val))
+ {
+ error = fz_deepcopydict(&val, val);
+ if (error)
+ {
+ fz_droparray(new);
+ return fz_rethrow(error, "cannot deep copy item");
+ }
+
+ error = fz_arraypush(new, val);
+ if (error)
+ {
+ fz_dropobj(val);
+ fz_droparray(new);
+ return fz_rethrow(error, "cannot add copied item to array");
+ }
+ fz_dropobj(val);
+ }
+
+ else
+ {
+ error = fz_arraypush(new, val);
+ if (error)
+ {
+ fz_droparray(new);
+ return fz_rethrow(error, "cannot add copied item to array");
+ }
+ }
+ }
+
+ *op = new;
+
+ return fz_okay;
+}
+
+int
+fz_arraylen(fz_obj *obj)
+{
+ if (!fz_isarray(obj))
+ return 0;
+ return obj->u.a.len;
+}
+
+fz_obj *
+fz_arrayget(fz_obj *obj, int i)
+{
+ if (!fz_isarray(obj))
+ return nil;
+
+ if (i < 0 || i >= obj->u.a.len)
+ return nil;
+
+ return obj->u.a.items[i];
+}
+
+fz_error *
+fz_arrayput(fz_obj *obj, int i, fz_obj *item)
+{
+ if (!fz_isarray(obj))
+ return fz_throw("assert: not an array (%s)", fz_objkindstr(obj));
+ if (i < 0)
+ return fz_throw("assert: index %d < 0", i);
+ if (i >= obj->u.a.len)
+ return fz_throw("assert: index %d > length %d", i, obj->u.a.len);
+
+ if (obj->u.a.items[i])
+ fz_dropobj(obj->u.a.items[i]);
+ obj->u.a.items[i] = fz_keepobj(item);
+
+ return fz_okay;
+}
+
+static fz_error *
+growarray(fz_obj *obj)
+{
+ fz_obj **newitems;
+ int newcap;
+ int i;
+
+ newcap = obj->u.a.cap * 2;
+ newitems = fz_realloc(obj->u.a.items, sizeof (fz_obj*) * newcap);
+ if (!newitems)
+ return fz_throw("outofmem: resize item buffer");
+
+ obj->u.a.items = newitems;
+ for (i = obj->u.a.cap ; i < newcap; i++)
+ obj->u.a.items[i] = nil;
+ obj->u.a.cap = newcap;
+
+ return fz_okay;
+}
+
+fz_error *
+fz_arraypush(fz_obj *obj, fz_obj *item)
+{
+ fz_error *error;
+
+ if (!fz_isarray(obj))
+ return fz_throw("assert: not an array (%s)", fz_objkindstr(obj));
+
+ if (obj->u.a.len + 1 > obj->u.a.cap)
+ {
+ error = growarray(obj);
+ if (error)
+ return fz_rethrow(error, "cannot grow item buffer");
+ }
+
+ obj->u.a.items[obj->u.a.len] = fz_keepobj(item);
+ obj->u.a.len++;
+
+ return fz_okay;
+}
+
+void
+fz_droparray(fz_obj *obj)
+{
+ int i;
+
+ assert(obj->kind == FZ_ARRAY);
+
+ for (i = 0; i < obj->u.a.len; i++)
+ if (obj->u.a.items[i])
+ fz_dropobj(obj->u.a.items[i]);
+
+ fz_free(obj->u.a.items);
+ fz_free(obj);
+}
+