]> git.tdb.fi Git - libs/core.git/blob - source/io/memory.cpp
Unify end-of-file handling
[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)
12 {
13         init(d, d+s, M_RDWR);
14 }
15
16 Memory::Memory(char *b, char *e)
17 {
18         init(b, e, M_RDWR);
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         if(pos==end)
53         {
54                 set_eof();
55                 return 0;
56         }
57
58         size = min<unsigned>(size, end-pos);
59         memcpy(buf, pos, size);
60         pos += size;
61         return size;
62 }
63
64 unsigned Memory::put(char c)
65 {
66         check_access(M_WRITE);
67         *pos++ = c;
68         return 1;
69 }
70
71 bool Memory::getline(string &line)
72 {
73         char *nl = find(pos, end, '\n');
74         line.assign(pos, nl);
75         bool result = (nl!=pos);
76         pos = nl;
77         return result;
78 }
79
80 int Memory::get()
81 {
82         if(pos==end)
83         {
84                 set_eof();
85                 return -1;
86         }
87
88         return static_cast<unsigned char>(*pos++);
89 }
90
91 SeekOffset Memory::seek(SeekOffset off, SeekType type)
92 {
93         char *new_pos;
94         if(type==S_BEG)
95                 new_pos = begin+off;
96         else if(type==S_CUR)
97                 new_pos = pos+off;
98         else if(type==S_END)
99                 new_pos = end+off;
100         else
101                 throw invalid_argument("Memory::seek");
102
103         if(new_pos<begin || new_pos>end)
104                 throw out_of_range("Memory::seek");
105
106         pos = new_pos;
107         return pos-begin;
108 }
109
110 } // namespace IO
111 } // namespace Msp