chunked_helpers.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #include <util/ysaveload.h>
  2. #include "chunked_helpers.h"
  3. TBlob GetBlock(const TBlob& blob, size_t index) {
  4. TChunkedDataReader reader(blob);
  5. if (index >= reader.GetBlocksCount())
  6. ythrow yexception() << "index " << index << " is >= than block count " << reader.GetBlocksCount();
  7. size_t begin = (const char*)reader.GetBlock(index) - (const char*)blob.Data();
  8. return blob.SubBlob(begin, begin + reader.GetBlockLen(index));
  9. }
  10. /*************************** TNamedChunkedDataReader ***************************/
  11. static const char* NamedChunkedDataMagic = "NamedChunkedData";
  12. TNamedChunkedDataReader::TNamedChunkedDataReader(const TBlob& blob)
  13. : TChunkedDataReader(blob)
  14. {
  15. if (TChunkedDataReader::GetBlocksCount() < 1)
  16. throw yexception() << "Too few blocks";
  17. size_t block = TChunkedDataReader::GetBlocksCount() - 1;
  18. size_t magicLen = strlen(NamedChunkedDataMagic);
  19. if (GetBlockLen(block) < magicLen || memcmp(GetBlock(block), NamedChunkedDataMagic, magicLen) != 0)
  20. throw yexception() << "Not a valid named chunked data file";
  21. TMemoryInput input(static_cast<const char*>(GetBlock(block)) + magicLen, GetBlockLen(block) - magicLen);
  22. Load(&input, Names);
  23. size_t index = 0;
  24. for (TVector<TString>::const_iterator it = Names.begin(); it != Names.end(); ++it, ++index) {
  25. if (!it->empty())
  26. NameToIndex[*it] = index;
  27. }
  28. }
  29. /*************************** TNamedChunkedDataWriter ***************************/
  30. TNamedChunkedDataWriter::TNamedChunkedDataWriter(IOutputStream& slave)
  31. : TChunkedDataWriter(slave)
  32. {
  33. }
  34. TNamedChunkedDataWriter::~TNamedChunkedDataWriter() {
  35. }
  36. void TNamedChunkedDataWriter::NewBlock() {
  37. NewBlock("");
  38. }
  39. void TNamedChunkedDataWriter::NewBlock(const TString& name) {
  40. if (!name.empty()) {
  41. if (NameToIndex.count(name) != 0)
  42. throw yexception() << "Block name is not unique";
  43. NameToIndex[name] = Names.size();
  44. }
  45. Names.push_back(name);
  46. TChunkedDataWriter::NewBlock();
  47. }
  48. void TNamedChunkedDataWriter::WriteFooter() {
  49. NewBlock("");
  50. Write(NamedChunkedDataMagic);
  51. Save(this, Names);
  52. TChunkedDataWriter::WriteFooter();
  53. }