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