1use std::io::prelude::*;
39use std::path::Path;
40
41pub const O_CREATE: u32 = 1 << 1;
43pub const O_APPEND: u32 = 1 << 2;
45pub const O_NONBLOCK: u32 = 1 << 3;
47pub const O_READ: u32 = 1 << 4;
49pub const O_WRITE: u32 = 1 << 5;
51pub const O_RW: u32 = O_READ | O_WRITE;
53pub const O_TRUNCATE: u32 = 1 << 6;
55
56pub const SEEK_SET: i32 = 1;
58pub const SEEK_CUR: i32 = 2;
60pub const SEEK_END: i32 = 3;
62
63#[allow(non_camel_case_types)]
64type int = i32;
65
66pub fn mkdir<P: AsRef<Path>>(path: P) -> int {
68 if let Err(_) = std::fs::create_dir_all(path) {
69 return -1;
70 }
71 return 0;
72}
73
74pub fn remove<T: AsRef<Path>>(path: T) -> int {
76 if let Err(_) = std::fs::remove_file(path) {
77 return -1;
78 }
79 return 0;
80}
81
82pub struct File {
84 pod: Option<std::fs::File>,
85 path: String,
86 flags: u32,
87 error: std::io::Error,
88}
89
90impl File {
91 pub fn new() -> Self {
93 return File {
94 pod: None,
95 path: "".to_string(),
96 flags: 0,
97 error: std::io::Error::new(std::io::ErrorKind::Other, ""),
98 };
99 }
100
101 pub fn open<T: AsRef<str>>(&mut self, path: T, flags: u32) -> int {
103 let mut options = std::fs::File::options();
104
105 self.pod = None;
106 self.path = path.as_ref().to_string();
107
108 self.flags = flags;
109 if flags == 0 {
110 self.flags |= O_READ;
111 }
112
113 options.create(self.flags & O_CREATE != 0);
114 options.append(self.flags & O_APPEND != 0);
115 options.read(self.flags & O_READ != 0);
116 options.write(self.flags & O_WRITE != 0);
117 options.truncate(self.flags & O_TRUNCATE != 0);
118
119 let ret = options.open(path.as_ref());
120 match ret {
121 Ok(f) => {
122 self.pod = Some(f);
123 }
124 Err(e) => {
125 self.error = e;
126 return -1;
127 }
128 }
129
130 return 0;
131 }
132
133 pub fn close(&mut self) {
135 self.pod = None;
136 }
137
138 pub fn path(&self) -> &String {
140 return &self.path;
141 }
142
143 pub fn error(&self) -> &std::io::Error {
145 return &self.error;
146 }
147
148 pub fn write<Buffer: AsRef<[u8]>>(&mut self, data: Buffer) -> int {
150 let mut i = 0;
151 let buf = data.as_ref();
152 let n = buf.len() as i32;
153
154 if self.is_none() {
155 return -1;
156 }
157
158 let nb = self.flags & O_NONBLOCK != 0;
159 let mut fd = self.fd();
160
161 while i < n {
162 let off = i as usize;
163 let ret = fd.write(&buf[off..]);
164 match ret {
165 Ok(n) => i += n as i32,
166 Err(e) => {
167 self.error = e;
168 break;
169 }
170 }
171 if nb {
172 break;
173 }
174 }
175
176 return i;
177 }
178
179 pub fn read_to_end(&mut self, buf: &mut Vec<u8>) -> i32 {
180 if self.is_none() {
181 return -1;
182 }
183
184 match self.fd().read_to_end(buf) {
185 Ok(n) => {
186 return n as i32;
187 },
188 Err(e) => {
189 self.error = e;
190 }
191 }
192
193 return -1;
194 }
195
196 pub fn read(&mut self, buf: &mut [u8]) -> int {
198 if self.is_none() {
199 return -1;
200 }
201
202 let mut i = 0;
203 let mut fd = self.fd();
204
205 let ret = fd.read(buf);
206 match ret {
207 Ok(n) => {
208 i = n as i32;
209 }
210 Err(e) => {
211 self.error = e;
212 }
213 }
214
215 return i;
216 }
217
218 pub fn flush(&mut self) -> int {
220 if self.is_none() {
221 return -1;
222 }
223
224 if let Err(e) = self.fd().flush() {
225 self.error = e;
226 return -1;
227 }
228
229 return 0;
230 }
231
232 pub fn seek(&mut self, offset: i64, whence: int) -> i64 {
236 if self.is_none() {
237 return -1;
238 }
239
240 let w;
241 let mut off = -1;
242
243 match whence {
244 SEEK_SET => {
245 w = std::io::SeekFrom::Start(offset as u64);
246 }
247 SEEK_CUR => {
248 w = std::io::SeekFrom::Current(offset);
249 }
250 SEEK_END => {
251 w = std::io::SeekFrom::End(offset);
252 }
253 _ => {
254 return off;
255 }
256 }
257
258 let ret = self.fd().seek(w);
259 match ret {
260 Ok(n) => {
261 off = n as i64;
262 }
263 Err(e) => {
264 self.error = e;
265 }
266 }
267
268 return off;
269 }
270
271 pub fn rewind(&mut self) -> int {
273 if self.seek(0, SEEK_SET) < 0 {
274 return -1;
275 }
276 return 0;
277 }
278
279 pub fn position(&mut self) -> i64 {
281 return self.seek(0, SEEK_CUR);
282 }
283
284 pub fn is_none(&self) -> bool {
286 return self.pod.is_none();
287 }
288
289 pub fn fd(&mut self) -> Box<&mut std::fs::File> {
291 return Box::new(self.pod.as_mut().unwrap());
292 }
293}