1 module nspire;
2 
3 import nspire.device;
4 import nspire.c.handle;
5 import nspire.c.devinfo;
6 import nspire.c.error;
7 import nspire.c.file;
8 import nspire.c.dir;
9 import nspire.c.os;
10 import core.stdc.config;
11                                
12 enum ErrorCodes {
13     NSPIRE_ERR_SUCCESS = 0,
14 
15     /* Generic */
16     NSPIRE_ERR_TIMEOUT = -1,
17     NSPIRE_ERR_NOMEM = -2,
18     NSPIRE_ERR_INVALID = -3,
19 
20     /* USB */
21     NSPIRE_ERR_LIBUSB = -4,
22     NSPIRE_ERR_NODEVICE = -5,
23 
24     /* Packet */
25     NSPIRE_ERR_INVALPKT = -6,
26     NSPIRE_ERR_NACK = -7,
27 
28     /* Service */
29     NSPIRE_ERR_BUSY = -8,
30 
31     /* File/Dir services */
32     NSPIRE_ERR_EXISTS = -9,
33     NSPIRE_ERR_NONEXIST = -10,
34 
35     /* OS install */
36     NSPIRE_ERR_OSFAILED = -11,
37 
38     /* Number of errors */
39     NSPIRE_ERR_MAX = -12
40 }
41 
42 enum DirType {
43     NSPIRE_FILE = 0,
44     NSPIRE_DIR = 1
45 }
46 
47 struct DirItem {
48     string name;
49     ulong size;
50     ulong date;
51     DirType type;
52     
53     this(nspire_dir_item dirItem) {
54         this.name = dirItem.name.dup;
55         this.size = dirItem.size;
56         this.date = dirItem.date;
57         this.type = cast(DirType) dirItem.type;
58     }
59 }
60 
61 struct Image {
62     ushort width;
63     ushort height;
64     ubyte bbp;
65     ubyte[] data;
66     
67     this(ushort width, ushort height, ubyte bbp, ubyte[] data) {
68         this.width = width;
69         this.height = height;
70         this.bbp = bbp;
71         this.data = data;
72     }
73 }
74 
75 struct NSpire {
76     private nspire_handle_t* handle;
77     private bool isInit = false;
78     
79     int init() {
80         auto ret = nspire_init(&this.handle);
81         
82         if (ret == NSPIRE_ERR_SUCCESS) {
83            isInit = true;
84         }
85         
86         return ret;
87     }
88     
89     void deinit() {
90         if (isInit && this.handle) {
91             nspire_free(this.handle);
92         }
93     }
94     
95     DeviceInfo getDeviceInfo(out int error) {
96         nspire_devinfo devinfo;
97         
98         if (!isInit) {
99             error = NSPIRE_ERR_NODEVICE;
100             return DeviceInfo();
101         }
102         
103         error = nspire_device_info(this.handle, &devinfo);
104         
105         if (error != ErrorCodes.NSPIRE_ERR_SUCCESS) {
106             return DeviceInfo();
107         }
108         
109         return DeviceInfo(devinfo);
110     }
111     
112     static string errorStr(int error) {
113         import std..string : fromStringz;
114         
115         if (error == NSPIRE_ERR_SUCCESS) {
116             return "No error";
117         }
118         
119         return nspire_strerror(error).fromStringz.idup;
120     }
121     
122     int writeFile(string path, void[] data) {
123         import std..string : toStringz;
124         
125         if (!isInit) {
126             return NSPIRE_ERR_NODEVICE;
127         }
128         
129         return nspire_file_write(this.handle, path.toStringz, data.ptr, data.length);
130     }
131     
132     int readFile(string path, void[] data, out size_t readBytes) {
133         import std..string : toStringz;
134         
135         if (!isInit) {
136             return NSPIRE_ERR_NODEVICE;
137         }
138         
139         return nspire_file_read(this.handle, path.toStringz, data.ptr, data.length, &readBytes);
140     }
141     
142     int moveFile(string pathSrc, string pathDst) {
143         import std..string : toStringz;
144         
145         if (!isInit) {
146             return NSPIRE_ERR_NODEVICE;
147         }
148         
149         return nspire_file_move(this.handle, pathSrc.toStringz, pathDst.toStringz);
150     }
151     
152     int copyFile(string pathSrc, string pathDst) {
153         import std..string : toStringz;
154         
155         if (!isInit) {
156             return NSPIRE_ERR_NODEVICE;
157         }
158         
159         return nspire_file_copy(this.handle, pathSrc.toStringz, pathDst.toStringz);
160     }
161     
162     int deleteFile(string path) {
163         import std..string : toStringz;
164         
165         if (!isInit) {
166             return NSPIRE_ERR_NODEVICE;
167         }
168         
169         return nspire_file_delete(this.handle, path.toStringz);
170     }
171     
172     DirItem[] dirList(string path, out int error) {
173         import std..string : toStringz;
174         import std.stdio;
175         
176         DirItem[] items;
177         nspire_dir_info* dir_info;
178         
179         
180         if (!isInit) {
181             error = NSPIRE_ERR_NODEVICE;
182             return items;
183         }
184         
185         error = nspire_dirlist(this.handle, path.toStringz, &dir_info);
186         
187         if (error != NSPIRE_ERR_SUCCESS) {
188             return null;
189         }
190         
191         nspire_dir_item* itemsMem = cast(nspire_dir_item*) &dir_info[1];
192             
193         for (size_t i = 0; i < (*dir_info).num; i++) {
194             items ~= DirItem(itemsMem[i]);
195         }
196             
197         nspire_dirlist_free(dir_info);
198         return items;
199     }
200     
201     int createDirectory(string path) {
202         import std..string : toStringz;
203         
204         if (!isInit) {
205             return NSPIRE_ERR_NODEVICE;
206         }
207         
208         return nspire_dir_create(this.handle, path.toStringz);
209     }
210     
211     int deleteDirectory(string path) {
212         import std..string : toStringz;
213         
214         if (!isInit) {
215             return NSPIRE_ERR_NODEVICE;
216         }
217         
218         return nspire_dir_delete(this.handle, path.toStringz);
219     }
220     
221     DirItem getAttr(string path, out int error) {
222         import std..string : toStringz;
223         nspire_dir_item dir_item;
224         
225         if (!isInit) {
226             error = NSPIRE_ERR_NODEVICE;
227             return DirItem();
228         }
229         
230         error = nspire_attr(this.handle, path.toStringz, &dir_item);
231         
232         if (error != NSPIRE_ERR_SUCCESS) {
233             return DirItem();
234         }
235         
236         return cast(DirItem) dir_item;
237     }
238     
239     int sendOs(void[] data) {
240         if (!isInit) {
241             return NSPIRE_ERR_NODEVICE;
242         }
243         
244         return nspire_os_send(this.handle, data.ptr, data.length);
245     }
246 }