diff options
Diffstat (limited to 'ewah/ewah_io.c')
-rw-r--r-- | ewah/ewah_io.c | 119 |
1 files changed, 22 insertions, 97 deletions
diff --git a/ewah/ewah_io.c b/ewah/ewah_io.c index 61f6a43579..9035ee65ea 100644 --- a/ewah/ewah_io.c +++ b/ewah/ewah_io.c @@ -14,39 +14,12 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "git-compat-util.h" #include "ewok.h" #include "strbuf.h" -int ewah_serialize_native(struct ewah_bitmap *self, int fd) -{ - uint32_t write32; - size_t to_write = self->buffer_size * 8; - - /* 32 bit -- bit size for the map */ - write32 = (uint32_t)self->bit_size; - if (write(fd, &write32, 4) != 4) - return -1; - - /** 32 bit -- number of compressed 64-bit words */ - write32 = (uint32_t)self->buffer_size; - if (write(fd, &write32, 4) != 4) - return -1; - - if (write(fd, self->buffer, to_write) != to_write) - return -1; - - /** 32 bit -- position for the RLW */ - write32 = self->rlw - self->buffer; - if (write(fd, &write32, 4) != 4) - return -1; - - return (3 * 4) + to_write; -} - int ewah_serialize_to(struct ewah_bitmap *self, int (*write_fun)(void *, const void *, size_t), void *data) @@ -101,16 +74,6 @@ int ewah_serialize_to(struct ewah_bitmap *self, return (3 * 4) + (self->buffer_size * 8); } -static int write_helper(void *fd, const void *buf, size_t len) -{ - return write((intptr_t)fd, buf, len); -} - -int ewah_serialize(struct ewah_bitmap *self, int fd) -{ - return ewah_serialize_to(self, write_helper, (void *)(intptr_t)fd); -} - static int write_strbuf(void *user_data, const void *data, size_t len) { struct strbuf *sb = user_data; @@ -123,16 +86,23 @@ int ewah_serialize_strbuf(struct ewah_bitmap *self, struct strbuf *sb) return ewah_serialize_to(self, write_strbuf, sb); } -int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len) +ssize_t ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len) { const uint8_t *ptr = map; + size_t data_len; size_t i; + if (len < sizeof(uint32_t)) + return error("corrupt ewah bitmap: eof before bit size"); self->bit_size = get_be32(ptr); ptr += sizeof(uint32_t); + len -= sizeof(uint32_t); + if (len < sizeof(uint32_t)) + return error("corrupt ewah bitmap: eof before length"); self->buffer_size = self->alloc_size = get_be32(ptr); ptr += sizeof(uint32_t); + len -= sizeof(uint32_t); REALLOC_ARRAY(self->buffer, self->alloc_size); @@ -142,68 +112,23 @@ int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len) * the endianness conversion in a separate pass to ensure * we're loading 8-byte aligned words. */ - memcpy(self->buffer, ptr, self->buffer_size * sizeof(uint64_t)); - ptr += self->buffer_size * sizeof(uint64_t); + data_len = st_mult(self->buffer_size, sizeof(eword_t)); + if (len < data_len) + return error("corrupt ewah bitmap: eof in data " + "(%"PRIuMAX" bytes short)", + (uintmax_t)(data_len - len)); + memcpy(self->buffer, ptr, data_len); + ptr += data_len; + len -= data_len; for (i = 0; i < self->buffer_size; ++i) self->buffer[i] = ntohll(self->buffer[i]); + if (len < sizeof(uint32_t)) + return error("corrupt ewah bitmap: eof before rlw"); self->rlw = self->buffer + get_be32(ptr); + ptr += sizeof(uint32_t); + len -= sizeof(uint32_t); - return (3 * 4) + (self->buffer_size * 8); -} - -int ewah_deserialize(struct ewah_bitmap *self, int fd) -{ - size_t i; - eword_t dump[2048]; - const size_t words_per_dump = sizeof(dump) / sizeof(eword_t); - uint32_t bitsize, word_count, rlw_pos; - - eword_t *buffer = NULL; - size_t words_left; - - ewah_clear(self); - - /* 32 bit -- bit size for the map */ - if (read(fd, &bitsize, 4) != 4) - return -1; - - self->bit_size = (size_t)ntohl(bitsize); - - /** 32 bit -- number of compressed 64-bit words */ - if (read(fd, &word_count, 4) != 4) - return -1; - - self->buffer_size = self->alloc_size = (size_t)ntohl(word_count); - REALLOC_ARRAY(self->buffer, self->alloc_size); - - /** 64 bit x N -- compressed words */ - buffer = self->buffer; - words_left = self->buffer_size; - - while (words_left >= words_per_dump) { - if (read(fd, dump, sizeof(dump)) != sizeof(dump)) - return -1; - - for (i = 0; i < words_per_dump; ++i, ++buffer) - *buffer = ntohll(dump[i]); - - words_left -= words_per_dump; - } - - if (words_left) { - if (read(fd, dump, words_left * 8) != words_left * 8) - return -1; - - for (i = 0; i < words_left; ++i, ++buffer) - *buffer = ntohll(dump[i]); - } - - /** 32 bit -- position for the RLW */ - if (read(fd, &rlw_pos, 4) != 4) - return -1; - - self->rlw = self->buffer + ntohl(rlw_pos); - return 0; + return ptr - (const uint8_t *)map; } |