/* * delta.h: headers for delta functionality * * Adapted from GIT for Bazaar by * John Arbash Meinel (C) 2009 * * This code is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #ifndef DELTA_H #define DELTA_H /* opaque object for delta index */ struct delta_index; struct source_info { const void *buf; /* Pointer to the beginning of source data */ unsigned long size; /* Total length of source data */ unsigned long agg_offset; /* Start of source data as part of the aggregate source */ }; /* result type for functions that have multiple failure modes */ typedef enum { DELTA_OK, /* Success */ DELTA_OUT_OF_MEMORY, /* Could not allocate required memory */ DELTA_INDEX_NEEDED, /* A delta_index must be passed */ DELTA_SOURCE_EMPTY, /* A source_info had no content */ DELTA_SOURCE_BAD, /* A source_info had invalid or corrupt content */ DELTA_BUFFER_EMPTY, /* A buffer pointer and size */ DELTA_SIZE_TOO_BIG, /* Delta data is larger than the max requested */ } delta_result; /* * create_delta_index: compute index data from given buffer * * Returns a delta_result status, when DELTA_OK then *fresh is set to a struct * delta_index that should be passed to subsequent create_delta() calls, or to * free_delta_index(). Other values are a failure, and *fresh is unset. * The given buffer must not be freed nor altered before free_delta_index() is * called. The resultant struct must be freed using free_delta_index(). */ extern delta_result create_delta_index(const struct source_info *src, struct delta_index *old, struct delta_index **fresh); /* * create_delta_index_from_delta: compute index data from given buffer * * Returns a delta_result status, when DELTA_OK then *fresh is set to a struct * delta_index that should be passed to subsequent create_delta() calls, or to * free_delta_index(). Other values are a failure, and *fresh is unset. * The bytes must be in the form of a delta structure, as generated by * create_delta(). The generated index will only index the insert bytes, and * not any of the control structures. */ extern delta_result create_delta_index_from_delta(const struct source_info *delta, struct delta_index *old, struct delta_index **fresh); /* * free_delta_index: free the index created by create_delta_index() * * Given pointer must be what create_delta_index() returned, or NULL. */ extern void free_delta_index(struct delta_index *index); /* * sizeof_delta_index: returns memory usage of delta index * * Given pointer must be what create_delta_index() returned, or NULL. */ extern unsigned long sizeof_delta_index(struct delta_index *index); /* * create_delta: create a delta from given index for the given buffer * * This function may be called multiple times with different buffers using * the same delta_index pointer. If max_delta_size is non-zero and the * resulting delta is to be larger than max_delta_size then DELTA_SIZE_TOO_BIG * is returned. Otherwise on success, DELTA_OK is returned and *delta_data is * set to a new buffer with the delta data and *delta_size is updated with its * size. That buffer must be freed by the caller. */ extern delta_result create_delta(const struct delta_index *index, const void *buf, unsigned long bufsize, unsigned long *delta_size, unsigned long max_delta_size, void **delta_data); /* the smallest possible delta size is 3 bytes * Target size, Copy command, Copy length */ #define DELTA_SIZE_MIN 3 /* * This must be called twice on the delta data buffer, first to get the * expected source buffer size, and again to get the target buffer size. */ static unsigned long get_delta_hdr_size(unsigned char **datap, const unsigned char *top) { unsigned char *data = *datap; unsigned char cmd; unsigned long size = 0; int i = 0; do { cmd = *data++; size |= (cmd & ~0x80) << i; i += 7; } while (cmd & 0x80 && data < top); *datap = data; return size; } #endif