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