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