ab957c97f1e2472a5d007b86e8ace3ea9493ec59
[libs/core.git] / source / io / file.cpp
1 #include "file.h"
2 #include "handle_private.h"
3
4 using namespace std;
5
6 namespace Msp {
7 namespace IO {
8
9 File::File(const string &fn, Mode m, CreateMode cm)
10 {
11         if(!(m&M_RDWR))
12                 throw invalid_argument("File::File mode");
13         if(cm&~(C_CREATE|C_TRUNCATE|C_EXCLUSIVE))
14                 throw invalid_argument("File::File create");
15         if((cm&C_EXCLUSIVE) && (!(cm&C_CREATE) || (cm&C_TRUNCATE)))
16                 throw invalid_argument("File::File create");
17
18         mode = m;
19
20         platform_init(fn, cm);
21 }
22
23 File::~File()
24 {
25         signal_flush_required.emit();
26         sys_close(handle);
27 }
28
29 void File::set_block(bool b)
30 {
31         adjust_mode(mode, M_NONBLOCK, !b);
32         sys_set_blocking(handle, b);
33 }
34
35 unsigned File::do_write(const char *buf, unsigned size)
36 {
37         check_access(M_WRITE);
38
39         if(size==0)
40                 return 0;
41
42 #ifdef _WIN32
43         if(mode&M_APPEND)
44                 seek(0, S_END);
45 #endif
46
47         return sys_write(handle, buf, size);
48 }
49
50 unsigned File::do_read(char *buf, unsigned size)
51 {
52         check_access(M_READ);
53
54         if(size==0)
55                 return 0;
56
57         unsigned ret = sys_read(handle, buf, size);
58         if(ret==0)
59                 set_eof();
60
61         return ret;
62 }
63
64 SeekOffset File::seek(SeekOffset off, SeekType type)
65 {
66         signal_flush_required.emit();
67         off = sys_seek(handle, off, type);
68         eof_flag = false;
69
70         return off;
71 }
72
73 SeekOffset File::tell() const
74 {
75         return sys_seek(const_cast<Handle &>(handle), 0, S_CUR);
76 }
77
78 const Handle &File::get_handle(Mode m)
79 {
80         check_access(m);
81         return handle;
82 }
83
84
85 BufferedFile::BufferedFile(const string &fn, Mode m, File::CreateMode cm):
86         file(fn, m, cm),
87         buffer(file),
88         position(0)
89 {
90         mode = m;
91         file.signal_end_of_file.connect(sigc::mem_fun(this, &BufferedFile::set_eof));
92 }
93
94 void BufferedFile::set_block(bool b)
95 {
96         file.set_block(b);
97 }
98
99 unsigned BufferedFile::do_write(const char *buf, unsigned size)
100 {
101         unsigned ret = buffer.write(buf, size);
102         position += ret;
103         return ret;
104 }
105
106 unsigned BufferedFile::do_read(char *buf, unsigned size)
107 {
108         unsigned ret = buffer.read(buf, size);
109         position += ret;
110         return ret;
111 }
112
113 unsigned BufferedFile::put(char c)
114 {
115         unsigned ret = buffer.put(c);
116         position += ret;
117         return ret;
118 }
119
120 bool BufferedFile::getline(string &line)
121 {
122         bool ret = buffer.getline(line);
123         if(ret)
124                 position += line.size();
125         return ret;
126 }
127
128 int BufferedFile::get()
129 {
130         int ret = buffer.get();
131         if(ret>=0)
132                 ++position;
133         return ret;
134 }
135
136 const Handle &BufferedFile::get_handle(Mode)
137 {
138         throw logic_error("BufferedFile::get_handle");
139 }
140
141 SeekOffset BufferedFile::seek(SeekOffset offset, SeekType type)
142 {
143         if(type==S_CUR)
144         {
145                 offset += position;
146                 type = S_BEG;
147         }
148
149         signal_flush_required.emit();
150         position = file.seek(offset, type);
151         eof_flag = false;
152         return position;
153 }
154
155 } // namespace IO
156 } // namespace Msp