1 // -*- coding: utf-8 -*- 2 // 3 // EmbeddedResource.hxx --- Class for pointing to/accessing an embedded resource 4 // Copyright (C) 2017 Florent Rougon 5 // 6 // This library is free software; you can redistribute it and/or 7 // modify it under the terms of the GNU Library General Public 8 // License as published by the Free Software Foundation; either 9 // version 2 of the License, or (at your option) any later version. 10 // 11 // This library 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 GNU 14 // Library General Public License for more details. 15 // 16 // You should have received a copy of the GNU Library General Public 17 // License along with this library; if not, write to the Free Software 18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19 // MA 02110-1301 USA. 20 21 #ifndef FG_EMBEDDEDRESOURCE_HXX 22 #define FG_EMBEDDEDRESOURCE_HXX 23 24 #include <iosfwd> 25 #include <string> 26 #include <ostream> 27 #include <memory> // std::unique_ptr 28 #include <cstddef> // std::size_t, std::ptrdiff_t 29 30 #include <simgear/io/iostreams/zlibstream.hxx> 31 32 33 namespace simgear 34 { 35 36 // Abstract base class for embedded resources 37 class AbstractEmbeddedResource 38 { 39 public: 40 enum class CompressionType { 41 NONE = 0, 42 ZLIB 43 }; 44 45 // Constructor. 46 // 47 // 'data' and 'size' indicate the resource contents. There is no requirement 48 // of null-termination, including for text data (given how 49 // EmbeddedResourceManager::getString() works, including a null terminator 50 // for text contents is actually counter-productive). The data may be of 51 // arbitrary type and size: binary, text, whatever. The constructed object 52 // (for derived classes since this one is abstract) does *not* hold a copy 53 // of the data, it just keeps a pointer to it and provides methods to access 54 // it. The data must therefore remain available as long as the object is in 55 // use---this class was designed for use with data stored in static 56 // variables. 57 explicit AbstractEmbeddedResource(const char *data, std::size_t size); 58 AbstractEmbeddedResource(const AbstractEmbeddedResource&) = default; 59 AbstractEmbeddedResource(AbstractEmbeddedResource&&) = default; 60 AbstractEmbeddedResource& operator=(const AbstractEmbeddedResource&) = default; 61 AbstractEmbeddedResource& operator=(AbstractEmbeddedResource&&) = default; 62 virtual ~AbstractEmbeddedResource() = default; 63 64 // Return the pointer to beginning-of-resource contents---the same that was 65 // passed to the constructor. 66 const char *rawPtr() const; 67 // Return the resource size, as passed to the constructor. For a compressed 68 // resource, this is the compressed size; such resources provide an 69 // additional uncompressedSize() method. 70 std::size_t rawSize() const; 71 72 // Return an std::string object containing a copy of the resource contents. 73 // For a compressed resource, this is the data obtained after decompression. 74 virtual std::string str() const; 75 // Return an std::streambuf instance providing read-only access to the 76 // resource contents (in uncompressed form for compressed resources). This 77 // allows memory-friendly access to large resources by enabling incremental 78 // processing with transparent decompression for compressed resources. 79 virtual std::unique_ptr<std::streambuf> streambuf() const = 0; 80 // Return an std::istream instance providing read-only access to the 81 // resource contents (in uncompressed form for compressed resources). 82 // 83 // The same remark as for streambuf() applies. std::istream is simply a 84 // higher-level interface than std::streambuf, otherwise both allow the same 85 // kind of processing. 86 virtual std::unique_ptr<std::istream> istream() const = 0; 87 88 // Return the resource compression type. 89 virtual CompressionType compressionType() const = 0; 90 // Return a string description of the resource compression type. Examples: 91 // "none", "zlib". 92 virtual std::string compressionDescr() const = 0; 93 94 private: 95 // Pointer to the start of resource contents 96 const char *_data; 97 // Size of resource contents, in bytes 98 std::size_t _size; 99 }; 100 101 // Class to describe an uncompressed resource. See AbstractEmbeddedResource. 102 class RawEmbeddedResource : public AbstractEmbeddedResource 103 { 104 public: 105 explicit RawEmbeddedResource(const char *data, std::size_t size); 106 107 AbstractEmbeddedResource::CompressionType compressionType() const override; 108 std::string compressionDescr() const override; 109 110 // The str() method is inherited from AbstractEmbeddedResource 111 std::unique_ptr<std::streambuf> streambuf() const override; 112 std::unique_ptr<std::istream> istream() const override; 113 }; 114 115 // Class to describe a zlib-compressed resource. 116 // 117 // Instances of this class point to resource contents stored in the stream 118 // format documented in RFC 1950. 119 class ZlibEmbeddedResource : public AbstractEmbeddedResource 120 { 121 public: 122 explicit ZlibEmbeddedResource(const char *data, std::size_t compressedSize, 123 std::size_t uncompressedSize); 124 125 AbstractEmbeddedResource::CompressionType compressionType() const override; 126 std::string compressionDescr() const override; 127 // Return the resource uncompressed size, in bytes. 128 std::size_t uncompressedSize() const; 129 130 std::string str() const override; 131 std::unique_ptr<std::streambuf> streambuf() const override; 132 std::unique_ptr<std::istream> istream() const override; 133 134 // Getters and setters for parameters used in streambuf() and istream(). 135 // Calling any of the setters affects the subsequent streambuf() and 136 // istream() calls. 137 char* getInputBufferStart(); 138 void setInputBufferStart(char* inBuf); 139 std::size_t getInputBufferSize(); 140 void setInputBufferSize(std::size_t size); 141 char* getOutputBufferStart(); 142 void setOutputBufferStart(char* outBuf); 143 std::size_t getOutputBufferSize(); 144 void setOutputBufferSize(std::size_t size); 145 std::size_t getPutbackSize(); 146 void setPutbackSize(std::size_t size); 147 148 private: 149 std::size_t _uncompressedSize; 150 char* _inBuf; 151 std::size_t _inBufSize; 152 char* _outBuf; 153 std::size_t _outBufSize; 154 std::size_t _putbackSize; 155 }; 156 157 // These functions are essentially intended for troubleshooting purposes. 158 std::ostream& operator<<(std::ostream&, const RawEmbeddedResource&); 159 std::ostream& operator<<(std::ostream&, const ZlibEmbeddedResource&); 160 161 } // of namespace simgear 162 163 #endif // of FG_EMBEDDEDRESOURCE_HXX 164