1 /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */ 2 3 /* libstaroffice 4 * Version: MPL 2.0 / LGPLv2+ 5 * 6 * The contents of this file are subject to the Mozilla Public License Version 7 * 2.0 (the "License"); you may not use this file except in compliance with 8 * the License or as specified alternatively below. You may obtain a copy of 9 * the License at http://www.mozilla.org/MPL/ 10 * 11 * Software distributed under the License is distributed on an "AS IS" basis, 12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13 * for the specific language governing rights and limitations under the 14 * License. 15 * 16 * Major Contributor(s): 17 * Copyright (C) 2002 William Lachance (wrlach@gmail.com) 18 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net) 19 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch) 20 * Copyright (C) 2006, 2007 Andrew Ziem 21 * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr) 22 * 23 * 24 * All Rights Reserved. 25 * 26 * For minor contributions see the git repository. 27 * 28 * Alternatively, the contents of this file may be used under the terms of 29 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"), 30 * in which case the provisions of the LGPLv2+ are applicable 31 * instead of those above. 32 */ 33 34 #ifndef STOFF_INPUT_STREAM_H 35 #define STOFF_INPUT_STREAM_H 36 37 #include <string> 38 #include <vector> 39 40 #include <librevenge/librevenge.h> 41 #include <librevenge-stream/librevenge-stream.h> 42 #include "libstaroffice_internal.hxx" 43 44 /*! \class STOFFInputStream 45 * \brief Internal class used to read the file stream 46 * Internal class used to read the file stream, 47 * this class adds some usefull functions to the basic librevenge::RVNGInputStream: 48 * - read number (int8, int16, int32) in low or end endian 49 * - selection of a section of a stream 50 * - read block of data 51 * - interface with modified librevenge::RVNGOLEStream 52 */ 53 class STOFFInputStream 54 { 55 public: 56 /*!\brief creates a stream with given endian 57 * \param input the given input 58 * \param inverted must be set to true for pc doc and ole part and to false for mac doc 59 */ 60 STOFFInputStream(std::shared_ptr<librevenge::RVNGInputStream> input, bool inverted); 61 62 /*!\brief creates a stream with given endian from an existing input 63 * 64 * Note: this functions does not delete input 65 */ 66 STOFFInputStream(librevenge::RVNGInputStream *input, bool inverted); 67 //! destructor 68 ~STOFFInputStream(); 69 70 //! returns the basic librevenge::RVNGInputStream input()71 std::shared_ptr<librevenge::RVNGInputStream> input() 72 { 73 return m_stream; 74 } 75 //! returns a new input stream corresponding to a librevenge::RVNGBinaryData 76 static std::shared_ptr<STOFFInputStream> get(librevenge::RVNGBinaryData const &data, bool inverted); 77 78 //! returns the endian mode (see constructor) readInverted() const79 bool readInverted() const 80 { 81 return m_inverseRead; 82 } 83 //! sets the endian mode setReadInverted(bool newVal)84 void setReadInverted(bool newVal) 85 { 86 m_inverseRead = newVal; 87 } 88 // 89 // Position: access 90 // 91 92 /*! \brief seeks to a offset position, from actual, beginning or ending position 93 * \return 0 if ok 94 */ 95 int seek(long offset, librevenge::RVNG_SEEK_TYPE seekType); 96 //! returns actual offset position 97 long tell(); 98 //! returns the stream size size() const99 long size() const 100 { 101 return m_streamSize; 102 } 103 //! checks if a position is or not a valid file position checkPosition(long pos) const104 bool checkPosition(long pos) const 105 { 106 if (pos < 0) return false; 107 return pos<=m_streamSize; 108 } 109 //! returns true if we are at the end of the section/file 110 bool isEnd(); 111 112 // 113 // get data 114 // 115 116 //! returns the value of the next caracters or -1, but does not increment the position counter 117 int peek(); 118 //! operator>> for bool operator >>(bool & res)119 STOFFInputStream &operator>>(bool &res) 120 { 121 res=readULong(1)!=0 ? true : false; 122 return *this; 123 } 124 //! operator>> for uint8_t operator >>(uint8_t & res)125 STOFFInputStream &operator>>(uint8_t &res) 126 { 127 res=static_cast<uint8_t>(readULong(1)); 128 return *this; 129 } 130 //! operator>> for int8_t operator >>(int8_t & res)131 STOFFInputStream &operator>>(int8_t &res) 132 { 133 res=static_cast<int8_t>(readLong(1)); 134 return *this; 135 } 136 //! operator>> for uint16_t operator >>(uint16_t & res)137 STOFFInputStream &operator>>(uint16_t &res) 138 { 139 res=static_cast<uint16_t>(readULong(2)); 140 return *this; 141 } 142 //! operator>> for int16_t operator >>(int16_t & res)143 STOFFInputStream &operator>>(int16_t &res) 144 { 145 res=static_cast<int16_t>(readLong(2)); 146 return *this; 147 } 148 //! operator>> for uint32_t operator >>(uint32_t & res)149 STOFFInputStream &operator>>(uint32_t &res) 150 { 151 res=static_cast<uint32_t>(readULong(4)); 152 return *this; 153 } 154 //! operator>> for int32_t operator >>(int32_t & res)155 STOFFInputStream &operator>>(int32_t &res) 156 { 157 res=static_cast<int32_t>(readLong(4)); 158 return *this; 159 } 160 //! operator>> for double operator >>(double & res)161 STOFFInputStream &operator>>(double &res) 162 { 163 bool isNan; 164 long pos=tell(); 165 if (!readDoubleReverted8(res, isNan)) { 166 STOFF_DEBUG_MSG(("STOFFInputStream::operator>>: can not read a double\n")); 167 seek(pos+8, librevenge::RVNG_SEEK_SET); 168 res=0; 169 } 170 return *this; 171 } 172 //! returns a uint8, uint16, uint32 readed from actualPos readULong(int num)173 unsigned long readULong(int num) 174 { 175 return readULong(m_stream.get(), num, 0, m_inverseRead); 176 } 177 //! return a int8, int16, int32 readed from actualPos 178 long readLong(int num); 179 //! try to read a color 180 bool readColor(STOFFColor &color); 181 //! read a compressed long (pstm.cxx:ReadCompressed) 182 bool readCompressedLong(long &res); 183 //! read a compressed unsigned long (sw_sw3imp.cxx Sw3IoImp::InULong) 184 bool readCompressedULong(unsigned long &res); 185 //! try to read a double of size 8: 1.5 bytes exponent, 6.5 bytes mantisse 186 bool readDouble8(double &res, bool &isNotANumber); 187 //! try to read a double of size 8: 6.5 bytes mantisse, 1.5 bytes exponent 188 bool readDoubleReverted8(double &res, bool &isNotANumber); 189 //! try to read a double of size 10: 2 bytes exponent, 8 bytes mantisse 190 bool readDouble10(double &res, bool &isNotANumber); 191 /**! reads numbytes data, WITHOUT using any endian or section consideration 192 * \return a pointer to the read elements 193 */ 194 const uint8_t *read(size_t numBytes, unsigned long &numBytesRead); 195 /*! \brief internal function used to read num byte, 196 * - where a is the previous read data 197 */ 198 static unsigned long readULong(librevenge::RVNGInputStream *stream, int num, unsigned long a, bool inverseRead); 199 200 //! reads a librevenge::RVNGBinaryData with a given size in the actual section/file 201 bool readDataBlock(long size, librevenge::RVNGBinaryData &data); 202 //! reads a librevenge::RVNGBinaryData from actPos to the end of the section/file 203 bool readEndDataBlock(librevenge::RVNGBinaryData &data); 204 205 // 206 // OLE/Zip access 207 // 208 209 //! return true if the stream is ole 210 bool isStructured(); 211 //! returns the number of substream 212 unsigned subStreamCount(); 213 //! returns the name of the i^th substream 214 std::string subStreamName(unsigned id); 215 216 //! return a new stream for a ole zone 217 std::shared_ptr<STOFFInputStream> getSubStreamByName(std::string const &name); 218 //! return a new stream for a ole zone 219 std::shared_ptr<STOFFInputStream> getSubStreamById(unsigned id); 220 221 // 222 // Resource Fork access 223 // 224 225 /** returns true if the data fork block exists */ hasDataFork() const226 bool hasDataFork() const 227 { 228 return bool(m_stream); 229 } 230 231 protected: 232 //! update the stream size ( must be called in the constructor ) 233 void updateStreamSize(); 234 //! internal function used to read a byte 235 static uint8_t readU8(librevenge::RVNGInputStream *stream); 236 237 private: 238 STOFFInputStream(STOFFInputStream const &orig); 239 STOFFInputStream &operator=(STOFFInputStream const &orig); 240 241 protected: 242 //! the initial input 243 std::shared_ptr<librevenge::RVNGInputStream> m_stream; 244 //! the stream size 245 long m_streamSize; 246 247 //! big or normal endian 248 bool m_inverseRead; 249 }; 250 251 #endif 252 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: 253