You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
4.7 KiB
C++

/***************************************************************************
* 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 <iostream>
#include <vector>
#include <fstream>
#include <stdint.h>
#include <gempa/caps/packet.h>
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 <int SIZE_T, bool BigEndian>
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 <int SIZE_T, bool BigEndian>
struct VectorChunk : Chunk {
std::vector<char> &data;
VectorChunk(std::vector<char> &d);
// sampleOfs and sampleCount are not byte offsets but elements of
// type T
VectorChunk(std::vector<char> &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