µGFX  2.9
version 2.9
gfile_fs_petitfs.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 PETITFS file-system
10  ********************************************************/
11 
12 #include "../../gfx.h"
13 
14 #if GFX_USE_GFILE && GFILE_NEED_PETITFS
15 
16 #include "gfile_fs.h"
17 #include "gfile_petitfs_wrapper.h"
18 
19 static gBool petitfsExists(const char* fname);
20 static gBool petitfsOpen(GFILE* f, const char* fname);
21 static int petitfsRead(GFILE* f, void* buf, int size);
22 static gBool petitfsSetPos(GFILE* f, gFileSize pos);
23 #if GFILE_NEED_FILELISTS && _FS_MINIMIZE <= 1
24  static gfileList *petitfsFlOpen(const char *path, gBool dirs);
25  static const char *petitfsFlRead(gfileList *pfl);
26  static void petitfsFlClose(gfileList *pfl);
27 #endif
28 
29 const GFILEVMT FsPetitFSVMT = {
30  GFSFLG_WRITEABLE | GFSFLG_SEEKABLE,
31  'F',
32  0,
33  petitfsExists,
34  0, // No Filesize
35  0,
36  petitfsOpen,
37  0, // No Close
38  petitfsRead,
39  0, // No Write
40  petitfsSetPos,
41  0, // No Getsize
42  0, // No EOF
43  0, 0, 0, // No Mount, UnMount or Sync
44  #if GFILE_NEED_FILELISTS
45  #if _USE_DIR
46  petitfsFlOpen, petitfsFlRead, petitfsFlClose
47  #else
48  0, 0, 0
49  #endif
50  #endif
51 };
52 
53 // Our directory list structure
54 typedef struct petitfsList {
55  gfileList fl; // This must be the first element.
56  DIR dir;
57  FILINFO fno;
58 } petitfsList;
59 
60 // optimize these later on. Use an array to have multiple
61 static gBool petitfs_mounted = gFalse;
62 static FATFS petitfs_fs;
63 
64 static gBool petitfsExists(const char* fname)
65 {
66  // Mount first
67  if (!petitfs_mounted && pf_mount(&petitfs_fs) != FR_OK)
68  return gFalse;
69 
70  // Open
71  if (pf_open(fname) != FR_OK)
72  return gFalse;
73 
74  return gTrue;
75 }
76 
77 static gBool petitfsOpen(GFILE* f, const char* fname)
78 {
79  // No writing
80  if ((f->flags & GFILEFLG_WRITE))
81  return gFalse;
82 
83  // Mount first
84  if (!petitfs_mounted && pf_mount(&petitfs_fs) != FR_OK)
85  return gFalse;
86 
87  // Open
88  if (pf_open(fname) != FR_OK)
89  return gFalse;
90 
91  f->obj = &petitfs_fs;
92  return gTrue;
93 }
94 
95 static int petitfsRead(GFILE* f, void* buf, int size)
96 {
97  int br;
98  (void) f;
99 
100  if (pf_read(buf, size, (UINT*)&br) != FR_OK)
101  return 0;
102 
103  return br;
104 }
105 
106 static gBool petitfsSetPos(GFILE* f, gFileSize pos)
107 {
108  (void) f;
109  return pf_lseek((DWORD)pos) == FR_OK;
110 }
111 
112 #if GFILE_NEED_FILELISTS
113  static gfileList *petitfsFlOpen(const char *path, gBool dirs) {
114  petitfsList *p;
115  (void) dirs;
116 
117  if (!(p = gfxAlloc(sizeof(petitfsList))))
118  return 0;
119 
120  if (pf_opendir(&p->dir, path) != FR_OK) {
121  gfxFree(p);
122  return 0;
123  }
124  return &p->fl;
125  }
126 
127  static const char *petitfsFlRead(gfileList *pfl) {
128  #define ffl ((petitfsList *)pfl)
129 
130  while(1) {
131  // Read the next entry
132  if (pf_readdir(&ffl->dir, &ffl->fno) != FR_OK || !ffl->fno.fname[0])
133  return 0;
134 
135  /* Ignore dot entries */
136  if (ffl->fno.fname[0] == '.') continue;
137 
138  /* Is it a directory */
139  if (ffl->fl.dirs) {
140  if ((ffl->fno.fattrib & AM_DIR))
141  break;
142  } else {
143  if (!(ffl->fno.fattrib & (AM_DIR|AM_HID|AM_SYS)))
144  break;
145  }
146  }
147 
148  return ffl->fno.fname;
149  }
150 
151  static void petitfsFlClose(gfileList *pfl) {
152  gfxFree(pfl);
153  }
154 
155 #endif
156 
157 #endif //GFX_USE_GFILE && GFILE_NEED_PETITFS
GFILE file system header.
GFILE PETITFS wrapper.
struct GFILE GFILE
A file pointer.
Definition: gfile.h:34
void * gfxAlloc(gMemSize sz)
Allocate memory.
void gfxFree(void *ptr)
Free memory.