-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlib.rs
More file actions
237 lines (221 loc) · 9.94 KB
/
lib.rs
File metadata and controls
237 lines (221 loc) · 9.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
//! The Neotron API
//!
//! Defines the API supplied to applications that run on Neotron OS. This API is
//! provided in the form of a rust `struct Api`, where every field is a function
//! pointer.
#![no_std]
// ============================================================================
// Imports
// ============================================================================
pub mod dir;
pub mod file;
pub mod path;
pub use neotron_ffi::{FfiBuffer, FfiByteSlice, FfiString};
// ============================================================================
// Constants
// ============================================================================
/// Maximum length of a filename (with no directory components), including the
/// extension.
pub const MAX_FILENAME_LEN: usize = 11;
// ============================================================================
// Types
// ============================================================================
/// The result type for any SDK API function.
///
/// Like a [`neotron_ffi::FfiResult`] but the error type is [`Error`].
pub type Result<T> = neotron_ffi::FfiResult<T, Error>;
/// The syscalls provided by the Neotron OS to a Neotron Application.
#[repr(C)]
pub struct Api {
/// Open a file, given a path as UTF-8 string.
///
/// If the file does not exist, or is already open, it returns an error.
///
/// Path may be relative to current directory, or it may be an absolute
/// path.
///
/// # Limitations
///
/// * You cannot open a file if it is currently open.
/// * Paths must confirm to the rules for the filesystem for the given drive.
/// * Relative paths are taken relative to the current directory (see `Api::chdir`).
pub open: extern "C" fn(path: FfiString, flags: file::Flags) -> Result<file::Handle>,
/// Close a previously opened file.
///
/// Closing a file is important, as only this action will cause the
/// directory entry for the file to be updated. Crashing the system without
/// closing a file may cause the directory entry to be incorrect, and you
/// may need to run `CHKDSK` (or similar) on your disk to fix it.
pub close: extern "C" fn(fd: file::Handle) -> Result<()>,
/// Write to an open file handle, blocking until everything is written.
///
/// Some files do not support writing and will produce an error. You will
/// also get an error if you run out of disk space.
///
/// The `buffer` is only borrowed for the duration of the function call and
/// is then forgotten.
pub write: extern "C" fn(fd: file::Handle, buffer: FfiByteSlice) -> Result<()>,
/// Read from an open file, returning how much was actually read.
///
/// You might get less data than you asked for. If you do an `Api::read` and
/// you are already at the end of the file you will get
/// `Err(Error::EndOfFile)`.
///
/// Data is stored to the given `buffer. The `buffer` is only borrowed for
/// the duration of the function call and is then forgotten.
pub read: extern "C" fn(fd: file::Handle, buffer: FfiBuffer) -> Result<usize>,
/// Move the file offset (for the given file handle) to the given position.
///
/// Some files do not support seeking and will produce an error.
pub seek_set: extern "C" fn(fd: file::Handle, position: u64) -> Result<()>,
/// Move the file offset (for the given file handle) relative to the current position.
///
/// Returns the new file offset.
///
/// Some files do not support seeking and will produce an error.
pub seek_cur: extern "C" fn(fd: file::Handle, offset: i64) -> Result<u64>,
/// Move the file offset (for the given file handle) to the end of the file
///
/// Returns the new file offset.
///
/// Some files do not support seeking and will produce an error.
pub seek_end: extern "C" fn(fd: file::Handle) -> Result<u64>,
/// Rename a file.
///
/// # Limitations
///
/// * You cannot rename a file if it is currently open.
/// * You cannot rename a file where the `old_path` and the `new_path` are
/// not on the same drive.
/// * Paths must confirm to the rules for the filesystem for the given drive.
pub rename: extern "C" fn(old_path: FfiString, new_path: FfiString) -> Result<()>,
/// Perform a special I/O control operation.
pub ioctl: extern "C" fn(fd: file::Handle, command: u64, value: u64) -> Result<u64>,
/// Open a directory, given a path as a UTF-8 string.
pub opendir: extern "C" fn(path: FfiString) -> Result<dir::Handle>,
/// Close a previously opened directory.
pub closedir: extern "C" fn(dir: dir::Handle) -> Result<()>,
/// Read from an open directory
pub readdir: extern "C" fn(dir: dir::Handle) -> Result<dir::Entry>,
/// Get information about a file.
pub stat: extern "C" fn(path: FfiString) -> Result<file::Stat>,
/// Get information about an open file.
pub fstat: extern "C" fn(fd: file::Handle) -> Result<file::Stat>,
/// Delete a file.
///
/// # Limitations
///
/// * You cannot delete a file if it is currently open.
pub deletefile: extern "C" fn(path: FfiString) -> Result<()>,
/// Delete a directory.
///
/// # Limitations
///
/// * You cannot delete a root directory.
/// * You cannot delete a directory that has any files or directories in it.
pub deletedir: extern "C" fn(path: FfiString) -> Result<()>,
/// Change the current directory.
///
/// Relative file paths (e.g. passed to `Api::open`) are taken to be relative to the current directory.
///
/// Unlike on MS-DOS, there is only one current directory for the whole
/// system, not one per drive.
pub chdir: extern "C" fn(path: FfiString) -> Result<()>,
/// Change the current directory to the given open directory.
///
/// Unlike on MS-DOS, there is only one current directory for the whole
/// system, not one per drive.
pub dchdir: extern "C" fn(dir: dir::Handle) -> Result<()>,
/// Get the current directory.
///
/// The current directory is stored as UTF-8 into the given buffer. The
/// function returns the number of bytes written to the buffer, or an error.
/// If the function did not return an error, the buffer can be assumed to
/// contain a valid file path. That path will not be null terminated.
pub pwd: extern "C" fn(path: FfiBuffer) -> Result<usize>,
/// Allocate some memory.
///
/// * `size` - the number of bytes required
/// * `alignment` - the returned address will have this alignment, or
/// better. For example, pass `4` if you are allocating an array of `u32`.
pub malloc: extern "C" fn(size: usize, alignment: usize) -> Result<*mut core::ffi::c_void>,
/// Free some previously allocated memory.
///
/// You must pass the same `size` and `alignment` values that you passed to `malloc`.
pub free: extern "C" fn(ptr: *mut core::ffi::c_void, size: usize, alignment: usize),
/// Learn about the current video mode.
///
/// Pass the value to `video_mode_info` to learn about the current
/// resolution and colour depth. You will get an error if the system is
/// using a serial console rather than a video display.
pub video_mode_get: extern "C" fn() -> Result<u8>,
/// Learn about the supported video mode.
///
/// Video modes are not necessarily consecutive - if you want to learn
/// about all video modes, iterate from `0..=255` and note which ones do
/// not return an error.
pub video_mode_info: extern "C" fn(mode: u8) -> Result<VideoModeInfo>,
/// Change the current video mode.
///
/// The OS will attempt to allocate space, if required, for this video mode
/// from the top of the TPA. If there is insufficient RAM available, an
/// error is returned and the video mode is not changed.
///
/// If the mode change is succesful, you will receive a pointer to
/// framebuffer. Any writes there will appear on the display.
pub video_mode_set: extern "C" fn(mode: u8) -> Result<*mut u8>,
}
/// Describes a video mode
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct VideoModeInfo {
/// Width of the graphics mode in pixels, or text mode in characters
width: u16,
/// Height of the graphics mode in pixels, or text mode in characters
height: u16,
/// Colour depth of the graphics mode
///
/// * `0` - text mode
/// * `1` - one bit per pixel, black and white, indexed
/// * `2` - two bits per pixel, 4 colours, indexed
/// * `4` - four bits per pixel, 16 colours, indexed
/// * `8` - eight bits per pixel, 256 colours, indexed
/// * `15` - 15 bits per pixel, RGB555 high-colour
/// * `16` - 16 bits per pixel, RGB565 high-colour
/// * `32` - 32 bits per pixel, RGBA true-colour
colour_depth: u8,
}
/// Describes how something has failed
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Error {
/// The given file/directory path was not found
NotFound,
/// Tried to write to a read-only file
FileReadOnly,
/// Reached the end of the file
EndOfFile,
/// The API has not been implemented
Unimplemented,
/// An invalid argument was given to the API
InvalidArg,
/// A bad handle was given to the API
BadHandle,
/// An device-specific error occurred. Look at the BIOS source for more details.
DeviceSpecific,
/// The OS does not have enough memory
OutOfMemory,
/// The given path was invalid
InvalidPath,
}
// ============================================================================
// Functions
// ============================================================================
// None
// ============================================================================
// Tests
// ============================================================================
// None
// ============================================================================
// End of File
// ============================================================================