int32_t multiround_hash_table::_haser_first_round (file_reader & reader , hasher_stream & stream , std::set<hole_t> & holes) const { if (!holes.empty ()) { std::string errmsg = fmt_string ("Holes must be empty."); THROW_XDELTA_EXCEPTION (errmsg); } hole_t hole; hole.offset = 0; bool round = true; try { reader.open_file (); // sometimes this will throw. hole.length = reader.get_file_size (); holes.insert (hole); } catch (...) { round = false; } if (!round) { hash_table::hash_it (reader, stream); return -1; } int32_t blk_len = (uint32_t)(hole.length / multiround_base ()); if (blk_len > MULTIROUND_MAX_BLOCK_SIZE) blk_len = MULTIROUND_MAX_BLOCK_SIZE; if (blk_len < XDELTA_BLOCK_SIZE) blk_len = XDELTA_BLOCK_SIZE; stream.start_hash_stream (reader.get_fname (), blk_len); rs_mdfour_t ctx; rs_mdfour_begin(&ctx); read_and_hash (reader, stream, hole.length, blk_len, hole.offset, &ctx); uchar_t file_hash[DIGEST_BYTES]; memset (&file_hash, 0, sizeof (file_hash)); rs_mdfour_result (&ctx, file_hash); bool neednextround = stream.end_first_round (file_hash); return (neednextround ? blk_len : -1); }
// // used the hash_table object receive from remote host // and send a hash stream to the remote host. // void hash_table::hash_it (file_reader & reader, hasher_stream & stream) const { rs_mdfour_t ctx; rs_mdfour_begin(&ctx); uint64_t filsize = 0; try { int32_t f_blk_len = 0; if (reader.exist_file ()) { try { reader.open_file (); // sometimes this will throw. filsize = reader.get_file_size (); f_blk_len = get_xdelta_block_size (filsize); } catch (...) { stream.start_hash_stream (reader.get_fname (), 0); throw; } stream.start_hash_stream (reader.get_fname (), f_blk_len); } else { std::string mesg = fmt_string ("File %s not exists." , reader.get_fname ().c_str ()); stream.start_hash_stream (reader.get_fname (), 0); stream.on_error (mesg, ENOENT); goto end; } read_and_hash (reader, stream, filsize, f_blk_len, 0, &ctx); } catch (xdelta_exception &e) { stream.on_error (e.what (), e.get_errno ()); } end: uchar_t file_hash[DIGEST_BYTES]; memset (file_hash, 0, sizeof (file_hash)); rs_mdfour_result (&ctx, file_hash); reader.close_file (); stream.end_hash_stream (file_hash, filsize); return; }