/*
* 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);
}