2 Copyright 2009, Ifcaro & volca
3 Licenced under Academic Free License version 3.0
4 Review OpenUsbLd README & LICENSE files for further details.
7 #include "include/util.h"
8 #include "include/ioman.h"
14 extern void *icon_sys
;
15 extern int size_icon_sys
;
16 extern void *icon_icn
;
17 extern int size_icon_icn
;
21 int getFileSize(int fd
) {
22 int size
= fioLseek(fd
, 0, SEEK_END
);
23 fioLseek(fd
, 0, SEEK_SET
);
27 static void writeMCIcon() {
28 void** buffer
= &icon_icn
;
29 file_buffer_t
* fileBuffer
= openFileBuffer("mc?:OPL/opl.icn", O_WRONLY
| O_CREAT
| O_TRUNC
, 0, 0);
31 writeFileBuffer(fileBuffer
, (char *)buffer
, size_icon_icn
);
32 closeFileBuffer(fileBuffer
);
36 fileBuffer
= openFileBuffer("mc?:OPL/icon.sys", O_WRONLY
| O_CREAT
| O_TRUNC
, 0, 0);
38 writeFileBuffer(fileBuffer
, (char *)buffer
, size_icon_sys
);
39 closeFileBuffer(fileBuffer
);
43 static int checkMC() {
45 int fd
= fioDopen("mc0:OPL");
47 fd
= fioDopen("mc1:OPL");
49 // No base dir found on any MC, will create the folder
50 if (fioMkdir("mc0:OPL") >= 0) {
54 else if (fioMkdir("mc1:OPL") >= 0) {
72 static int checkFile(char* path
, int mode
) {
74 if (strncmp(path
, "mc", 2) == 0) {
76 // if user didn't explicitly asked for a MC (using '?' char)
77 if (path
[2] == 0x3F) {
79 // Use default detected card
86 // in create mode, we check that the directory exist, or create it
89 char* pos
= strrchr(path
, '/');
91 memcpy(dirPath
, path
, pos
- path
);
92 dirPath
[pos
- path
] = '\0';
93 int fd
= fioDopen(dirPath
);
95 if (fioMkdir(dirPath
) < 0)
106 int openFile(char* path
, int mode
) {
107 if (checkFile(path
, mode
))
108 return fioOpen(path
, mode
);
113 void* readFile(char* path
, int align
, int* size
) {
116 int fd
= openFile(path
, O_RDONLY
);
118 unsigned int realSize
= getFileSize(fd
);
120 if ((*size
> 0) && (*size
!= realSize
)) {
121 LOG("Invalid filesize, expected: %d, got: %d\n", *size
, realSize
);
127 buffer
= memalign(128, realSize
); // The allocation is aligned to aid the DMA transfers
129 buffer
= malloc(realSize
);
132 LOG("readFile: Failed allocation of %d bytes", realSize
);
135 fioRead(fd
, buffer
, realSize
);
143 void checkCreateDir(char* dirPath
) {
144 int fd
= fioDopen(dirPath
);
151 int listDir(char* path
, char* separator
, int maxElem
,
152 int (*readEntry
)(int index
, char *path
, char* separator
, char* name
, unsigned int mode
)) {
153 int fdDir
, index
= 0;
154 if (checkFile(path
, O_RDONLY
)) {
157 fdDir
= fioDopen(path
);
159 while (index
< maxElem
&& fioDread(fdDir
, &record
) > 0)
160 index
= readEntry(index
, path
, separator
, record
.name
, record
.stat
.mode
);
168 /* size will be the maximum line size possible */
169 file_buffer_t
* openFileBuffer(char* fpath
, int mode
, short allocResult
, unsigned int size
) {
170 file_buffer_t
* fileBuffer
= NULL
;
172 int fd
= openFile(fpath
, mode
);
174 fileBuffer
= (file_buffer_t
*) malloc(sizeof(file_buffer_t
));
175 fileBuffer
->size
= size
;
176 fileBuffer
->available
= 0;
177 fileBuffer
->buffer
= (char*) malloc(size
* sizeof(char));
178 if (mode
== O_RDONLY
)
179 fileBuffer
->lastPtr
= NULL
;
181 fileBuffer
->lastPtr
= fileBuffer
->buffer
;
182 fileBuffer
->allocResult
= allocResult
;
184 fileBuffer
->mode
= mode
;
190 int readFileBuffer(file_buffer_t
* fileBuffer
, char** outBuf
) {
191 int lineSize
= 0, read
, length
;
195 // if lastPtr is set, then we continue the read from this point as reference
196 if (fileBuffer
->lastPtr
) {
197 // Calculate the remaining chars to the right of lastPtr
198 lineSize
= fileBuffer
->available
- (fileBuffer
->lastPtr
- fileBuffer
->buffer
);
199 /*LOG("##### Continue read, position: %X (total: %d) line size (\\0 not inc.): %d end: %x\n",
200 fileBuffer->lastPtr - fileBuffer->buffer, fileBuffer->available, lineSize, fileBuffer->lastPtr[lineSize]);*/
201 posLF
= strchr(fileBuffer
->lastPtr
, 0x0A);
204 if (!posLF
) { // We can come here either when the buffer is empty, or if the remaining chars don't have a LF
206 // if available, we shift the remaining chars to the left ...
208 //LOG("##### LF not found, Shift %d characters from end to beginning\n", lineSize);
209 memmove(fileBuffer
->buffer
, fileBuffer
->lastPtr
, lineSize
);
212 // ... and complete the buffer if we're not at EOF
213 if (fileBuffer
->fd
>= 0) {
215 // Load as many characters necessary to fill the buffer
216 length
= fileBuffer
->size
- lineSize
- 1;
217 //LOG("##### Asking for %d characters to complete buffer\n", length);
218 read
= fioRead(fileBuffer
->fd
, fileBuffer
->buffer
+ lineSize
, length
);
219 fileBuffer
->buffer
[lineSize
+ read
] = '\0';
221 // Search again (from the lastly added chars only), the result will be "analyzed" in next if
222 posLF
= strchr(fileBuffer
->buffer
+ lineSize
, 0x0A);
224 // Now update read context info
225 lineSize
= lineSize
+ read
;
226 //LOG("##### %d characters really read, line size now (\\0 not inc.): %d\n", read, lineSize);
228 // If buffer not full it means we are at EOF
229 if (fileBuffer
->size
!= lineSize
+ 1) {
230 //LOG("##### Reached EOF\n");
231 fioClose(fileBuffer
->fd
);
236 fileBuffer
->lastPtr
= fileBuffer
->buffer
;
237 fileBuffer
->available
= lineSize
;
241 lineSize
= posLF
- fileBuffer
->lastPtr
;
243 // Check the previous char (on Windows there are CR/LF instead of single linux LF)
245 if (*(fileBuffer
->lastPtr
+ lineSize
- 1) == 0x0D)
248 fileBuffer
->lastPtr
[lineSize
] = '\0';
249 *outBuf
= fileBuffer
->lastPtr
;
251 //LOG("##### Result line is \"%s\" size: %d avail: %d pos: %d\n", fileBuffer->lastPtr, lineSize, fileBuffer->available, fileBuffer->lastPtr - fileBuffer->buffer);
253 // If we are at EOF and no more chars available to scan, then we are finished
254 if (!lineSize
&& !fileBuffer
->available
&& fileBuffer
->fd
== -1)
257 if (fileBuffer
->lastPtr
[0] == 0x23) {// '#' for comment lines
259 fileBuffer
->lastPtr
= posLF
+ 1;
261 fileBuffer
->lastPtr
= NULL
;
265 if (lineSize
&& fileBuffer
->allocResult
) {
266 *outBuf
= (char*) malloc((lineSize
+ 1) * sizeof(char));
267 memcpy(*outBuf
, fileBuffer
->lastPtr
, lineSize
+ 1);
270 // Either move the pointer to next chars, or set it to null to force a whole buffer read (if possible)
272 fileBuffer
->lastPtr
= posLF
+ 1;
274 fileBuffer
->lastPtr
= NULL
;
281 void writeFileBuffer(file_buffer_t
* fileBuffer
, char* inBuf
, int size
) {
282 //LOG("writeFileBuffer avail: %d size: %d\n", fileBuffer->available, size);
283 if (fileBuffer
->available
&& fileBuffer
->available
+ size
> fileBuffer
->size
) {
284 //LOG("writeFileBuffer flushing: %d\n", fileBuffer->available);
285 fioWrite(fileBuffer
->fd
, fileBuffer
->buffer
, fileBuffer
->available
);
286 fileBuffer
->lastPtr
= fileBuffer
->buffer
;
287 fileBuffer
->available
= 0;
290 if (size
> fileBuffer
->size
) {
291 //LOG("writeFileBuffer direct write: %d\n", size);
292 fioWrite(fileBuffer
->fd
, inBuf
, size
);
295 memcpy(fileBuffer
->lastPtr
, inBuf
, size
);
296 fileBuffer
->lastPtr
+= size
;
297 fileBuffer
->available
+= size
;
299 //LOG("writeFileBuffer lastPrt: %d\n", (fileBuffer->lastPtr - fileBuffer->buffer));
303 void closeFileBuffer(file_buffer_t
* fileBuffer
) {
304 if (fileBuffer
->fd
>= 0) {
305 if (fileBuffer
->mode
!= O_RDONLY
&& fileBuffer
->available
) {
306 //LOG("writeFileBuffer final write: %d\n", fileBuffer->available);
307 fioWrite(fileBuffer
->fd
, fileBuffer
->buffer
, fileBuffer
->available
);
309 fioClose(fileBuffer
->fd
);
311 free(fileBuffer
->buffer
);
316 // a simple maximum of two inline
317 inline int max(int a
, int b
) {
318 return a
> b
? a
: b
;
321 // a simple minimum of two inline
322 inline int min(int a
, int b
) {
323 return a
< b
? a
: b
;
326 // single digit from hex decode
327 int fromHex(char digit
) {
328 if ((digit
>= '0') && (digit
<= '9')) {
329 return (digit
- '0');
330 } else if ( (digit
>= 'A') && (digit
<= 'F') ) {
331 return (digit
- 'A' + 10);
332 } else if ( (digit
>= 'a') && (digit
<= 'f') ) {
333 return (digit
- 'a' + 10);
338 static const char htab
[16] = "0123456789ABCDEF";
339 char toHex(int digit
) {
340 return htab
[digit
& 0x0F];