Some fixes for eof handling in Memory
[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 unsigned Memory::do_write(const char *buf, unsigned size)
41 {
42         check_access(M_WRITE);
43
44         size = min<unsigned>(size, end-pos);
45         memcpy(pos, buf, size);
46         pos += size;
47         return size;
48 }
49
50 unsigned Memory::do_read(char *buf, unsigned size)
51 {
52         check_access(M_READ);
53
54         if(pos==end)
55         {
56                 set_eof();
57                 return 0;
58         }
59
60         size = min<unsigned>(size, end-pos);
61         memcpy(buf, pos, size);
62         pos += size;
63         return size;
64 }
65
66 unsigned Memory::put(char c)
67 {
68         check_access(M_WRITE);
69
70         if(pos==end)
71                 return 0;
72
73         *pos++ = c;
74         return 1;
75 }
76
77 bool Memory::getline(string &line)
78 {
79         check_access(M_READ);
80
81         if(pos==end)
82         {
83                 set_eof();
84                 return false;
85         }
86
87         char *nl = find(pos, end, '\n');
88         line.assign(pos, nl);
89         pos = (nl==end ? end : nl+1);
90         return true;
91 }
92
93 int Memory::get()
94 {
95         check_access(M_READ);
96
97         if(pos==end)
98         {
99                 set_eof();
100                 return -1;
101         }
102
103         return static_cast<unsigned char>(*pos++);
104 }
105
106 SeekOffset Memory::seek(SeekOffset off, SeekType type)
107 {
108         char *new_pos;
109         if(type==S_BEG)
110                 new_pos = begin+off;
111         else if(type==S_CUR)
112                 new_pos = pos+off;
113         else if(type==S_END)
114                 new_pos = end+off;
115         else
116                 throw invalid_argument("Memory::seek");
117
118         if(new_pos<begin || new_pos>end)
119                 throw out_of_range("Memory::seek");
120
121         pos = new_pos;
122         eof_flag = false;
123         return pos-begin;
124 }
125
126 } // namespace IO
127 } // namespace Msp