1/* 2 * Copyright (C) 2005 Junio C Hamano 3 * The delta-parsing part is almost straight copy of patch-delta.c 4 * which is (C) 2005 Nicolas Pitre <nico@cam.org>. 5 */ 6#include <stdlib.h> 7#include <string.h> 8#include <limits.h> 9#include"delta.h" 10#include"count-delta.h" 11 12/* 13 * NOTE. We do not _interpret_ delta fully. As an approximation, we 14 * just count the number of bytes that are copied from the source, and 15 * the number of literal data bytes that are inserted. 16 * 17 * Number of bytes that are _not_ copied from the source is deletion, 18 * and number of inserted literal bytes are addition, so sum of them 19 * is the extent of damage. xdelta can express an edit that copies 20 * data inside of the destination which originally came from the 21 * source. We do not count that in the following routine, so we are 22 * undercounting the source material that remains in the final output 23 * that way. 24 */ 25intcount_delta(void*delta_buf,unsigned long delta_size, 26unsigned long*src_copied,unsigned long*literal_added) 27{ 28unsigned long copied_from_source, added_literal; 29const unsigned char*data, *top; 30unsigned char cmd; 31unsigned long src_size, dst_size, out; 32 33if(delta_size < DELTA_SIZE_MIN) 34return-1; 35 36 data = delta_buf; 37 top = delta_buf + delta_size; 38 39 src_size =get_delta_hdr_size(&data); 40 dst_size =get_delta_hdr_size(&data); 41 42 added_literal = copied_from_source = out =0; 43while(data < top) { 44 cmd = *data++; 45if(cmd &0x80) { 46unsigned long cp_off =0, cp_size =0; 47if(cmd &0x01) cp_off = *data++; 48if(cmd &0x02) cp_off |= (*data++ <<8); 49if(cmd &0x04) cp_off |= (*data++ <<16); 50if(cmd &0x08) cp_off |= (*data++ <<24); 51if(cmd &0x10) cp_size = *data++; 52if(cmd &0x20) cp_size |= (*data++ <<8); 53if(cmd &0x40) cp_size |= (*data++ <<16); 54if(cp_size ==0) cp_size =0x10000; 55 56 copied_from_source += cp_size; 57 out += cp_size; 58}else{ 59/* write literal into dst */ 60 added_literal += cmd; 61 out += cmd; 62 data += cmd; 63} 64} 65 66/* sanity check */ 67if(data != top || out != dst_size) 68return-1; 69 70/* delete size is what was _not_ copied from source. 71 * edit size is that and literal additions. 72 */ 73*src_copied = copied_from_source; 74*literal_added = added_literal; 75return0; 76}