$treeview $search $mathjax $extrastylesheet
librsync
2.0.2
$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 signature magic value. Must be set to a valid magic value. 00056 * 00057 * \param block_len the block size to use. Must be > 0. 00058 * 00059 * \param strong_len the strongsum size to use. Must be <= the max strongsum 00060 * size for the strongsum type indicated by the magic value. Use 0 to use the 00061 * recommended size for the provided magic value. 00062 * 00063 * \param sig_fsize signature file size to preallocate required storage for. 00064 * Use 0 if size is unknown. */ 00065 rs_result rs_signature_init(rs_signature_t *sig, int magic, int block_len, 00066 int strong_len, rs_long_t sig_fsize); 00067 00068 /** Destroy an rs_signature instance. */ 00069 void rs_signature_done(rs_signature_t *sig); 00070 00071 /** Add a block to an rs_signature instance. */ 00072 rs_block_sig_t *rs_signature_add_block(rs_signature_t *sig, 00073 rs_weak_sum_t weak_sum, 00074 rs_strong_sum_t *strong_sum); 00075 00076 /** Find a matching block offset in a signature. */ 00077 rs_long_t rs_signature_find_match(rs_signature_t *sig, rs_weak_sum_t weak_sum, 00078 void const *buf, size_t len); 00079 00080 /** Log the rs_signature_find_match() stats. */ 00081 void rs_signature_log_stats(rs_signature_t const *sig); 00082 00083 /** Assert that a signature is valid. 00084 * 00085 * We don't use a static inline function here so that assert failure output 00086 * points at where rs_signature_check() was called from. */ 00087 #define rs_signature_check(sig) do {\ 00088 assert(((sig)->magic == RS_BLAKE2_SIG_MAGIC && (sig)->strong_sum_len <= RS_BLAKE2_SUM_LENGTH)\ 00089 || ((sig)->magic == RS_MD4_SIG_MAGIC && (sig)->strong_sum_len <= RS_MD4_SUM_LENGTH));\ 00090 assert(0 < (sig)->block_len);\ 00091 assert(0 < (sig)->strong_sum_len && (sig)->strong_sum_len <= RS_MAX_STRONG_SUM_LENGTH);\ 00092 assert(0 <= (sig)->count && (sig)->count <= (sig)->size);\ 00093 assert(!(sig)->hashtable || (sig)->hashtable->count <= (sig)->count);\ 00094 } while (0) 00095 00096 /** Calculate the strong sum of a buffer. */ 00097 static inline void rs_signature_calc_strong_sum(rs_signature_t const *sig, 00098 void const *buf, size_t len, 00099 rs_strong_sum_t *sum) 00100 { 00101 if (sig->magic == RS_BLAKE2_SIG_MAGIC) { 00102 rs_calc_blake2_sum(buf, len, sum); 00103 } else { 00104 rs_calc_md4_sum(buf, len, sum); 00105 } 00106 }