#include "InMemoryBuffer.h" #include "Either.h" #include "Text.h" using namespace Framework; InMemoryBuffer::InMemoryBuffer() : ReferenceCounter() { buffer = new char*[1]; buffer[0] = new char[256]; numBuffers = 1; readPos = 0; writePos = 0; maxWritePos = 0; } InMemoryBuffer::~InMemoryBuffer() { for (int i = 0; i < numBuffers; i++) delete[] buffer[i]; delete[] buffer; } //! Ließt aus der Datei //! \param bytes Ein Array, der mit Bytes aus der Resource gefüllt werden soll //! \param len Wie viele Bytes aus der Resource gelesen werden sollen void InMemoryBuffer::lese(char* bytes, int len) { if (readPos < writePos) { len = MIN(len, writePos - readPos); int readCount = 0; do { int curPos = readPos % 256; int tmp = MIN(len, 256 - curPos); memcpy(bytes + readCount, buffer[readPos / 256] + curPos, tmp); readCount += tmp; readPos += tmp; len -= tmp; } while (len > 0); } } //! Schreibt in die Resource //! \param bytes Ein Array, der die Bytes enthält, welche in die Resource //! geschrieben werden soll \param len Wie viele Bytes in die Resource //! geschrieben werden sollen void InMemoryBuffer::schreibe(const char* bytes, int len) { if (numBuffers * 256 < writePos + len) { int newSize = (writePos + len) / 256 + 1; char** newBuffer = new char*[newSize]; memcpy(newBuffer, buffer, sizeof(char*) * numBuffers); memset( newBuffer + numBuffers, 0, sizeof(char*) * (newSize - numBuffers)); delete[] buffer; buffer = newBuffer; numBuffers = newSize; } int writeCount = 0; do { int curPos = writePos % 256; int tmp = MIN(len, 256 - curPos); if (!buffer[writePos / 256]) buffer[writePos / 256] = new char[256]; memcpy(buffer[writePos / 256] + curPos, bytes + writeCount, tmp); writeCount += tmp; writePos += tmp; len -= tmp; } while (len > 0); maxWritePos = MAX(maxWritePos, writePos); } //! Ließt die nächste zeile der Resource ein //! \return Die gelesene Zeile als Text mit zeilenumbruch Text* InMemoryBuffer::leseZeile() { if (istEnde()) return 0; Text* ret = new Text(""); for (char c = 0; c != '\n' && readPos < writePos;) { lese(&c, 1); if (c) ret->append(&c, 1); } return ret; } //! Prüft, ob die Resource vollständig gelesen wurde //! return 1, wenn die Resource vollständig gelesen wurde. 0, sonst bool InMemoryBuffer::istEnde() const { return readPos < writePos; } //! Setzt die Position des Bytes, das als nächstes gelesen werden soll //! \param pos Der Index des Bytes //! \param ende 1, wenn der Index vom ende der Resource zählt. 0, wenn der Index //! vom Beginn der Resource zählt void InMemoryBuffer::setLPosition(__int64 pos, bool ende) { if (ende) readPos = MAX(0, maxWritePos - (int)pos); else readPos = MIN(maxWritePos, (int)pos); } //! Setzt die Position des Bytes, das als nächstes geschrieben werden soll //! \param pos Der Index des Bytes //! \param ende 1, wenn der Index vom ende der Resource zählt. 0, wenn der Index //! vom Beginn der Resource zählt void InMemoryBuffer::setSPosition(__int64 pos, bool ende) { if (ende) writePos = MAX(0, maxWritePos - (int)pos); else writePos = MIN(maxWritePos, (int)pos); } //! Gibt den Index des Bytes aus der Resource zurück, welches als nächstes //! gelesen werden würde return -1, falls ein Fehler aufgetreten ist. Sonst die //! Position des Lesezeigers __int64 InMemoryBuffer::getLPosition() const { return readPos; } //! Gibt den Index des Bytes aus der Resource zurück, welches als nächstes //! geschrieben werden würde return -1, falls ein Fehler aufgetreten ist. Sonst //! die Position des Schreibzeigers __int64 InMemoryBuffer::getSPosition() const { return writePos; } //! Gibt die Anzahl der zu lesenden Bytes zurück __int64 InMemoryBuffer::getSize() const { return maxWritePos; }