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
194 lines
4.7 KiB
C
4 years ago
|
/***************************************************************************
|
||
|
* 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
|