Example #1
0
static VBoolean WriteAttr (FILE *f, VAttrListPosn *posn, int indent, VList *data_list, long *offset)
{
    int i;
    char *str;
    VRepnKind repn;
    VAttrList sublist;
    VBundle b;
    DataBlock *db;
    VTypeMethods *methods;
    size_t length;
    VPointer value;
    VBoolean result;
    VAttrListPosn subposn;

    /* Indent by the specified amount: */
    for (i = 0; i < indent; i++)
	FailTest (fputc ('\t', f));
    indent++;

    /* Output the attribute's name: */
    FailTest (fprintf (f, "%s: ", VGetAttrName (posn)));

    /* Ouput its value: */
    switch (repn = VGetAttrRepn (posn)) {

    case VAttrListRepn:
	VGetAttrValue (posn, NULL, VAttrListRepn, (VPointer) & sublist);
	result = WriteAttrList (f, sublist, indent, data_list, offset);
	break;

    case VBundleRepn:
	VGetAttrValue (posn, NULL, VBundleRepn, (VBundle) & b);
	if (! WriteString (f, b->type_name))
	    return FALSE;
	FailTest (fputc (' ', f));

	/* If it's a typed value with binary data... */
	if (b->length > 0) {

	    /* Include "data" and "length" attributes in its attribute list: */
	    VPrependAttr (b->list, VLengthAttr, NULL, VLongRepn,
			  (VLong) b->length);
	    VPrependAttr (b->list, VDataAttr, NULL, VLongRepn,
			  (VLong) *offset);

	    /* Add it to the queue of binary data blocks to be written: */
	    *offset += b->length;
	    db = VNew (DataBlock);
	    db->posn = *posn;
	    db->list = b->list;
	    db->length = b->length;
	    VListAppend (*data_list, db);
	}

	/* Write the typed value's attribute list: */
	result = WriteAttrList (f, b->list, indent, data_list, offset);

	/* Remove the "data" and "length" attributes added earlier: */
	if (b->length > 0) {
	    VFirstAttr (b->list, & subposn);
	    VDeleteAttr (& subposn);
	    VDeleteAttr (& subposn);
	}
	break;

    case VStringRepn:
	VGetAttrValue (posn, NULL, VStringRepn, (VPointer) & str);
	result = WriteString (f, str);
	break;

    default:
	if (! (methods = VRepnMethods (repn)) ||
	    ! methods->encode_attr || ! methods->encode_data) {
	    VWarning ("VWriteFile: "
		      "%s attribute has unwriteable representation: %s",
		      VGetAttrName (posn), VRepnName (repn));
	    return FALSE;
	}

	/* Write the type name: */
	if (! WriteString (f, VRepnName (repn)))
	    return FALSE;
	FailTest (fputc (' ', f));

	/* Invoke the object type's encode_attr method to obtain an
	   attribute list: */
	VGetAttrValue (posn, NULL, repn, & value);
	sublist = (methods->encode_attr) (value, & length);

	/* If binary data is indicated... */
	if (length > 0) {

	    /* Include "data" and "length" attributes in the attr list: */
	    VPrependAttr (sublist, VLengthAttr, NULL, VLongRepn,
			  (VLong) length);
	    VPrependAttr (sublist, VDataAttr, NULL, VLongRepn,
			  (VLong) *offset);

	    *offset += length;
	}

	/* Add the object to the queue of binary data blocks to be written: */
	db = VNew (DataBlock);
	db->posn = *posn;
	db->list = sublist;
	db->length = length;
	VListAppend (*data_list, db);

	/* Write the typed value's attribute list: */
	result = WriteAttrList (f, sublist, indent, data_list, offset);

	/* Remove the "data" and "length" attributes added earlier: */
	if (length > 0) {
	    VFirstAttr (sublist, & subposn);
	    VDeleteAttr (& subposn);
	    VDeleteAttr (& subposn);
	}
    }

    /* Output a trailing newline: */
    if (result)
	FailTest (fputc ('\n', f));
    return result;

Fail:
    VWarning ("VWriteFile: Write to stream failed");
    return FALSE;
}
Example #2
0
VBoolean VWriteFile (FILE *f, VAttrList list)
{
    DataBlock *db;
    VBundle b;
    VTypeMethods *methods;
    VRepnKind repn;
    VPointer value, ptr;
    VBoolean result, free_it;
    VList data_list;

    /* Write the FIL_Vista data file header, attribute list, and delimeter
       while queuing on data_list any binary data blocks to be written: */
    long offset = 0;
    data_list = VListCreate ();
    FailTest (fprintf (f, "%s %d ", VFileHeader, VFileVersion));
    if (! WriteAttrList (f, list, 1, &data_list, &offset)) {
	VListDestroy (data_list, VFree);
	return FALSE;
    }
    FailTest (fputs ("\n" VFileDelimiter, f));
    fflush (f);

    /* Traverse data_list to write the binary data blocks: */
    for (db = VListFirst (data_list); db; db = VListNext (data_list)) {
	repn = VGetAttrRepn (& db->posn);
	if (repn == VBundleRepn) {

	    /* A typed value includes its binary data block explicitly: */
	    VGetAttrValue (& db->posn, NULL, VBundleRepn, & b);
	    ptr = b->data;
	    free_it = FALSE;

	} else {

	    /* For any other representation, obtain the binary data block
	       from its encode_data method: */
	    VGetAttrValue (& db->posn, NULL, repn, & value);
	    methods = VRepnMethods (repn);
	    ptr = (methods->encode_data)
		(value, db->list, db->length, & free_it);
	    if (! ptr)
		goto Fail;
	}

	/* Write the binary data and free the buffer containing it if it was
	   allocated temporarily by an encode_data method: */
	if (db->length > 0) {
	    result = fwrite (ptr, 1, db->length, f) == db->length;
	    if (free_it)
		VFree (ptr);
	    if (! result)
		goto Fail;
	}
    }
    VListDestroy (data_list, VFree);
    return TRUE;

Fail:
    VWarning ("VWriteFile: Write to stream failed");
    VListDestroy (data_list, VFree);
    return FALSE;
}
Example #3
0
EXPORT_VISTA VistaIOBoolean VistaIOWriteFile (FILE * f, VistaIOAttrList list)
{
	DataBlock *db;
	VistaIOBundle b;
	VistaIOTypeMethods *methods;
	VistaIORepnKind repn;
	VistaIOPointer value, ptr;
	VistaIOBoolean free_it;
	VistaIOBoolean result = 0;

	/* Write the Vista data file header, attribute list, and delimeter
	   while queuing on data_list any binary data blocks to be written: */
	offset = 0;
	data_list = VistaIOListCreate ();
	FailTest (fprintf (f, "%s %d ", VistaIOFileHeader, VistaIOFileVersion));
	if (!WriteAttrList (f, list, 1)) {
		VistaIOListDestroy (data_list, VistaIOFree);
		return FALSE;
	}
	FailTest (fputs ("\n" VistaIOFileDelimiter, f));
	fflush (f);

	/* Traverse data_list to write the binary data blocks: */
	for (db = VistaIOListFirst (data_list); db; db = VistaIOListNext (data_list)) {
		repn = VistaIOGetAttrRepn (&db->posn);
		if (repn == VistaIOBundleRepn) {

			/* A typed value includes its binary data block explicitly: */
			VistaIOGetAttrValue (&db->posn, NULL, VistaIOBundleRepn, &b);
			ptr = b->data;
			free_it = FALSE;

		} else {

			/* For any other representation, obtain the binary data block
			   from its encode_data method: */
			VistaIOGetAttrValue (&db->posn, NULL, repn, &value);
			methods = VistaIORepnMethods (repn);
			ptr = (methods->encode_data)
				(value, db->list, db->length, &free_it);
			if (!ptr)
				goto Fail;
		}

		/* Write the binary data and free the buffer containing it if it was
		   allocated temporarily by an encode_data method: */
		if (db->length > 0) {
			int togo = db->length; 
			int pos = 0; 
			while (togo) {
				size_t write_length = togo < 100000  ? togo: 100000;
				result = fwrite (((char *)ptr) + pos, 1, write_length, f) == write_length;
				pos += write_length;
				togo -= write_length;
				VistaIOShowWriteProgress(pos, db->length, VistaIOProgressData);
			}
			if (free_it)
				VistaIOFree (ptr);
			if (!result)
				goto Fail;
		}
	}
	VistaIOListDestroy (data_list, VistaIOFree);
	return TRUE;

      Fail:
	VistaIOWarning ("VistaIOWriteFile: Write to stream failed");
	VistaIOListDestroy (data_list, VistaIOFree);
	return FALSE;
}