/*************************************************************************** * Copyright (C) 2009 by gempa GmbH * * * * All Rights Reserved. * * * * NOTICE: All information contained herein is, and remains * * the property of gempa GmbH and its suppliers, if any. The intellectual * * and technical concepts contained herein are proprietary to gempa GmbH * * and its suppliers. * * Dissemination of this information or reproduction of this material * * is strictly forbidden unless prior written permission is obtained * * from gempa GmbH. * ***************************************************************************/ #ifndef CAPS_IO_RIFF_H #define CAPS_IO_RIFF_H #include #include #include #include #include namespace Gempa { namespace CAPS { namespace RIFF { struct SC_GEMPA_CAPS_API ChunkHeader { union { char chunkType[4]; uint32_t chunkID; }; int chunkSize; /* Chunk size in bytes */ bool setChunkType(const char *type); bool isChunkType(const char *type) const; bool validChunkType() const; int dataSize() const { return 8; } bool read(std::istream &input) { return get(*input.rdbuf()); } bool write(std::ostream &output) const { return put(*output.rdbuf()); } bool get(std::streambuf &input); bool put(std::streambuf &output) const; }; const int ChunkHeaderSize = 8; class SC_GEMPA_CAPS_API ChunkIterator { public: ChunkIterator(); ChunkIterator(const std::string &filename); ChunkIterator(std::istream &input); //! Starts iterating over a file or stream void begin(const std::string &filename); void begin(std::istream &input); //! Jumps to the next chunk. Returns false, //! if no chunk is available bool next(); //! Returns the current chunk header const ChunkHeader &header() const; //! Returns the file position pointing //! to the current chunk header size_t headerPos() const; //! Returns the file position pointing //! to the current chunk content size_t contentPos() const; //! Returns the current input stream std::istream &istream() const { return *_stream; } private: ChunkHeader _header; std::istream *_stream; size_t _index; std::ifstream _own; }; struct SC_GEMPA_CAPS_API Chunk { virtual ~Chunk(); bool read(std::istream &input, int size) { return get(*input.rdbuf(), size); } bool write(std::ostream &output) const { return put(*output.rdbuf()); } virtual bool get(std::streambuf &input, int size) = 0; virtual bool put(std::streambuf &output) const = 0; virtual int chunkSize() const = 0; }; struct SC_GEMPA_CAPS_API HeadChunk : Chunk { PacketDataHeader data; int chunkSize() const; bool get(std::streambuf &input, int size); bool put(std::streambuf &output) const; }; struct SC_GEMPA_CAPS_API SID { std::string networkCode; std::string stationCode; std::string locationCode; std::string channelCode; bool operator==(const SID &other ) const { return networkCode == other.networkCode && stationCode == other.stationCode && locationCode == other.locationCode && channelCode == other.channelCode; } bool operator!=(const SID &other ) const { return networkCode != other.networkCode || stationCode != other.stationCode || locationCode != other.locationCode || channelCode != other.channelCode; } std::string toString() const { return networkCode + "." + stationCode + "." + locationCode + "." + channelCode; } }; struct SC_GEMPA_CAPS_API SIDChunk : Chunk, SID { int chunkSize() const; bool get(std::streambuf &input, int size); bool put(std::streambuf &output) const; }; template struct CPtrChunk : Chunk { const char *data; int size; CPtrChunk(const char* d, int len); virtual ~CPtrChunk() {} int chunkSize() const; bool get(std::streambuf &input, int size); bool put(std::streambuf &output) const; }; template struct VectorChunk : Chunk { std::vector &data; VectorChunk(std::vector &d); // sampleOfs and sampleCount are not byte offsets but elements of // type T VectorChunk(std::vector &d, int sampleOfs, int sampleCount); virtual ~VectorChunk() {} int chunkSize() const; bool get(std::streambuf &input, int size); bool put(std::streambuf &output) const; int startOfs; int len; }; } } } #endif