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