1/** 2 * Copyright 2013, GitHub, Inc 3 * Copyright 2009-2013, Daniel Lemire, Cliff Moon, 4 * David McIntosh, Robert Becho, Google Inc. and Veronika Zenz 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 */ 19#include"git-compat-util.h" 20#include"ewok.h" 21#include"strbuf.h" 22 23intewah_serialize_native(struct ewah_bitmap *self,int fd) 24{ 25uint32_t write32; 26size_t to_write = self->buffer_size *8; 27 28/* 32 bit -- bit size for the map */ 29 write32 = (uint32_t)self->bit_size; 30if(write(fd, &write32,4) !=4) 31return-1; 32 33/** 32 bit -- number of compressed 64-bit words */ 34 write32 = (uint32_t)self->buffer_size; 35if(write(fd, &write32,4) !=4) 36return-1; 37 38if(write(fd, self->buffer, to_write) != to_write) 39return-1; 40 41/** 32 bit -- position for the RLW */ 42 write32 = self->rlw - self->buffer; 43if(write(fd, &write32,4) !=4) 44return-1; 45 46return(3*4) + to_write; 47} 48 49intewah_serialize_to(struct ewah_bitmap *self, 50int(*write_fun)(void*,const void*,size_t), 51void*data) 52{ 53size_t i; 54 eword_t dump[2048]; 55const size_t words_per_dump =sizeof(dump) /sizeof(eword_t); 56uint32_t bitsize, word_count, rlw_pos; 57 58const eword_t *buffer; 59size_t words_left; 60 61/* 32 bit -- bit size for the map */ 62 bitsize =htonl((uint32_t)self->bit_size); 63if(write_fun(data, &bitsize,4) !=4) 64return-1; 65 66/** 32 bit -- number of compressed 64-bit words */ 67 word_count =htonl((uint32_t)self->buffer_size); 68if(write_fun(data, &word_count,4) !=4) 69return-1; 70 71/** 64 bit x N -- compressed words */ 72 buffer = self->buffer; 73 words_left = self->buffer_size; 74 75while(words_left >= words_per_dump) { 76for(i =0; i < words_per_dump; ++i, ++buffer) 77 dump[i] =htonll(*buffer); 78 79if(write_fun(data, dump,sizeof(dump)) !=sizeof(dump)) 80return-1; 81 82 words_left -= words_per_dump; 83} 84 85if(words_left) { 86for(i =0; i < words_left; ++i, ++buffer) 87 dump[i] =htonll(*buffer); 88 89if(write_fun(data, dump, words_left *8) != words_left *8) 90return-1; 91} 92 93/** 32 bit -- position for the RLW */ 94 rlw_pos = (uint8_t*)self->rlw - (uint8_t*)self->buffer; 95 rlw_pos =htonl(rlw_pos /sizeof(eword_t)); 96 97if(write_fun(data, &rlw_pos,4) !=4) 98return-1; 99 100return(3*4) + (self->buffer_size *8); 101} 102 103static intwrite_strbuf(void*user_data,const void*data,size_t len) 104{ 105struct strbuf *sb = user_data; 106strbuf_add(sb, data, len); 107return len; 108} 109 110intewah_serialize_strbuf(struct ewah_bitmap *self,struct strbuf *sb) 111{ 112returnewah_serialize_to(self, write_strbuf, sb); 113} 114 115ssize_t ewah_read_mmap(struct ewah_bitmap *self,const void*map,size_t len) 116{ 117const uint8_t*ptr = map; 118size_t data_len; 119size_t i; 120 121if(len <sizeof(uint32_t)) 122returnerror("corrupt ewah bitmap: eof before bit size"); 123 self->bit_size =get_be32(ptr); 124 ptr +=sizeof(uint32_t); 125 len -=sizeof(uint32_t); 126 127if(len <sizeof(uint32_t)) 128returnerror("corrupt ewah bitmap: eof before length"); 129 self->buffer_size = self->alloc_size =get_be32(ptr); 130 ptr +=sizeof(uint32_t); 131 len -=sizeof(uint32_t); 132 133REALLOC_ARRAY(self->buffer, self->alloc_size); 134 135/* 136 * Copy the raw data for the bitmap as a whole chunk; 137 * if we're in a little-endian platform, we'll perform 138 * the endianness conversion in a separate pass to ensure 139 * we're loading 8-byte aligned words. 140 */ 141 data_len =st_mult(self->buffer_size,sizeof(eword_t)); 142if(len < data_len) 143returnerror("corrupt ewah bitmap: eof in data " 144"(%"PRIuMAX" bytes short)", 145(uintmax_t)(data_len - len)); 146memcpy(self->buffer, ptr, data_len); 147 ptr += data_len; 148 len -= data_len; 149 150for(i =0; i < self->buffer_size; ++i) 151 self->buffer[i] =ntohll(self->buffer[i]); 152 153if(len <sizeof(uint32_t)) 154returnerror("corrupt ewah bitmap: eof before rlw"); 155 self->rlw = self->buffer +get_be32(ptr); 156 ptr +=sizeof(uint32_t); 157 len -=sizeof(uint32_t); 158 159return ptr - (const uint8_t*)map; 160}