1b4a73884d7b5891a43c461d79901bd7e9d1a147
[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         mode = b?(mode&~M_NONBLOCK):(mode|M_NONBLOCK);
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 unsigned BufferedFile::do_write(const char *buf, unsigned size)
95 {
96         unsigned ret = buffer.write(buf, size);
97         position += ret;
98         return ret;
99 }
100
101 unsigned BufferedFile::do_read(char *buf, unsigned size)
102 {
103         unsigned ret = buffer.read(buf, size);
104         position += ret;
105         return ret;
106 }
107
108 unsigned BufferedFile::put(char c)
109 {
110         unsigned ret = buffer.put(c);
111         position += ret;
112         return ret;
113 }
114
115 bool BufferedFile::getline(string &line)
116 {
117         bool ret = buffer.getline(line);
118         if(ret)
119                 position += line.size();
120         return ret;
121 }
122
123 int BufferedFile::get()
124 {
125         int ret = buffer.get();
126         if(ret>=0)
127                 ++position;
128         return ret;
129 }
130
131 SeekOffset BufferedFile::seek(SeekOffset offset, SeekType type)
132 {
133         if(type==S_CUR)
134         {
135                 offset += position;
136                 type = S_BEG;
137         }
138
139         signal_flush_required.emit();
140         position = file.seek(offset, type);
141         eof_flag = false;
142         return position;
143 }
144
145 } // namespace IO
146 } // namespace Msp