From f644c7d1a33fa8bd7c03003317c75ae733c40b9c Mon Sep 17 00:00:00 2001 From: Antidote Date: Sun, 27 Jan 2013 08:49:48 -0800 Subject: [PATCH] * Changed how TextStream works; It's now less derpish and doesn't produce a corrupted buffer everytime you edit a line. --- include/FileNotFoundException.hpp | 4 +- include/FileStream.hpp | 21 ----- include/TextStream.hpp | 5 +- libzelda.cbp | 2 + src/FileStream.cpp | 33 -------- src/Stream.cpp | 6 +- src/TextStream.cpp | 135 ++++++++++++++++-------------- 7 files changed, 82 insertions(+), 124 deletions(-) delete mode 100644 include/FileStream.hpp delete mode 100644 src/FileStream.cpp diff --git a/include/FileNotFoundException.hpp b/include/FileNotFoundException.hpp index ba6a059..04e0df2 100644 --- a/include/FileNotFoundException.hpp +++ b/include/FileNotFoundException.hpp @@ -21,9 +21,7 @@ /*! \class FileNotFoundException * \brief An excpeption thrown when a file could not be found at the given path. * - * This should only be thrown when the library tries to write to a buffer - * e.g when the position is greater than the position and the stream - * is not set to autoresize.
+ * This should only be thrown when the Stream is unable to open a file.
*
* It is NOT appropriate to use throw new so avoid doing so, * keeping things on the stack as much as possible is very important for speed. diff --git a/include/FileStream.hpp b/include/FileStream.hpp deleted file mode 100644 index e1963ee..0000000 --- a/include/FileStream.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __FILESTREAM_HPP__ -#define __FILESTREAM_HPP__ - -#include "Stream.hpp" -#include - -class FileStream : public Stream -{ -public: - enum FileMode { Open, Create, OpenOrCreate = Open|Create, Truncate, Append }; - enum AccessMode { ReadOnly, WriteOnly, ReadWrite }; - FileStream(const std::string& filename, FileMode fileMode, AccessMode accessMode); - - -private: - std::string m_filename; - FileMode m_filemode; - AccessMode m_accessmode; -}; - -#endif diff --git a/include/TextStream.hpp b/include/TextStream.hpp index 63cc47c..374bb6f 100644 --- a/include/TextStream.hpp +++ b/include/TextStream.hpp @@ -25,10 +25,13 @@ public: void setCurrentLine(Uint32 line); Uint32 currentLine() const; -private: +private: + void loadLines(); std::string m_filename; FileMode m_filemode; AccessMode m_accessmode; + + std::vector m_lines; Uint32 m_currentLine; Uint32 m_startLength; }; diff --git a/libzelda.cbp b/libzelda.cbp index 943c0ee..818aa5e 100644 --- a/libzelda.cbp +++ b/libzelda.cbp @@ -75,6 +75,7 @@ + @@ -84,6 +85,7 @@ + diff --git a/src/FileStream.cpp b/src/FileStream.cpp deleted file mode 100644 index feb8f1f..0000000 --- a/src/FileStream.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "FileStream.hpp" -#include -#include "FileNotFoundException.hpp" -#include "IOException.hpp" - -FileStream::FileStream(const std::string& filename, FileMode fileMode, AccessMode accessMode) : - m_filename(filename), - m_filemode(fileMode), - m_accessmode(accessMode) -{ - FILE* in; - int length; - in = fopen(filename.c_str(), "rb"); - - if (!in) - { - if((fileMode & Create) != Create) - throw FileNotFoundException(filename.c_str()); - - in = fopen(filename.c_str(), "w+b"); - } - - fseek(in, 0, SEEK_END); - length = ftell(in); - fseek(in, 0, SEEK_SET); - m_data = new Uint8[length]; - - fread(m_data, 1, length, in); - fclose(in); - printf("%i\n", length); - m_length = length; - m_position = 0; -} diff --git a/src/Stream.cpp b/src/Stream.cpp index 79ad90f..564c655 100644 --- a/src/Stream.cpp +++ b/src/Stream.cpp @@ -161,7 +161,7 @@ Int8 Stream::readByte() m_position += sizeof(Uint8); } if (m_position + 1 > m_length) - throw IOException("Position passed stream bounds: " + m_position); + throw IOException("Position passed stream bounds"); return *(Int8*)(m_data + m_position++); } @@ -228,7 +228,7 @@ void Stream::seek(Int64 position, SeekOrigin origin) void Stream::resize(Uint64 newSize) { if (newSize < m_length) - throw InvalidOperationException("Stream:Resize() -> New size cannot be less to the old size."); + throw InvalidOperationException("Stream::Resize() -> New size cannot be less to the old size."); // Allocate and copy new buffer Uint8* newArray = new Uint8[newSize]; @@ -274,7 +274,7 @@ Int64 Stream::position() bool Stream::atEnd() { - return m_position == m_length; + return m_position >= m_length; } void Stream::setAutoResizing(bool val) diff --git a/src/TextStream.cpp b/src/TextStream.cpp index 5c5e27f..cb6afc5 100644 --- a/src/TextStream.cpp +++ b/src/TextStream.cpp @@ -45,7 +45,9 @@ TextStream::TextStream(const std::string& filename, FileMode fileMode, AccessMod m_position = 0; m_length = length; - m_startLength = length; + m_startLength = length; + + loadLines(); } void TextStream::save(const std::string& filename) @@ -53,6 +55,20 @@ void TextStream::save(const std::string& filename) if (filename != std::string()) m_filename = filename; + // We need a new buffer to write the new lines + if (m_data) + delete[] m_data; + + m_position = 0; + m_length = 1; + + // Set the new buffer + m_data = new Uint8[m_length]; + + // Now write all the strings to the new buffer + for (std::string s : m_lines) + writeBytes((Int8*)s.c_str(), s.size()); + FILE* out = fopen(m_filename.c_str(), "wb"); if(out) @@ -63,43 +79,27 @@ void TextStream::save(const std::string& filename) else throw FileNotFoundException(m_filename); } + std::string TextStream::readLine() { - std::string ret; - Uint8 c; - for (;;) - { - c = readByte(); - - if (c == '\r' || c == '\n') - { - m_currentLine++; - ret.push_back(c); - if (*(Uint8*)(m_data + m_position + 1) == '\n') - { - ret.push_back('\n'); - m_currentLine++; - m_position++; // advance position past the new line character - } - break; - } - - if (c == '\0') - { - ret.push_back('\n'); - m_currentLine++; - break; - } - ret.push_back(c); - } - return ret; + if (m_currentLine > m_lines.size()) + throw IOException("Position past stream bounds"); + return m_lines[m_currentLine++]; } void TextStream::writeLine(const std::string& str) { - this->writeBytes((Int8*)str.c_str(), str.size()); - m_currentLine++; + if (m_currentLine > m_lines.size() && !m_autoResize) + throw IOException("Position past stream bounds"); + else if (m_currentLine > m_lines.size()) + { + m_lines.push_back(str); + m_currentLine++; + return; + } + + m_lines[m_currentLine++] = str; } void TextStream::writeLines(std::vector strings) @@ -110,14 +110,11 @@ void TextStream::writeLines(std::vector strings) std::vector TextStream::readLines(Uint32 numLines) { - m_position = 0; - m_currentLine = 0; + Uint32 currentLine = m_currentLine; std::vector ret; - while ((numLines--) > 0) - { - ret.push_back(readLine()); - } + while ((m_currentLine++) <= currentLine + numLines) + ret.push_back(m_lines[m_currentLine]); return ret; } @@ -127,44 +124,56 @@ std::string TextStream::readLineAt(Uint32 line) if (line <= 0) throw InvalidOperationException("A line cannot be zero indexed"); - m_position = 0; - m_currentLine = 0; - while (m_currentLine < line - 1) - { - readLine(); - } - - return readLine(); + return m_lines[line - 1]; } std::vector TextStream::readAllLines() { - m_position = 0; - m_currentLine = 0; - std::vector ret; - - while (!atEnd()) - { - ret.push_back(readLine()); - } - - return ret; + return m_lines; } void TextStream::setCurrentLine(Uint32 line) { if (line <= 0) throw InvalidOperationException("A line cannot be zero indexed"); - m_currentLine = 0; - m_position = 0; - - while(m_currentLine != line - 1) - { - readLine(); - } + m_currentLine = line - 1; } Uint32 TextStream::currentLine() const { - return m_currentLine; + return m_currentLine + 1; +} + +void TextStream::loadLines() +{ + while (!atEnd()) + { + std::string line; + Uint8 c; + for (;;) + { + c = readByte(); + + if (c == '\r' || c == '\n') + { + m_currentLine++; + line.push_back(c); + if (*(Uint8*)(m_data + m_position + 1) == '\n') + { + line.push_back('\n'); + m_position++; // advance position past the new line character + } + break; + } + + if (c == '\0') + { + line.push_back('\n'); + break; + } + line.push_back(c); + } + + m_lines.push_back(line); + } }