PageRenderTime 41ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/par2cmdline-0.4-tbb-20100203/recoverypacket.cpp

#
C++ | 127 lines | 65 code | 20 blank | 42 comment | 1 complexity | e3beb3c7b33d50ce7d5be86d9f2d30e7 MD5 | raw file
Possible License(s): GPL-2.0
  1. // This file is part of par2cmdline (a PAR 2.0 compatible file verification and
  2. // repair tool). See http://parchive.sourceforge.net for details of PAR 2.0.
  3. //
  4. // Copyright (c) 2003 Peter Brian Clements
  5. //
  6. // par2cmdline is free software; you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation; either version 2 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // par2cmdline 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, write to the Free Software
  18. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. #include "par2cmdline.h"
  20. #ifdef _MSC_VER
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char THIS_FILE[]=__FILE__;
  24. #define new DEBUG_NEW
  25. #endif
  26. #endif
  27. RecoveryPacket::RecoveryPacket(void)
  28. {
  29. diskfile = NULL;
  30. offset = 0;
  31. packetcontext = NULL;
  32. }
  33. RecoveryPacket::~RecoveryPacket(void)
  34. {
  35. delete packetcontext;
  36. }
  37. // Create a recovery packet.
  38. // The packet header can be almost completely filled in using the supplied
  39. // information and computation of the hash of the packet started immediately.
  40. // The hash will be updated as new data is written to the packet.
  41. void RecoveryPacket::Create(DiskFile *_diskfile,
  42. u64 _offset,
  43. u64 _blocksize,
  44. u32 _exponent,
  45. const MD5Hash &_setid)
  46. {
  47. diskfile = _diskfile;
  48. offset = _offset;
  49. // Record everything we know in the packet.
  50. packet.header.magic = packet_magic;
  51. packet.header.length = sizeof(packet) + _blocksize;
  52. //packet.header.hash; // Not known yet.
  53. packet.header.setid = _setid;
  54. packet.header.type = recoveryblockpacket_type;
  55. packet.exponent = _exponent;
  56. // Start computation of the packet hash
  57. packetcontext = new MD5Context;
  58. packetcontext->Update(&packet.header.setid,
  59. sizeof(RECOVERYBLOCKPACKET)-offsetof(RECOVERYBLOCKPACKET, header.setid));
  60. // Set the data block to immediatly follow the header on disk
  61. datablock.SetLocation(_diskfile, _offset + sizeof(packet));
  62. datablock.SetLength(_blocksize);
  63. }
  64. // Write data from the buffer to the data block on disk
  65. bool RecoveryPacket::WriteData(u64 position,
  66. size_t size,
  67. const void *buffer)
  68. {
  69. // Update the packet hash
  70. packetcontext->Update(buffer, size);
  71. // Write the data to the data block
  72. size_t wrote;
  73. return datablock.WriteData(position, size, buffer, wrote);
  74. }
  75. // Write the header of the packet to disk
  76. bool RecoveryPacket::WriteHeader(void)
  77. {
  78. // Finish computing the packet hash
  79. packetcontext->Final(packet.header.hash);
  80. // Write the header to disk
  81. return diskfile->Write(offset, &packet, sizeof(packet));
  82. }
  83. // Load the recovery packet from disk.
  84. //
  85. // The header of the packet will already have been read from disk. The only
  86. // thing that actually needs to be read is the exponent value.
  87. // The recovery data is not read from disk at this point. Its location
  88. // is recovered in the DataBlock object.
  89. bool RecoveryPacket::Load(DiskFile *_diskfile,
  90. u64 _offset,
  91. PACKET_HEADER &_header)
  92. {
  93. diskfile = _diskfile;
  94. offset = _offset;
  95. // Is the packet actually large enough
  96. if (_header.length <= sizeof(packet))
  97. {
  98. return false;
  99. }
  100. // Save the fixed header
  101. packet.header = _header;
  102. // Set the data block to immediatly follow the header on disk
  103. datablock.SetLocation(diskfile, offset + sizeof(packet));
  104. datablock.SetLength(packet.header.length - sizeof(packet));
  105. // Read the rest of the packet header
  106. return diskfile->Read(offset + sizeof(packet.header), &packet.exponent, sizeof(packet)-sizeof(packet.header));
  107. }