STOFFInputStream.hxx
Go to the documentation of this file.
00001 /* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
00002 
00003 /* libstaroffice
00004 * Version: MPL 2.0 / LGPLv2+
00005 *
00006 * The contents of this file are subject to the Mozilla Public License Version
00007 * 2.0 (the "License"); you may not use this file except in compliance with
00008 * the License or as specified alternatively below. You may obtain a copy of
00009 * the License at http://www.mozilla.org/MPL/
00010 *
00011 * Software distributed under the License is distributed on an "AS IS" basis,
00012 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013 * for the specific language governing rights and limitations under the
00014 * License.
00015 *
00016 * Major Contributor(s):
00017 * Copyright (C) 2002 William Lachance (wrlach@gmail.com)
00018 * Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
00019 * Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
00020 * Copyright (C) 2006, 2007 Andrew Ziem
00021 * Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
00022 *
00023 *
00024 * All Rights Reserved.
00025 *
00026 * For minor contributions see the git repository.
00027 *
00028 * Alternatively, the contents of this file may be used under the terms of
00029 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
00030 * in which case the provisions of the LGPLv2+ are applicable
00031 * instead of those above.
00032 */
00033 
00034 #ifndef STOFF_INPUT_STREAM_H
00035 #define STOFF_INPUT_STREAM_H
00036 
00037 #include <string>
00038 #include <vector>
00039 
00040 #include <librevenge/librevenge.h>
00041 #include <librevenge-stream/librevenge-stream.h>
00042 #include "libstaroffice_internal.hxx"
00043 
00053 class STOFFInputStream
00054 {
00055 public:
00060   STOFFInputStream(shared_ptr<librevenge::RVNGInputStream> input, bool inverted);
00061 
00066   STOFFInputStream(librevenge::RVNGInputStream *input, bool inverted);
00068   ~STOFFInputStream();
00069 
00071   shared_ptr<librevenge::RVNGInputStream> input()
00072   {
00073     return m_stream;
00074   }
00076   static shared_ptr<STOFFInputStream> get(librevenge::RVNGBinaryData const &data, bool inverted);
00077 
00079   bool readInverted() const
00080   {
00081     return m_inverseRead;
00082   }
00084   void setReadInverted(bool newVal)
00085   {
00086     m_inverseRead = newVal;
00087   }
00088   //
00089   // Position: access
00090   //
00091 
00096   int seek(long offset, librevenge::RVNG_SEEK_TYPE seekType);
00098   long tell();
00100   long size() const
00101   {
00102     return m_streamSize;
00103   }
00105   bool checkPosition(long pos) const
00106   {
00107     if (pos < 0) return false;
00108     if (m_readLimit > 0 && pos > m_readLimit) return false;
00109     return pos<=m_streamSize;
00110   }
00112   bool isEnd();
00113 
00117   void pushLimit(long newLimit)
00118   {
00119     m_prevLimits.push_back(m_readLimit);
00120     m_readLimit = newLimit > m_streamSize ? m_streamSize : newLimit;
00121   }
00123   void popLimit()
00124   {
00125     if (m_prevLimits.size()) {
00126       m_readLimit = m_prevLimits.back();
00127       m_prevLimits.pop_back();
00128     }
00129     else m_readLimit = -1;
00130   }
00131 
00132   //
00133   // get data
00134   //
00135 
00137   int peek();
00139   STOFFInputStream &operator>>(bool &res)
00140   {
00141     res=readULong(1)!=0 ? true : false;
00142     return *this;
00143   }
00145   STOFFInputStream &operator>>(uint8_t &res)
00146   {
00147     res=static_cast<uint8_t>(readULong(1));
00148     return *this;
00149   }
00151   STOFFInputStream &operator>>(int8_t &res)
00152   {
00153     res=static_cast<int8_t>(readLong(1));
00154     return *this;
00155   }
00157   STOFFInputStream &operator>>(uint16_t &res)
00158   {
00159     res=static_cast<uint16_t>(readULong(2));
00160     return *this;
00161   }
00163   STOFFInputStream &operator>>(int16_t &res)
00164   {
00165     res=static_cast<int16_t>(readLong(2));
00166     return *this;
00167   }
00169   STOFFInputStream &operator>>(uint32_t &res)
00170   {
00171     res=static_cast<uint32_t>(readULong(4));
00172     return *this;
00173   }
00175   STOFFInputStream &operator>>(int32_t &res)
00176   {
00177     res=static_cast<int32_t>(readLong(4));
00178     return *this;
00179   }
00181   STOFFInputStream &operator>>(double &res)
00182   {
00183     bool isNan;
00184     long pos=tell();
00185     if (!readDoubleReverted8(res, isNan)) {
00186       STOFF_DEBUG_MSG(("STOFFInputStream::operator>>: can not read a double\n"));
00187       seek(pos+8, librevenge::RVNG_SEEK_SET);
00188       res=0;
00189     }
00190     return *this;
00191   }
00193   unsigned long readULong(int num)
00194   {
00195     return readULong(m_stream.get(), num, 0, m_inverseRead);
00196   }
00198   long readLong(int num);
00200   bool readColor(STOFFColor &color);
00202   bool readCompressedLong(long &res);
00204   bool readCompressedULong(unsigned long &res);
00206   bool readDouble8(double &res, bool &isNotANumber);
00208   bool readDoubleReverted8(double &res, bool &isNotANumber);
00210   bool readDouble10(double &res, bool &isNotANumber);
00214   const uint8_t *read(size_t numBytes, unsigned long &numBytesRead);
00218   static unsigned long readULong(librevenge::RVNGInputStream *stream, int num, unsigned long a, bool inverseRead);
00219 
00221   bool readDataBlock(long size, librevenge::RVNGBinaryData &data);
00223   bool readEndDataBlock(librevenge::RVNGBinaryData &data);
00224 
00225   //
00226   // OLE/Zip access
00227   //
00228 
00230   bool isStructured();
00232   unsigned subStreamCount();
00234   std::string subStreamName(unsigned id);
00235 
00237   shared_ptr<STOFFInputStream> getSubStreamByName(std::string const &name);
00239   shared_ptr<STOFFInputStream> getSubStreamById(unsigned id);
00240 
00241   //
00242   // Resource Fork access
00243   //
00244 
00246   bool hasDataFork() const
00247   {
00248     return bool(m_stream);
00249   }
00250 
00251 protected:
00253   void updateStreamSize();
00255   static uint8_t readU8(librevenge::RVNGInputStream *stream);
00256 
00257 private:
00258   STOFFInputStream(STOFFInputStream const &orig);
00259   STOFFInputStream &operator=(STOFFInputStream const &orig);
00260 
00261 protected:
00263   shared_ptr<librevenge::RVNGInputStream> m_stream;
00265   long m_streamSize;
00266 
00268   bool m_inverseRead;
00269 
00271   long m_readLimit;
00273   std::vector<long> m_prevLimits;
00274 };
00275 
00276 #endif
00277 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: