/* findKey(key) copies records until it is either
       at the record containing the matching key,
       at the record that should immediately follow the key, if it were there,
       or at the end of the file if the key is larger than the largest key
          in the file.
   As a result, it is at the perfect spot to get a desired record, update
   a record, delete a record, or insert a new record.
   Returns whether rec contains a matching key. */
static int findKey(KeyType key) {
    if ( atEnd )
        changeDirections();
    else if ( KEY_COMPARE(key, rec.KEY) < 0 ) {
        copyRestOfFile();
        changeDirections();
    }

    while ( ! atEnd && KEY_COMPARE(key, rec.KEY) > 0 ) {
        fwrite(&rec, sizeof(rec), 1, destinationFile);
        atEnd = (fread(&rec, sizeof(rec), 1, sourceFile) < 1);
    }

    return ( ! atEnd && KEY_COMPARE(key, rec.KEY) == 0 );
}
/**
 * updateRecord(&record) changes the contents of the matching file record.
 * It is optimized so you can use getRecord to obtain data, change the data,
 * then use updateRecord to save the change. You can update the record
 * multiple times without incurring I/O as long as no access of other records
 * is occurring. This version does allow you to save multiple records and
 * update them in any order, although performance does suffer. updateRecord
 * simply searches to find the record if the one you are updating isn't the
 * current one. This flexibility comes at a price, however, as there is no
 * way to prevent you from updating the key and destroying another record.
 * To update the key value, you should use getRecord to save a local copy,
 * deleteRecord(key) to destroy the old record, change the key, and use
 * insertRecord to save the change as a new record.
 * Returns whether or not the updated record matches an existing record
 * in the file.
 **/
int updateRecord(Customer * r) {
	if ( KEY_COMPARE(r->KEY, rec.KEY) != 0 ) {
	    if ( ! findKey(r->KEY) )
	        return 0;
	}
	memcpy(&rec, r, sizeof(rec)); /* can replace memcpy with packing and unpacking operations, if desired */
	return 1;
}
Ejemplo n.º 3
0
static int
ewl_text_context_hash_cmp(const void *ctx1, const void *ctx2)
{
        const Ewl_Text_Context *tx1 = ctx1;
        const Ewl_Text_Context *tx2 = ctx2;

        DENTER_FUNCTION(DLEVEL_STABLE);

#define KEY_BUILD(c) ((c.r << 24) | (c.g << 16) | (c.b << 8) | c.a)
#define KEY_COMPARE(k1, k2) if (k1 > k2) goto CTX1_LARGER; else if (k2 > k1) goto CTX2_LARGER;

        KEY_COMPARE(ecore_str_compare(tx1->font, tx2->font), 0);
        KEY_COMPARE(ecore_str_compare(tx1->font_source, tx2->font_source), 0);
        KEY_COMPARE(tx1->size, tx2->size);
        KEY_COMPARE(tx1->styles, tx2->styles);
        KEY_COMPARE(tx1->align, tx2->align);
        KEY_COMPARE(tx1->wrap, tx2->wrap);
        KEY_COMPARE(KEY_BUILD(tx1->color), KEY_BUILD(tx2->color));
        KEY_COMPARE(KEY_BUILD(tx1->style_colors.bg),
                        KEY_BUILD(tx2->style_colors.bg));
        KEY_COMPARE(KEY_BUILD(tx1->style_colors.outline),
                        KEY_BUILD(tx2->style_colors.outline));
        KEY_COMPARE(KEY_BUILD(tx1->style_colors.shadow),
                        KEY_BUILD(tx2->style_colors.shadow));
        KEY_COMPARE(KEY_BUILD(tx1->style_colors.strikethrough),
                        KEY_BUILD(tx2->style_colors.strikethrough));
        KEY_COMPARE(KEY_BUILD(tx1->style_colors.underline),
                        KEY_BUILD(tx2->style_colors.underline));
        KEY_COMPARE(KEY_BUILD(tx1->style_colors.double_underline),
                        KEY_BUILD(tx2->style_colors.double_underline));

        DRETURN_INT(0, DLEVEL_STABLE);
CTX1_LARGER:
        DRETURN_INT(-1, DLEVEL_STABLE);
CTX2_LARGER:
        DRETURN_INT(1, DLEVEL_STABLE);
}