]> git.tdb.fi Git - libs/core.git/blob - source/memory.cpp
c44554ae5a4f9b59f7347befabc552c3fe190bf8
[libs/core.git] / source / memory.cpp
1 /* $Id$
2
3 This file is part of libmspio
4 Copyright © 2009 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <algorithm>
9 #include <cstring>
10 #include "except.h"
11 #include "memory.h"
12
13 using namespace std;
14
15 namespace Msp {
16 namespace IO {
17
18 Memory::Memory(char *d, unsigned s)
19 {
20         init(d, d+s, M_RDWR);
21 }
22
23 Memory::Memory(char *b, char *e)
24 {
25         init(b, e, M_RDWR);
26 }
27
28 Memory::Memory(const char *cd, unsigned s)
29 {
30         char *d=const_cast<char *>(cd);
31         init(d, d+s, M_READ);
32 }
33
34 Memory::Memory(const char *b, const char *e)
35 {
36         init(const_cast<char *>(b), const_cast<char *>(e), M_READ);
37 }
38
39 void Memory::init(char *b, char *e, Mode m)
40 {
41         begin=b;
42         end=e;
43         pos=begin;
44         mode=m;
45 }
46
47 unsigned Memory::put(char c)
48 {
49         check_mode(M_WRITE);
50         *pos++=c;
51         return 1;
52 }
53
54 bool Memory::getline(string &line)
55 {
56         char *nl=find(pos, end, '\n');
57         line.assign(pos, nl);
58         bool result=(nl!=pos);
59         pos=nl;
60         return result;
61 }
62
63 int Memory::get()
64 {
65         if(pos==end)
66         {
67                 eof_flag=true;
68                 return -1;
69         }
70
71         return static_cast<unsigned char>(*pos++);
72 }
73
74 unsigned Memory::seek(int off, SeekType type)
75 {
76         char *new_pos;
77         if(type==S_BEG)
78                 new_pos=begin+off;
79         else if(type==S_CUR)
80                 new_pos=pos+off;
81         else if(type==S_END)
82                 new_pos=end+off;
83         else
84                 throw InvalidParameterValue("Invalid seek type");
85
86         if(new_pos<begin || new_pos>end)
87                 throw InvalidParameterValue("Invalid seek offset");
88
89         pos=new_pos;
90         return pos-begin;
91 }
92
93 Handle Memory::get_event_handle()
94 {
95         throw Exception("Memory doesn't support events");
96 }
97
98 unsigned Memory::do_write(const char *buf, unsigned size)
99 {
100         check_mode(M_WRITE);
101
102         size=min<unsigned>(size, end-pos);
103         memcpy(pos, buf, size);
104         pos+=size;
105         return size;
106 }
107
108 unsigned Memory::do_read(char *buf, unsigned size)
109 {
110         if(pos==end)
111         {
112                 eof_flag=true;
113                 return 0;
114         }
115
116         size=min<unsigned>(size, end-pos);
117         memcpy(buf, pos, size);
118         pos+=size;
119         return size;
120 }
121
122 void Memory::check_mode(Mode m) const
123 {
124         if(m==M_WRITE)
125         {
126                 if(!(mode&M_WRITE))
127                         throw InvalidState("Memory is not writable");
128                 if(pos==end)
129                         throw InvalidState("Attempt to write past end of Memory");
130         }
131 }
132
133 } // namespace IO
134 } // namespace Msp