µGFX  2.9
version 2.9
gfile_fs_rom.c
1 /*
2  * This file is subject to the terms of the GFX License. If a copy of
3  * the license was not distributed with this file, you can obtain one at:
4  *
5  * http://ugfx.io/license.html
6  */
7 
8 /********************************************************
9  * The ROM file-system
10  ********************************************************/
11 
12 #include "../../gfx.h"
13 
14 #if GFX_USE_GFILE && GFILE_NEED_ROMFS
15 
16 #include "gfile_fs.h"
17 
18 #include <string.h>
19 
20 // What directory file formats do we understand
21 #define ROMFS_DIR_VER_MAX 0x0000
22 
23 // Compression Formats
24 #define ROMFS_CMP_UNCOMPRESSED 0
25 
26 typedef struct ROMFS_DIRENTRY {
27  gU16 ver; // Directory Entry Version
28  gU16 cmp; // Compression format
29  const struct ROMFS_DIRENTRY * next; // The next entry
30  const char * name; // The file name
31  gFileSize size; // The file size
32  const char * file; // The file data
33 } ROMFS_DIRENTRY;
34 
35 #define ROMFS_DIRENTRY_HEAD 0
36 #include "romfs_files.h"
37 
38 /*
39  * This should be: static const ROMFS_DIRENTRY const *FsROMHead = ROMFS_DIRENTRY_HEAD;
40  * However, some major compilers complain about the duplicate const specifier even though this is perfectly valid standard C.
41  */
42 static const ROMFS_DIRENTRY *FsROMHead = ROMFS_DIRENTRY_HEAD;
43 
44 typedef struct ROMFileList {
45  gfileList fl;
46  const ROMFS_DIRENTRY *pdir;
47 } ROMFileList;
48 
49 
50 static gBool ROMExists(const char *fname);
51 static gFileSize ROMFilesize(const char *fname);
52 static gBool ROMOpen(GFILE *f, const char *fname);
53 static void ROMClose(GFILE *f);
54 static int ROMRead(GFILE *f, void *buf, int size);
55 static gBool ROMSetpos(GFILE *f, gFileSize pos);
56 static gFileSize ROMGetsize(GFILE *f);
57 static gBool ROMEof(GFILE *f);
58 #if GFILE_NEED_FILELISTS
59  static gfileList *ROMFlOpen(const char *path, gBool dirs);
60  static const char *ROMFlRead(gfileList *pfl);
61  static void ROMFlClose(gfileList *pfl);
62 #endif
63 
64 const GFILEVMT FsROMVMT = {
65  GFSFLG_CASESENSITIVE|GFSFLG_SEEKABLE|GFSFLG_FAST, // flags
66  'S', // prefix
67  0, ROMExists, ROMFilesize, 0,
68  ROMOpen, ROMClose, ROMRead, 0,
69  ROMSetpos, ROMGetsize, ROMEof,
70  0, 0, 0,
71  #if GFILE_NEED_FILELISTS
72  ROMFlOpen, ROMFlRead, ROMFlClose
73  #endif
74 };
75 
76 static const ROMFS_DIRENTRY *ROMFindFile(const char *fname)
77 {
78  const ROMFS_DIRENTRY *p;
79 
80  for(p = FsROMHead; p; p = p->next) {
81  if (p->ver <= ROMFS_DIR_VER_MAX && p->cmp == ROMFS_CMP_UNCOMPRESSED && !strcmp(p->name, fname))
82  break;
83  }
84  return p;
85 }
86 
87 static gBool ROMExists(const char *fname)
88 {
89  return ROMFindFile(fname) != 0;
90 }
91 
92 static gFileSize ROMFilesize(const char *fname)
93 {
94  const ROMFS_DIRENTRY *p;
95 
96  if (!(p = ROMFindFile(fname))) return (gFileSize)-1;
97  return p->size;
98 }
99 
100 static gBool ROMOpen(GFILE *f, const char *fname)
101 {
102  const ROMFS_DIRENTRY *p;
103 
104  if (!(p = ROMFindFile(fname))) return gFalse;
105  f->obj = (void *)p;
106  return gTrue;
107 }
108 
109 static void ROMClose(GFILE *f)
110 {
111  (void)f;
112 }
113 
114 static int ROMRead(GFILE *f, void *buf, int size)
115 {
116  const ROMFS_DIRENTRY *p;
117 
118  p = (const ROMFS_DIRENTRY *)f->obj;
119  if (p->size - f->pos < size)
120  size = p->size - f->pos;
121  if (size <= 0) return 0;
122  memcpy(buf, p->file+f->pos, size);
123  return size;
124 }
125 
126 static gBool ROMSetpos(GFILE *f, gFileSize pos)
127 {
128  return pos <= ((const ROMFS_DIRENTRY *)f->obj)->size;
129 }
130 
131 static gFileSize ROMGetsize(GFILE *f)
132 {
133  return ((const ROMFS_DIRENTRY *)f->obj)->size;
134 }
135 
136 static gBool ROMEof(GFILE *f)
137 {
138  return f->pos >= ((const ROMFS_DIRENTRY *)f->obj)->size;
139 }
140 
141 #if GFILE_NEED_FILELISTS
142  static gfileList *ROMFlOpen(const char *path, gBool dirs) {
143  ROMFileList * p;
144  (void) path;
145 
146  // We don't support directories or path searching
147  if (dirs)
148  return 0;
149 
150  // Allocate the list buffer
151  if (!(p = gfxAlloc(sizeof(ROMFileList))))
152  return 0;
153 
154  // Initialize it and return it.
155  p->pdir = 0;
156  return &p->fl;
157  }
158 
159  static const char *ROMFlRead(gfileList *pfl) {
160  #define rfl ((ROMFileList *)pfl)
161 
162  // Is it the first entry
163  if (!rfl->pdir) {
164  rfl->pdir = FsROMHead;
165  return FsROMHead->name;
166  }
167 
168  // Is it not the last entry
169  if (rfl->pdir->next) {
170  rfl->pdir = rfl->pdir->next;
171  return rfl->pdir->name;
172  }
173 
174  return 0;
175  #undef rfl
176  }
177 
178  static void ROMFlClose(gfileList *pfl) {
179  gfxFree(pfl);
180  }
181 #endif
182 
183 #endif //GFX_USE_GFILE && GFILE_NEED_ROMFS
GFILE file system header.
struct GFILE GFILE
A file pointer.
Definition: gfile.h:34
void * gfxAlloc(gMemSize sz)
Allocate memory.
void gfxFree(void *ptr)
Free memory.