]> git.tdb.fi Git - libs/core.git/blobdiff - source/io/memory.cpp
Move files to prepare for assimilation into core
[libs/core.git] / source / io / memory.cpp
diff --git a/source/io/memory.cpp b/source/io/memory.cpp
new file mode 100644 (file)
index 0000000..6ea130b
--- /dev/null
@@ -0,0 +1,127 @@
+#include <algorithm>
+#include <cstring>
+#include "except.h"
+#include "memory.h"
+
+using namespace std;
+
+namespace Msp {
+namespace IO {
+
+Memory::Memory(char *d, unsigned s)
+{
+       init(d, d+s, M_RDWR);
+}
+
+Memory::Memory(char *b, char *e)
+{
+       init(b, e, M_RDWR);
+}
+
+Memory::Memory(const char *cd, unsigned s)
+{
+       char *d = const_cast<char *>(cd);
+       init(d, d+s, M_READ);
+}
+
+Memory::Memory(const char *b, const char *e)
+{
+       init(const_cast<char *>(b), const_cast<char *>(e), M_READ);
+}
+
+void Memory::init(char *b, char *e, Mode m)
+{
+       begin = b;
+       end = e;
+       pos = begin;
+       mode = m;
+}
+
+unsigned Memory::do_write(const char *buf, unsigned size)
+{
+       check_mode(M_WRITE);
+
+       size = min<unsigned>(size, end-pos);
+       memcpy(pos, buf, size);
+       pos += size;
+       return size;
+}
+
+unsigned Memory::do_read(char *buf, unsigned size)
+{
+       if(pos==end)
+       {
+               eof_flag = true;
+               return 0;
+       }
+
+       size = min<unsigned>(size, end-pos);
+       memcpy(buf, pos, size);
+       pos += size;
+       return size;
+}
+
+unsigned Memory::put(char c)
+{
+       check_mode(M_WRITE);
+       *pos++ = c;
+       return 1;
+}
+
+bool Memory::getline(string &line)
+{
+       char *nl = find(pos, end, '\n');
+       line.assign(pos, nl);
+       bool result = (nl!=pos);
+       pos = nl;
+       return result;
+}
+
+int Memory::get()
+{
+       if(pos==end)
+       {
+               eof_flag = true;
+               return -1;
+       }
+
+       return static_cast<unsigned char>(*pos++);
+}
+
+unsigned Memory::seek(int off, SeekType type)
+{
+       char *new_pos;
+       if(type==S_BEG)
+               new_pos = begin+off;
+       else if(type==S_CUR)
+               new_pos = pos+off;
+       else if(type==S_END)
+               new_pos = end+off;
+       else
+               throw InvalidParameterValue("Invalid seek type");
+
+       if(new_pos<begin || new_pos>end)
+               throw InvalidParameterValue("Invalid seek offset");
+
+       pos = new_pos;
+       return pos-begin;
+}
+
+Handle Memory::get_event_handle()
+{
+       throw Exception("Memory doesn't support events");
+}
+
+void Memory::check_mode(Mode m) const
+{
+       if(m==M_WRITE)
+       {
+               if(!(mode&M_WRITE))
+                       throw InvalidState("Memory is not writable");
+               if(pos==end)
+                       throw InvalidState("Attempt to write past end of Memory");
+       }
+}
+
+} // namespace IO
+} // namespace Msp