Decompressor.cc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright (C) 2011 Michael McMaster <michael@codesrc.com>
  2. //
  3. // This file is part of libzipper.
  4. //
  5. // libzipper is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // libzipper is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with libzipper. If not, see <http://www.gnu.org/licenses/>.
  17. #include "zipper.hh"
  18. #include "util.hh"
  19. #include "gzip.hh"
  20. #include "zip.hh"
  21. using namespace zipper;
  22. namespace
  23. {
  24. class PlainFile : public CompressedFile
  25. {
  26. public:
  27. PlainFile(const ReaderPtr& reader) :
  28. m_reader(reader)
  29. {}
  30. virtual bool isDecompressSupported() const { return true; }
  31. virtual const std::string& getPath() const
  32. {
  33. return m_reader->getSourceName();
  34. }
  35. virtual zsize_t getCompressedSize() const
  36. {
  37. return m_reader->getSize();
  38. }
  39. virtual zsize_t getUncompressedSize() const
  40. {
  41. return m_reader->getSize();
  42. }
  43. virtual void decompress(Writer& writer)
  44. {
  45. enum Constants
  46. {
  47. ChunkSize = 64*1024
  48. };
  49. zsize_t end(m_reader->getSize());
  50. for (zsize_t pos(0); pos < end; pos += ChunkSize)
  51. {
  52. uint8_t buf[ChunkSize];
  53. size_t bytes(
  54. std::min(zsize_t(ChunkSize), end - pos)
  55. );
  56. m_reader->readData(pos, bytes, &buf[0]);
  57. writer.writeData(pos, bytes, &buf[0]);
  58. }
  59. }
  60. virtual const timeval& getModificationTime() const
  61. {
  62. return m_reader->getModTime();
  63. }
  64. private:
  65. ReaderPtr m_reader;
  66. };
  67. }
  68. class Decompressor::DecompressorImpl
  69. {
  70. public:
  71. DecompressorImpl(const ReaderPtr& reader) :
  72. m_reader(reader),
  73. m_format(Container_none)
  74. {
  75. if (isZip(reader))
  76. {
  77. m_format = Container_zip;
  78. m_entries = unzip(reader);
  79. }
  80. else if (isGzip(reader))
  81. {
  82. m_format = Container_gzip;
  83. m_entries = ungzip(reader);
  84. }
  85. else
  86. {
  87. m_format = Container_none;
  88. m_entries.push_back(
  89. CompressedFilePtr(new PlainFile(reader))
  90. );
  91. }
  92. }
  93. ContainerFormat getContainerFormat() const { return m_format; }
  94. std::vector<CompressedFilePtr> getEntries() const { return m_entries; }
  95. private:
  96. ReaderPtr m_reader;
  97. ContainerFormat m_format;
  98. std::vector<CompressedFilePtr> m_entries;
  99. };
  100. Decompressor::Decompressor(const ReaderPtr& reader) :
  101. m_decompressor(new DecompressorImpl(reader))
  102. {
  103. }
  104. Decompressor::Decompressor(Reader& reader) :
  105. m_decompressor(
  106. new DecompressorImpl(ReaderPtr(&reader, dummy_delete<Reader>()))
  107. )
  108. {
  109. }
  110. Decompressor::~Decompressor()
  111. {
  112. delete m_decompressor;
  113. }
  114. ContainerFormat
  115. Decompressor::getContainerFormat() const
  116. {
  117. return m_decompressor->getContainerFormat();
  118. }
  119. std::vector<CompressedFilePtr>
  120. Decompressor::getEntries() const
  121. {
  122. return m_decompressor->getEntries();
  123. }