]> git.tdb.fi Git - libs/core.git/blob - source/io/memory.cpp
274f6bae91c1a6a1d53f67be3872319bdae85bc2
[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         if(pos==end)
74         {
75                 set_eof();
76                 return false;
77         }
78
79         char *nl = find(pos, end, '\n');
80         line.assign(pos, nl);
81         pos = (nl==end ? end : nl+1);
82         return true;
83 }
84
85 int Memory::get()
86 {
87         if(pos==end)
88         {
89                 set_eof();
90                 return -1;
91         }
92
93         return static_cast<unsigned char>(*pos++);
94 }
95
96 SeekOffset Memory::seek(SeekOffset off, SeekType type)
97 {
98         char *new_pos;
99         if(type==S_BEG)
100                 new_pos = begin+off;
101         else if(type==S_CUR)
102                 new_pos = pos+off;
103         else if(type==S_END)
104                 new_pos = end+off;
105         else
106                 throw invalid_argument("Memory::seek");
107
108         if(new_pos<begin || new_pos>end)
109                 throw out_of_range("Memory::seek");
110
111         pos = new_pos;
112         return pos-begin;
113 }
114
115 } // namespace IO
116 } // namespace Msp