$treeview $search $mathjax $extrastylesheet
librsync
2.3.0
$projectbrief
|
$projectbrief
|
$searchbox |
00001 /*= -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- 00002 * 00003 * librsync -- the library for network deltas 00004 * 00005 * Copyright (C) 1999, 2000, 2001 by Martin Pool <mbp@sourcefrog.net> 00006 * Copyright (C) 1999 by Andrew Tridgell <tridge@samba.org> 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public License 00010 * as published by the Free Software Foundation; either version 2.1 of 00011 * the License, or (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, but 00014 * WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00021 */ 00022 00023 #include <assert.h> 00024 #include "hashtable.h" 00025 #include "checksum.h" 00026 00027 /** Signature of a single block. */ 00028 typedef struct rs_block_sig { 00029 rs_weak_sum_t weak_sum; /**< Block's weak checksum. */ 00030 rs_strong_sum_t strong_sum; /**< Block's strong checksum. */ 00031 } rs_block_sig_t; 00032 00033 /** Signature of a whole file. 00034 * 00035 * This includes the all the block sums generated for a file and datastructures 00036 * for fast matching against them. */ 00037 struct rs_signature { 00038 int magic; /**< The signature magic value. */ 00039 int block_len; /**< The block length. */ 00040 int strong_sum_len; /**< The block strong sum length. */ 00041 int count; /**< Total number of blocks. */ 00042 int size; /**< Total number of blocks allocated. */ 00043 void *block_sigs; /**< The packed block_sigs for all blocks. */ 00044 hashtable_t *hashtable; /**< The hashtable for finding matches. */ 00045 /* The is extra stats not included in the hashtable stats. */ 00046 #ifndef HASHTABLE_NSTATS 00047 long calc_strong_count; /**< The count of strongsum calcs done. */ 00048 #endif 00049 }; 00050 00051 /** Initialize an rs_signature instance. 00052 * 00053 * \param *sig the signature to initialize. 00054 * 00055 * \param magic - the magic type to use (0 for "recommended"). 00056 * 00057 * \param block_len - the block length to use (0 for "recommended"). 00058 * 00059 * \param strong_len - the strongsum length to use (0 for "maximum", -1 for 00060 * "minimum"). Must be <= the max strongsum size for the strongsum type 00061 * indicated by the magic value. 00062 * 00063 * \param sig_fsize - the signature file size (-1 for "unknown"). Used to 00064 * preallocate required storage. */ 00065 rs_result rs_signature_init(rs_signature_t *sig, rs_magic_number magic, 00066 size_t block_len, size_t strong_len, 00067 rs_long_t sig_fsize); 00068 00069 /** Destroy an rs_signature instance. */ 00070 void rs_signature_done(rs_signature_t *sig); 00071 00072 /** Add a block to an rs_signature instance. */ 00073 rs_block_sig_t *rs_signature_add_block(rs_signature_t *sig, 00074 rs_weak_sum_t weak_sum, 00075 rs_strong_sum_t *strong_sum); 00076 00077 /** Find a matching block offset in a signature. */ 00078 rs_long_t rs_signature_find_match(rs_signature_t *sig, rs_weak_sum_t weak_sum, 00079 void const *buf, size_t len); 00080 00081 /** Assert that rs_sig_args() args for rs_signature_init() are valid. 00082 * 00083 * We don't use a static inline function here so that assert failure output 00084 * points at where rs_sig_args_check() was called from. */ 00085 #define rs_sig_args_check(magic, block_len, strong_len) do {\ 00086 assert(((magic) & 0xffffff00) == (RS_MD4_SIG_MAGIC & 0xffffff00));\ 00087 assert(((magic) & 0xf0) == 0x30 || ((magic) & 0xf0) == 0x40);\ 00088 assert((((magic) & 0x0f) == 0x06 &&\ 00089 (strong_len) <= RS_MD4_SUM_LENGTH) ||\ 00090 (((magic) & 0x0f) == 0x07 &&\ 00091 (strong_len) <= RS_BLAKE2_SUM_LENGTH));\ 00092 assert(0 < (block_len));\ 00093 assert(0 < (strong_len) && (strong_len) <= RS_MAX_STRONG_SUM_LENGTH);\ 00094 } while (0) 00095 00096 /** Assert that a signature is valid. 00097 * 00098 * We don't use a static inline function here so that assert failure output 00099 * points at where rs_signature_check() was called from. */ 00100 #define rs_signature_check(sig) do {\ 00101 rs_sig_args_check((sig)->magic, (sig)->block_len, (sig)->strong_sum_len);\ 00102 assert(0 <= (sig)->count && (sig)->count <= (sig)->size);\ 00103 assert(!(sig)->hashtable || (sig)->hashtable->count <= (sig)->count);\ 00104 } while (0) 00105 00106 /** Get the weaksum kind for a signature. */ 00107 static inline weaksum_kind_t rs_signature_weaksum_kind(rs_signature_t const 00108 *sig) 00109 { 00110 return (sig->magic & 0xf0) == 0x30 ? RS_ROLLSUM : RS_RABINKARP; 00111 } 00112 00113 /** Get the strongsum kind for a signature. */ 00114 static inline strongsum_kind_t rs_signature_strongsum_kind(rs_signature_t const 00115 *sig) 00116 { 00117 return (sig->magic & 0x0f) == 0x06 ? RS_MD4 : RS_BLAKE2; 00118 } 00119 00120 /** Calculate the weak sum of a buffer. */ 00121 static inline rs_weak_sum_t rs_signature_calc_weak_sum(rs_signature_t const 00122 *sig, void const *buf, 00123 size_t len) 00124 { 00125 return rs_calc_weak_sum(rs_signature_weaksum_kind(sig), buf, len); 00126 } 00127 00128 /** Calculate the strong sum of a buffer. */ 00129 static inline void rs_signature_calc_strong_sum(rs_signature_t const *sig, 00130 void const *buf, size_t len, 00131 rs_strong_sum_t *sum) 00132 { 00133 rs_calc_strong_sum(rs_signature_strongsum_kind(sig), buf, len, sum); 00134 }