138 lines
3.5 KiB
C++
138 lines
3.5 KiB
C++
#include "PackStream.h"
|
|
|
|
#include "Logs.h"
|
|
|
|
#include <cstring>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
|
|
class PackStream::pimpl {
|
|
public:
|
|
fstream *file;
|
|
stringstream *buffer;
|
|
iostream* stream;
|
|
};
|
|
|
|
PackStream::PackStream() : pv(new pimpl) {
|
|
pv->file = new fstream();
|
|
pv->buffer = new stringstream();
|
|
pv->stream = pv->buffer;
|
|
}
|
|
|
|
PackStream::PackStream(const PackStream *other) : pv(new pimpl) {
|
|
pv->file = new fstream();
|
|
pv->buffer = new stringstream();
|
|
if (other->pv->file->is_open()) {
|
|
Logs::error("System") << "Try to read from a substream bound to a file: "
|
|
<< other->pv->file << endl;
|
|
} else {
|
|
other->pv->buffer->seekg(0);
|
|
other->pv->buffer->get(*pv->buffer->rdbuf());
|
|
}
|
|
pv->stream = pv->buffer;
|
|
}
|
|
|
|
PackStream::PackStream(const string &buffer_content) : pv(new pimpl) {
|
|
pv->file = new fstream();
|
|
pv->buffer = new stringstream(buffer_content);
|
|
pv->stream = pv->buffer;
|
|
}
|
|
|
|
PackStream::~PackStream() {
|
|
delete pv->file;
|
|
delete pv->buffer;
|
|
}
|
|
|
|
bool PackStream::bindToFile(const string &filepath, bool write) {
|
|
if (pv->file->is_open()) {
|
|
return false;
|
|
} else {
|
|
pv->file->open(filepath, write ? ios_base::out : ios_base::in);
|
|
if (pv->file->is_open()) {
|
|
pv->stream = pv->file;
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void PackStream::write(const int *value) {
|
|
if (value) {
|
|
// TODO endianness and int size portability
|
|
pv->stream->write(reinterpret_cast<const char*>(value), sizeof(int));
|
|
}
|
|
}
|
|
|
|
void PackStream::write(const double *value) {
|
|
if (value) {
|
|
// TODO float format portability
|
|
pv->stream->write(reinterpret_cast<const char*>(value), sizeof(double));
|
|
}
|
|
}
|
|
|
|
void PackStream::write(const string &value) {
|
|
const int length = value.length();
|
|
write(&length);
|
|
pv->stream->write(value.c_str(), length);
|
|
}
|
|
|
|
void PackStream::writeFromBuffer(const PackStream &other, bool prepend_size) {
|
|
if (other.pv->file->is_open()) {
|
|
Logs::error("System") << "Try to write from a substream bound to a file: "
|
|
<< other.pv->file << endl;
|
|
} else {
|
|
int buffer_size = other.pv->buffer->rdbuf()->str().length();
|
|
if (prepend_size) {
|
|
write(&buffer_size);
|
|
}
|
|
pv->stream->write(other.pv->buffer->rdbuf()->str().c_str(), buffer_size);
|
|
}
|
|
}
|
|
|
|
string PackStream::getBuffer() {
|
|
if (pv->file->is_open()) {
|
|
Logs::error("System") << "Try to get buffer on a stream bound to a file: " << pv->file << endl;
|
|
return "";
|
|
} else {
|
|
return pv->buffer->rdbuf()->str();
|
|
}
|
|
}
|
|
|
|
void PackStream::read(int *value) {
|
|
if (value and not pv->stream->eof()) {
|
|
pv->stream->read(reinterpret_cast<char*>(value), sizeof(int));
|
|
}
|
|
}
|
|
|
|
void PackStream::read(double *value) {
|
|
if (value and not pv->stream->eof()) {
|
|
pv->stream->read(reinterpret_cast<char*>(value), sizeof(double));
|
|
}
|
|
}
|
|
|
|
string PackStream::readString() {
|
|
if (not pv->stream->eof()) {
|
|
int size;
|
|
read(&size);
|
|
if (size > 0) {
|
|
std::string str(size, '\0');
|
|
pv->stream->read(&str[0], size);
|
|
return str;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
void PackStream::skip(const int &value, int count) {
|
|
skipBytes(sizeof(value) * count);
|
|
}
|
|
|
|
void PackStream::skip(const double &value, int count) {
|
|
skipBytes(sizeof(value) * count);
|
|
}
|
|
|
|
void PackStream::skipBytes(int bytes) {
|
|
pv->stream->seekg(bytes, ios_base::cur);
|
|
}
|