/* * Binary object handling gear. Shit simple. * * Andrew Molitor, amolitor@nmsu.edu * * 1992 * * $Id: udb_obj.c,v 1.2 1995/11/22 23:33:17 root Exp $ */ #include "autoconf.h" #include "udb.h" #include "udb_defs.h" /* * Sizes, on disk, of Object and (within the object) Attribute headers */ #define OBJ_HEADER_SIZE (sizeof(Objname) + sizeof(int)) #define ATTR_HEADER_SIZE (sizeof(int) * 2) /* * * Routines to get Obj's on and off disk. Obj's are stowed in a * fairly complex way: an object header with the object ID (not really * needed, but there to facilitate possible recoveries of crashed DBs), * and an attribute count. This is followed by the attributes. * * We use the standard library here, and do a lot of fread()s. * Trust your standard library. If you think this is inefficient, you have * your head up your ass. This means you, Jellan. */ Obj * objfromFILE(f) FILE *f; { int i, j; int size; Obj *o; Attrib *a; /* * Get a new Obj struct */ if ((o = (Obj *) malloc(sizeof(Obj))) == (Obj *) 0) return ((Obj *) 0); /* * Read in the header */ if (fread(&(o->name), sizeof(Objname), 1, f) != 1) { free(o); return ((Obj *) 0); } if (fread(&i, sizeof(int), 1, f) != 1) { free(o); return ((Obj *) 0); } o->at_count = i; /* * Now get an array of Attrs */ a = o->atrs = (Attrib *) malloc(i * sizeof(Attrib)); if (!o->atrs) { free(o); return ((Obj *) 0); } /* * Now go get the attrs, one at a time. */ for (j = 0; j < i;) { /* * Attribute size */ if (fread(&size, sizeof(int), 1, f) != 1) goto bail; a[j].size = size; /* * Attribute number */ if (fread(&(a[j].attrnum), sizeof(int), 1, f) != 1) goto bail; /* * get some memory for the data */ if ((a[j].data = (char *)malloc(size)) == (char *)0) goto bail; /* * Preincrement j, so we know how many to free if this next * * * * * * bit fails. */ j++; /* * Now get the data */ if (fread(a[j - 1].data, 1, size, f) != size) goto bail; } /* * Should be all done.. */ return (o); /* * Oh shit. We gotta free up all these little bits of memory. */ bail: /* * j points one attribute *beyond* what we need to free up */ for (i = 0; i < j; i++) free(a[i].data); free(a); free(o); return ((Obj *) 0); } int objtoFILE(o, f) Obj *o; FILE *f; { int i; Attrib *a; /* * Write out the object header */ if (fwrite(&(o->name), sizeof(Objname), 1, f) != 1) return (-1); if (fwrite(&(o->at_count), sizeof(int), 1, f) != 1) return (-1); /* * Now do the attributes, one at a time. */ a = o->atrs; for (i = 0; i < o->at_count; i++) { /* * Attribute size. */ if (fwrite(&(a[i].size), sizeof(int), 1, f) != 1) return (-1); /* * Attribute number */ if (fwrite(&(a[i].attrnum), sizeof(int), 1, f) != 1) return (-1); /* * Attribute data */ if (fwrite(a[i].data, 1, a[i].size, f) != a[i].size) return (-1); } /* * That's all she wrote. */ return (0); } /* * Return the size, on disk, the thing is going to take up. */ int obj_siz(o) Obj *o; { int i; int siz; siz = OBJ_HEADER_SIZE; for (i = 0; i < o->at_count; i++) siz += (((o->atrs)[i]).size + ATTR_HEADER_SIZE); return (siz); }