summaryrefslogtreecommitdiff
path: root/firmware/include
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/include')
-rw-r--r--firmware/include/dir.h91
-rw-r--r--firmware/include/dir_uncached.h107
-rw-r--r--firmware/include/dircache.h209
-rw-r--r--firmware/include/dircache_redirect.h198
-rw-r--r--firmware/include/disk_cache.h83
-rw-r--r--firmware/include/file.h125
-rw-r--r--firmware/include/file_internal.h371
-rw-r--r--firmware/include/fileobj_mgr.h56
-rw-r--r--firmware/include/filesystem-native.h107
-rw-r--r--firmware/include/fs_attr.h39
-rw-r--r--firmware/include/rb-loader.h1
-rw-r--r--firmware/include/rbunicode.h18
12 files changed, 1133 insertions, 272 deletions
diff --git a/firmware/include/dir.h b/firmware/include/dir.h
index 6e8b70588e..f7719823a9 100644
--- a/firmware/include/dir.h
+++ b/firmware/include/dir.h
@@ -18,46 +18,71 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21
22#ifndef _DIR_H_ 21#ifndef _DIR_H_
23#define _DIR_H_ 22#define _DIR_H_
24 23
24#include <sys/types.h>
25#include <fcntl.h>
26#include <time.h>
25#include "config.h" 27#include "config.h"
28#include "fs_attr.h"
26 29
27#define ATTR_READ_ONLY 0x01 30#if defined (APPLICATION)
28#define ATTR_HIDDEN 0x02 31#include "filesystem-app.h"
29#define ATTR_SYSTEM 0x04 32#elif defined(SIMULATOR) || defined(__PCTOOL__)
30#define ATTR_VOLUME_ID 0x08 33#include "../../uisimulator/common/filesystem-sim.h"
31#define ATTR_DIRECTORY 0x10
32#define ATTR_ARCHIVE 0x20
33#define ATTR_VOLUME 0x40 /* this is a volume, not a real directory */
34#define ATTR_LINK 0x80
35
36#ifdef HAVE_DIRCACHE
37# include "dircache.h"
38# define DIR DIR_CACHED
39# define dirent dirent_cached
40# define opendir opendir_cached
41# define closedir closedir_cached
42# define readdir readdir_cached
43# define closedir closedir_cached
44# define mkdir mkdir_cached
45# define rmdir rmdir_cached
46#else 34#else
47# include "dir_uncached.h" 35#include "filesystem-native.h"
48# define DIR DIR_UNCACHED 36#endif
49# define dirent dirent_uncached 37
50# define opendir opendir_uncached 38#ifndef DIRFUNCTIONS_DEFINED
51# define closedir closedir_uncached 39#ifndef opendir
52# define readdir readdir_uncached 40#define opendir FS_PREFIX(opendir)
53# define closedir closedir_uncached 41#endif
54# define mkdir mkdir_uncached 42#ifndef readdir
55# define rmdir rmdir_uncached 43#define readdir FS_PREFIX(readdir)
44#endif
45#ifndef readdir_r
46#define readdir_r FS_PREFIX(readdir_r)
47#endif
48#ifndef rewinddir
49#define rewinddir FS_PREFIX(rewinddir)
56#endif 50#endif
51#ifndef closedir
52#define closedir FS_PREFIX(closedir)
53#endif
54#ifndef mkdir
55#define mkdir FS_PREFIX(mkdir)
56#endif
57#ifndef rmdir
58#define rmdir FS_PREFIX(rmdir)
59#endif
60#ifndef samedir
61#define samedir FS_PREFIX(samedir)
62#endif
63#ifndef dir_exists
64#define dir_exists FS_PREFIX(dir_exists)
65#endif
66#endif /* !DIRFUNCTIONS_DEFINED */
57 67
68#ifndef DIRENT_DEFINED
69struct DIRENT
70{
71 struct dirinfo_native info; /* platform extra info */
72 char d_name[MAX_PATH]; /* UTF-8 name of entry (last!) */
73};
74#endif /* DIRENT_DEFINED */
58 75
59typedef DIR* (*opendir_func)(const char* name); 76struct dirinfo
60typedef int (*closedir_func)(DIR* dir); 77{
61typedef struct dirent* (*readdir_func)(DIR* dir); 78 unsigned int attribute; /* attribute bits of file */
79 off_t size; /* binary size of file */
80 time_t mtime; /* local file time */
81};
62 82
63#endif 83#ifndef DIRFUNCTIONS_DECLARED
84/* TIP: set errno to zero before calling to see if anything failed */
85struct dirinfo dir_get_info(DIR *dirp, struct DIRENT *entry);
86#endif /* !DIRFUNCTIONS_DECLARED */
87
88#endif /* _DIR_H_ */
diff --git a/firmware/include/dir_uncached.h b/firmware/include/dir_uncached.h
deleted file mode 100644
index 6443d5ba97..0000000000
--- a/firmware/include/dir_uncached.h
+++ /dev/null
@@ -1,107 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: dir.h 13741 2007-06-30 02:08:27Z jethead71 $
9 *
10 * Copyright (C) 2002 by Björn Stenberg
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _DIR_UNCACHED_H_
22#define _DIR_UNCACHED_H_
23
24#include "config.h"
25
26struct dirinfo {
27 int attribute;
28 long size;
29 unsigned short wrtdate;
30 unsigned short wrttime;
31};
32
33#include <stdbool.h>
34#include "file.h"
35
36#if defined(SIMULATOR) || defined(__PCTOOL__)
37# define dirent_uncached sim_dirent
38# define DIR_UNCACHED SIM_DIR
39# define opendir_uncached sim_opendir
40# define readdir_uncached sim_readdir
41# define closedir_uncached sim_closedir
42# define mkdir_uncached sim_mkdir
43# define rmdir_uncached sim_rmdir
44#elif defined(APPLICATION)
45# include "rbpaths.h"
46# define DIRENT_DEFINED
47# define DIR_DEFINED
48# define dirent_uncached dirent
49# define DIR_UNCACHED DIR
50# define opendir_uncached app_opendir
51# define readdir_uncached app_readdir
52# define closedir_uncached app_closedir
53# define mkdir_uncached app_mkdir
54# define rmdir_uncached app_rmdir
55#endif
56
57
58#ifndef DIRENT_DEFINED
59struct dirent_uncached {
60 unsigned char d_name[MAX_PATH];
61 struct dirinfo info;
62 long startcluster;
63};
64#endif
65
66#include "fat.h"
67
68#ifndef DIR_DEFINED
69typedef struct {
70#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
71 struct fat_dir fatdir CACHEALIGN_ATTR;
72 bool busy;
73 long startcluster;
74 struct dirent_uncached theent;
75#ifdef HAVE_MULTIVOLUME
76 int volumecounter; /* running counter for faked volume entries */
77#endif
78#else
79 /* simulator/application: */
80 void *dir; /* actually a DIR* dir */
81 char *name;
82#endif
83} DIR_UNCACHED CACHEALIGN_ATTR;
84#endif
85
86#ifdef HAVE_HOTSWAP
87char *get_volume_name(int volume);
88#endif
89
90#ifdef HAVE_MULTIVOLUME
91 int strip_volume(const char*, char*);
92#endif
93
94#ifndef DIRFUNCTIONS_DEFINED
95
96extern DIR_UNCACHED* opendir_uncached(const char* name);
97extern int closedir_uncached(DIR_UNCACHED* dir);
98extern int mkdir_uncached(const char* name);
99extern int rmdir_uncached(const char* name);
100
101extern struct dirent_uncached* readdir_uncached(DIR_UNCACHED* dir);
102
103extern int release_dirs(int volume);
104
105#endif /* DIRFUNCTIONS_DEFINED */
106
107#endif
diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h
index 019ccf49b7..7e8c764e7f 100644
--- a/firmware/include/dircache.h
+++ b/firmware/include/dircache.h
@@ -8,6 +8,7 @@
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2005 by Miika Pekkarinen 10 * Copyright (C) 2005 by Miika Pekkarinen
11 * Copyright (C) 2014 by Michael Sevakis
11 * 12 *
12 * This program is free software; you can redistribute it and/or 13 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 14 * modify it under the terms of the GNU General Public License
@@ -21,84 +22,154 @@
21#ifndef _DIRCACHE_H 22#ifndef _DIRCACHE_H
22#define _DIRCACHE_H 23#define _DIRCACHE_H
23 24
24#include "config.h" 25#include "mv.h"
25#include "dir_uncached.h" 26#include <string.h> /* size_t */
26#include <string.h> /* size_t */ 27#include <sys/types.h> /* ssize_t */
27 28
28#ifdef HAVE_DIRCACHE 29#ifdef HAVE_DIRCACHE
29 30
30#define DIRCACHE_RESERVE (1024*64) 31/****************************************************************************
31#define DIRCACHE_LIMIT (1024*1024*6) 32 ** Configurable values
32 33 **/
33#define DIRCACHE_APPFLAG_TAGCACHE 0x0001 34
34#define DIRCACHE_APPFLAG_PLAYLIST 0x0002 35#if 0
35 36/* enable dumping code */
36/* Internal structures. */ 37#define DIRCACHE_DUMPSTER
37struct travel_data { 38#define DIRCACHE_DUMPSTER_BIN "/dircache_dump.bin"
38 struct dircache_entry *first; 39#define DIRCACHE_DUMPSTER_CSV "/dircache_dump.csv"
39 struct dircache_entry *ce;
40 struct dircache_entry *down_entry;
41#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
42 DIR_UNCACHED *dir, *newdir;
43 struct dirent_uncached *entry;
44#else
45 struct fat_dir *dir;
46 struct fat_dir newdir;
47 struct fat_direntry entry;
48#endif 40#endif
49 int pathpos; 41
42/* dircache builds won't search below this but will work down to this point
43 while below it the cache will just pass requests through to the storage;
44 the limiting factor is the scanning thread stack size, not the
45 implementation -- tune the two together */
46#define DIRCACHE_MAX_DEPTH 15
47#define DIRCACHE_STACK_SIZE (DEFAULT_STACK_SIZE + 0x100)
48
49/* memory buffer constants that control allocation */
50#define DIRCACHE_RESERVE (1024*64) /* 64 KB - new entry slack */
51#define DIRCACHE_MIN (1024*1024*1) /* 1 MB - provision min size */
52#define DIRCACHE_LIMIT (1024*1024*6) /* 6 MB - provision max size */
53
54/* make it easy to change serialnumber size without modifying anything else;
55 32 bits allows 21845 builds before wrapping in a 6MB cache that is filled
56 exclusively with entries and nothing else (32 byte entries), making that
57 figure pessimistic */
58typedef uint32_t dc_serial_t;
59
60/**
61 ****************************************************************************/
62
63#if CONFIG_PLATFORM & PLATFORM_NATIVE
64/* native dircache is lower-level than on a hosted target */
65#define DIRCACHE_NATIVE
66#endif
67
68struct dircache_file
69{
70 int idx; /* this file's cache index */
71 dc_serial_t serialnum; /* this file's serial number */
50}; 72};
51 73
52struct dirent_cached { 74enum dircache_status
53 struct dirinfo info; 75{
54 char *d_name; 76 DIRCACHE_IDLE = 0, /* no volume is initialized */
55 long startcluster; 77 DIRCACHE_SCANNING = 1, /* dircache is scanning a volume */
78 DIRCACHE_READY = 2, /* dircache is ready to be used */
79};
80
81/** Dircache control **/
82void dircache_wait(void);
83void dircache_suspend(void);
84int dircache_resume(void);
85int dircache_enable(void);
86void dircache_disable(void);
87void dircache_free_buffer(void);
88
89/** Volume mounting **/
90void dircache_mount(void); /* always tries building everything it can */
91void dircache_unmount(IF_MV_NONVOID(int volume));
92
93
94/** File API service functions **/
95
96/* avoid forcing #include of file_internal.h, fat.h and dir.h */
97struct filestr_base;
98struct file_base_info;
99struct file_base_binding;
100struct dirent;
101struct dirscan_info;
102struct dirinfo_native;
103
104int dircache_readdir_dirent(struct filestr_base *stream,
105 struct dirscan_info *scanp,
106 struct dirent *entry);
107void dircache_rewinddir_dirent(struct dirscan_info *scanp);
108
109#ifdef DIRCACHE_NATIVE
110struct fat_direntry;
111int dircache_readdir_internal(struct filestr_base *stream,
112 struct file_base_info *infop,
113 struct fat_direntry *fatent);
114void dircache_rewinddir_internal(struct file_base_info *info);
115#endif /* DIRCACHE_NATIVE */
116
117
118/** Dircache live updating **/
119
120void dircache_get_rootinfo(struct file_base_info *infop);
121void dircache_bind_file(struct file_base_binding *bindp);
122void dircache_unbind_file(struct file_base_binding *bindp);
123void dircache_fileop_create(struct file_base_info *dirinfop,
124 struct file_base_binding *bindp,
125 const char *basename,
126 const struct dirinfo_native *dinp);
127void dircache_fileop_rename(struct file_base_info *dirinfop,
128 struct file_base_binding *bindp,
129 const char *basename);
130void dircache_fileop_remove(struct file_base_binding *bindp);
131void dircache_fileop_sync(struct file_base_binding *infop,
132 const struct dirinfo_native *dinp);
133
134
135/** Dircache paths and files **/
136ssize_t dircache_get_path(const struct dircache_file *dcfilep, char *buf,
137 size_t size);
138int dircache_get_file(const char *path, struct dircache_file *dcfilep);
139
140
141/** Debug screen/info stuff **/
142
143struct dircache_info
144{
145 enum dircache_status status; /* current composite status value */
146 const char *statusdesc; /* pointer to string describing 'status' */
147 size_t last_size; /* cache size after last build */
148 size_t size; /* total size of entries (with holes) */
149 size_t sizeused; /* bytes of 'size' actually utilized */
150 size_t size_limit; /* maximum possible size */
151 size_t reserve; /* size of reserve area */
152 size_t reserve_used; /* amount of reserve used */
153 unsigned int entry_count; /* number of cache entries */
154 long build_ticks; /* total time used to build cache */
56}; 155};
57 156
58typedef struct { 157void dircache_get_info(struct dircache_info *info);
59 bool busy; 158#ifdef DIRCACHE_DUMPSTER
60 struct dirent_cached theent; /* .attribute is set to -1 on init(opendir) */ 159void dircache_dump(void);
61 int internal_entry; /* the current entry in the directory */ 160#endif /* DIRCACHE_DUMPSTER */
62 DIR_UNCACHED *regulardir; 161
63} DIR_CACHED;
64 162
65void dircache_init(void) INIT_ATTR; 163/** Misc. stuff **/
164void dircache_dcfile_init(struct dircache_file *dcfilep);
165
166#ifdef HAVE_EEPROM_SETTINGS
66int dircache_load(void); 167int dircache_load(void);
67int dircache_save(void); 168int dircache_save(void);
68int dircache_build(int last_size); 169#endif /* HAVE_EEPROM_SETTINGS */
69void* dircache_steal_buffer(size_t *size);
70bool dircache_is_enabled(void);
71bool dircache_is_initializing(void);
72void dircache_set_appflag(long mask);
73bool dircache_get_appflag(long mask);
74int dircache_get_entry_count(void);
75int dircache_get_cache_size(void);
76int dircache_get_reserve_used(void);
77int dircache_get_build_ticks(void);
78void dircache_disable(void);
79void dircache_suspend(void);
80bool dircache_resume(void);
81int dircache_get_entry_id(const char *filename);
82size_t dircache_copy_path(int index, char *buf, size_t size);
83
84/* the next two are internal for file.c */
85long _dircache_get_entry_startcluster(int id);
86struct dirinfo* _dircache_get_entry_dirinfo(int id);
87
88void dircache_bind(int fd, const char *path);
89void dircache_update_filesize(int fd, long newsize, long startcluster);
90void dircache_update_filetime(int fd);
91void dircache_mkdir(const char *path);
92void dircache_rmdir(const char *path);
93void dircache_remove(const char *name);
94void dircache_rename(const char *oldpath, const char *newpath);
95void dircache_add_file(const char *path, long startcluster);
96
97DIR_CACHED* opendir_cached(const char* name);
98struct dirent_cached* readdir_cached(DIR_CACHED* dir);
99int closedir_cached(DIR_CACHED *dir);
100int mkdir_cached(const char *name);
101int rmdir_cached(const char* name);
102#endif /* !HAVE_DIRCACHE */
103 170
104#endif 171void dircache_init(size_t last_size) INIT_ATTR;
172
173#endif /* HAVE_DIRCACHE */
174
175#endif /* _DIRCACHE_H */
diff --git a/firmware/include/dircache_redirect.h b/firmware/include/dircache_redirect.h
new file mode 100644
index 0000000000..15fb4bc38d
--- /dev/null
+++ b/firmware/include/dircache_redirect.h
@@ -0,0 +1,198 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 by Michael Sevakis
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _DIRCACHE_REDIRECT_H_
22
23#include "dir.h"
24
25/***
26 ** Internal redirects that depend upon whether or not dircache is made
27 **/
28
29/** File binding **/
30
31static inline void get_rootinfo_internal(struct file_base_info *infop)
32{
33#ifdef HAVE_DIRCACHE
34 dircache_get_rootinfo(infop);
35#else
36 (void)infop;
37#endif
38}
39
40static inline void fileobj_bind_file(struct file_base_binding *bindp)
41{
42#ifdef HAVE_DIRCACHE
43 dircache_bind_file(bindp);
44#else
45 file_binding_insert_last(bindp);
46#endif
47}
48
49static inline void fileobj_unbind_file(struct file_base_binding *bindp)
50{
51#ifdef HAVE_DIRCACHE
52 dircache_unbind_file(bindp);
53#else
54 file_binding_remove(bindp);
55#endif
56}
57
58
59/** File event handlers **/
60
61static inline void fileop_onopen_internal(struct filestr_base *stream,
62 struct file_base_info *srcinfop,
63 unsigned int callflags)
64{
65 fileobj_fileop_open(stream, srcinfop, callflags);
66}
67
68static inline void fileop_onclose_internal(struct filestr_base *stream)
69{
70 fileobj_fileop_close(stream);
71}
72
73static inline void fileop_oncreate_internal(struct filestr_base *stream,
74 struct file_base_info *srcinfop,
75 unsigned int callflags,
76 struct file_base_info *dirinfop,
77 const char *basename)
78{
79#ifdef HAVE_DIRCACHE
80 dircache_dcfile_init(&srcinfop->dcfile);
81#endif
82 fileobj_fileop_create(stream, srcinfop, callflags);
83#ifdef HAVE_DIRCACHE
84 struct dirinfo_native din;
85 fill_dirinfo_native(&din);
86 dircache_fileop_create(dirinfop, stream->bindp, basename, &din);
87#endif
88 (void)dirinfop; (void)basename;
89}
90
91static inline void fileop_onremove_internal(struct filestr_base *stream,
92 struct file_base_info *oldinfop)
93{
94 fileobj_fileop_remove(stream, oldinfop);
95#ifdef HAVE_DIRCACHE
96 dircache_fileop_remove(stream->bindp);
97#endif
98}
99
100static inline void fileop_onrename_internal(struct filestr_base *stream,
101 struct file_base_info *oldinfop,
102 struct file_base_info *dirinfop,
103 const char *basename)
104{
105 fileobj_fileop_rename(stream, oldinfop);
106#ifdef HAVE_DIRCACHE
107 dircache_fileop_rename(dirinfop, stream->bindp, basename);
108#endif
109 (void)dirinfop; (void)basename;
110}
111
112static inline void fileop_onsync_internal(struct filestr_base *stream)
113{
114 fileobj_fileop_sync(stream);
115#ifdef HAVE_DIRCACHE
116 struct dirinfo_native din;
117 fill_dirinfo_native(&din);
118 dircache_fileop_sync(stream->bindp, &din);
119#endif
120}
121
122static inline void fileop_ontruncate_internal(struct filestr_base *stream)
123{
124 fileobj_fileop_truncate(stream);
125}
126
127static inline void volume_onmount_internal(IF_MV_NONVOID(int volume))
128{
129#ifdef HAVE_DIRCACHE
130 dircache_mount();
131#endif
132 IF_MV( (void)volume; )
133}
134
135static inline void volume_onunmount_internal(IF_MV_NONVOID(int volume))
136{
137 fileobj_mgr_unmount(IF_MV(volume));
138#ifdef HAVE_DIRCACHE
139 dircache_unmount(IF_MV(volume));
140#endif
141}
142
143
144/** Directory reading **/
145
146static inline int readdir_dirent(struct filestr_base *stream,
147 struct dirscan_info *scanp,
148 struct dirent *entry)
149{
150#ifdef HAVE_DIRCACHE
151 return dircache_readdir_dirent(stream, scanp, entry);
152#else
153 return uncached_readdir_dirent(stream, scanp, entry);
154#endif
155}
156
157static inline void rewinddir_dirent(struct dirscan_info *scanp)
158{
159#ifdef HAVE_DIRCACHE
160 dircache_rewinddir_dirent(scanp);
161#else
162 uncached_rewinddir_dirent(scanp);
163#endif
164}
165
166static inline int readdir_internal(struct filestr_base *stream,
167 struct file_base_info *infop,
168 struct fat_direntry *fatent)
169{
170#ifdef HAVE_DIRCACHE
171 return dircache_readdir_internal(stream, infop, fatent);
172#else
173 return uncached_readdir_internal(stream, infop, fatent);
174#endif
175}
176
177static inline void rewinddir_internal(struct file_base_info *infop)
178{
179#ifdef HAVE_DIRCACHE
180 dircache_rewinddir_internal(infop);
181#else
182 uncached_rewinddir_internal(infop);
183#endif
184}
185
186
187/** Misc. stuff **/
188
189static inline struct fat_direntry *get_dir_fatent_dircache(void)
190{
191#ifdef HAVE_DIRCACHE
192 return get_dir_fatent();
193#else
194 return NULL;
195#endif
196}
197
198#endif /* _DIRCACHE_REDIRECT_H_ */
diff --git a/firmware/include/disk_cache.h b/firmware/include/disk_cache.h
new file mode 100644
index 0000000000..725b3778cc
--- /dev/null
+++ b/firmware/include/disk_cache.h
@@ -0,0 +1,83 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 by Michael Sevakis
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef DISK_CACHE_H
22#define DISK_CACHE_H
23
24/* This needs enough for all file handles to have a buffer in the worst case
25 * plus at least one reserved exclusively for the cache client and a couple
26 * for other file system code. The buffers are put to use by the cache if not
27 * taken for another purpose (meaning nothing is wasted sitting fallow).
28 *
29 * One map per volume is maintained in order to avoid collisions between
30 * volumes that would slow cache probing. DC_MAP_NUM_ENTRIES is the number
31 * for each map per volume. The buffers themselves are shared.
32 */
33#if MEMORYSIZE < 8
34#define DC_NUM_ENTRIES 32
35#define DC_MAP_NUM_ENTRIES 128
36#elif MEMORYSIZE <= 32
37#define DC_NUM_ENTRIES 48
38#define DC_MAP_NUM_ENTRIES 128
39#else /* MEMORYSIZE > 32 */
40#define DC_NUM_ENTRIES 64
41#define DC_MAP_NUM_ENTRIES 256
42#endif /* MEMORYSIZE */
43
44/* this _could_ be larger than a sector if that would ever be useful */
45#define DC_CACHE_BUFSIZE SECTOR_SIZE
46
47#include "mutex.h"
48#include "mv.h"
49
50static inline void dc_lock_cache(void)
51{
52 extern struct mutex disk_cache_mutex;
53 mutex_lock(&disk_cache_mutex);
54}
55
56static inline void dc_unlock_cache(void)
57{
58 extern struct mutex disk_cache_mutex;
59 mutex_unlock(&disk_cache_mutex);
60}
61
62void * dc_cache_probe(IF_MV(int volume,) unsigned long secnum,
63 unsigned int *flags);
64void dc_dirty_buf(void *buf);
65void dc_discard_buf(void *buf);
66void dc_commit_all(IF_MV_NONVOID(int volume));
67void dc_discard_all(IF_MV_NONVOID(int volume));
68
69void dc_init(void) INIT_ATTR;
70
71/* in addition to filling, writeback is implemented by the client */
72extern void dc_writeback_callback(IF_MV(int volume, ) unsigned long sector,
73 void *buf);
74
75
76/** These synchronize and can be called by anyone **/
77
78/* expropriate a buffer from the cache of DC_CACHE_BUFSIZE bytes */
79void * dc_get_buffer(void);
80/* return buffer to the cache by buffer */
81void dc_release_buffer(void *buf);
82
83#endif /* DISK_CACHE_H */
diff --git a/firmware/include/file.h b/firmware/include/file.h
index 77930864c7..8e5bacec0e 100644
--- a/firmware/include/file.h
+++ b/firmware/include/file.h
@@ -18,81 +18,88 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21
22#ifndef _FILE_H_ 21#ifndef _FILE_H_
23#define _FILE_H_ 22#define _FILE_H_
24 23
25#include <sys/types.h> 24#include <sys/types.h>
26#include "config.h" 25#include <stdbool.h>
27#include "gcc_extensions.h"
28#include <fcntl.h> 26#include <fcntl.h>
29#ifdef WIN32 27#ifdef WIN32
30/* this has SEEK_SET et al */ 28/* this has SEEK_SET et al */
31#include <stdio.h> 29#include <stdio.h>
32#endif 30#endif
33 31#include "config.h"
32#include "gcc_extensions.h"
34 33
35#undef MAX_PATH /* this avoids problems when building simulator */ 34#undef MAX_PATH /* this avoids problems when building simulator */
36#define MAX_PATH 260 35#define MAX_PATH 260
37#define MAX_OPEN_FILES 11
38 36
39#if !defined(PLUGIN) && !defined(CODEC) 37enum relate_result
40#if defined(APPLICATION) && !defined(__PCTOOL__) 38{
41#include "rbpaths.h" 39 /* < 0 == failure */
42# define open(x, ...) app_open(x, __VA_ARGS__) 40 RELATE_DIFFERENT = 0, /* the two paths are different objects */
43# define creat(x,m) app_creat(x, m) 41 RELATE_SAME, /* the two paths are the same object */
44# define remove(x) app_remove(x) 42 RELATE_PREFIX, /* the path2 contains path1 as a prefix */
45# define rename(x,y) app_rename(x,y) 43};
46# define readlink(x,y,z) app_readlink(x,y,z)
47# if (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA))
48/* SDL overrides a few more */
49# define read(x,y,z) sim_read(x,y,z)
50# define write(x,y,z) sim_write(x,y,z)
51# endif
52#elif defined(SIMULATOR) || defined(DBTOOL)
53# define open(x, ...) sim_open(x, __VA_ARGS__)
54# define creat(x,m) sim_creat(x,m)
55# define remove(x) sim_remove(x)
56# define rename(x,y) sim_rename(x,y)
57# define fsync(x) sim_fsync(x)
58# define ftruncate(x,y) sim_ftruncate(x,y)
59# define lseek(x,y,z) sim_lseek(x,y,z)
60# define read(x,y,z) sim_read(x,y,z)
61# define write(x,y,z) sim_write(x,y,z)
62# define close(x) sim_close(x)
63/* readlink() not used in the sim yet */
64extern int sim_open(const char *name, int o, ...);
65extern int sim_creat(const char *name, mode_t mode);
66#endif
67 44
68typedef int (*open_func)(const char* pathname, int flags, ...); 45#if defined(APPLICATION)
69typedef ssize_t (*read_func)(int fd, void *buf, size_t count); 46#include "filesystem-app.h"
70typedef int (*creat_func)(const char *pathname, mode_t mode); 47#elif defined(SIMULATOR) || defined(__PCTOOL__)
71typedef ssize_t (*write_func)(int fd, const void *buf, size_t count); 48#include "../../uisimulator/common/filesystem-sim.h"
72typedef void (*qsort_func)(void *base, size_t nmemb, size_t size, 49#else
73 int(*_compar)(const void *, const void *)); 50#include "filesystem-native.h"
51#endif
74 52
75extern int file_open(const char* pathname, int flags); 53#ifndef FILEFUNCTIONS_DECLARED
76extern int close(int fd); 54int fdprintf(int fildes, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3);
77extern int fsync(int fd); 55#endif /* FILEFUNCTIONS_DECLARED */
78extern ssize_t read(int fd, void *buf, size_t count);
79extern off_t lseek(int fildes, off_t offset, int whence);
80extern int file_creat(const char *pathname);
81#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) && !defined(__PCTOOL__)) || \
82 defined(TEST_FAT)
83#define creat(x, y) file_creat(x)
84 56
85#if !defined(CODEC) && !defined(PLUGIN) 57#ifndef FILEFUNCTIONS_DEFINED
86#define open(x, y, ...) file_open(x,y) 58#ifndef open
59#define open FS_PREFIX(open)
87#endif 60#endif
61#ifndef creat
62#define creat FS_PREFIX(creat)
88#endif 63#endif
89 64#ifndef close
90extern ssize_t write(int fd, const void *buf, size_t count); 65#define close FS_PREFIX(close)
91extern int remove(const char* pathname); 66#endif
92extern int rename(const char* path, const char* newname); 67#ifndef ftruncate
93extern int ftruncate(int fd, off_t length); 68#define ftruncate FS_PREFIX(ftruncate)
94extern off_t filesize(int fd); 69#endif
95extern int release_files(int volume); 70#ifndef fsync
96int fdprintf (int fd, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3); 71#define fsync FS_PREFIX(fsync)
97#endif /* !CODEC && !PLUGIN */
98#endif 72#endif
73#ifndef lseek
74#define lseek FS_PREFIX(lseek)
75#endif
76#ifndef read
77#define read FS_PREFIX(read)
78#endif
79#ifndef write
80#define write FS_PREFIX(write)
81#endif
82#ifndef remove
83#define remove FS_PREFIX(remove)
84#endif
85#ifndef rename
86#define rename FS_PREFIX(rename)
87#endif
88#ifndef filesize
89#define filesize FS_PREFIX(filesize)
90#endif
91#ifndef fsamefile
92#define fsamefile FS_PREFIX(fsamefile)
93#endif
94#ifndef file_exists
95#define file_exists FS_PREFIX(file_exists)
96#endif
97#ifndef relate
98#define relate FS_PREFIX(relate)
99#endif
100#ifndef readlink
101#define readlink FS_PREFIX(readlink)
102#endif
103#endif /* FILEFUNCTIONS_DEFINED */
104
105#endif /* _FILE_H_ */
diff --git a/firmware/include/file_internal.h b/firmware/include/file_internal.h
new file mode 100644
index 0000000000..d1bb67406a
--- /dev/null
+++ b/firmware/include/file_internal.h
@@ -0,0 +1,371 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 by Michael Sevakis
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _FILE_INTERNAL_H_
22#define _FILE_INTERNAL_H_
23
24#include <sys/types.h>
25#include <stdlib.h>
26#include "mv.h"
27#include "linked_list.h"
28#include "mutex.h"
29#include "mrsw_lock.h"
30#include "fs_attr.h"
31#include "fat.h"
32#ifdef HAVE_DIRCACHE
33#include "dircache.h"
34#endif
35
36/** Tuneable parameters **/
37
38/* limits for number of open descriptors - if you increase these values, make
39 certain that the disk cache has enough available buffers */
40#define MAX_OPEN_FILES 11
41#define MAX_OPEN_DIRS 12
42#define MAX_OPEN_HANDLES (MAX_OPEN_FILES+MAX_OPEN_DIRS)
43
44/* internal functions open streams as well; make sure they don't fail if all
45 user descs are busy; this needs to be at least the greatest quantity needed
46 at once by all internal functions */
47#ifdef HAVE_DIRCACHE
48#define AUX_FILEOBJS 3
49#else
50#define AUX_FILEOBJS 2
51#endif
52
53/* number of components statically allocated to handle the vast majority
54 of path depths; should maybe be tuned for >= 90th percentile but for now,
55 imma just guessing based on something like:
56 root + 'Music' + 'Artist' + 'Album' + 'Disc N' + filename */
57#define STATIC_PATHCOMP_NUM 6
58
59#define MAX_NAME 255
60
61/* unsigned value that will also hold the off_t range we need without
62 overflow */
63#define file_size_t uint32_t
64
65#ifdef __USE_FILE_OFFSET64
66/* if we want, we can deal with files up to 2^32-1 bytes-- the full FAT16/32
67 range */
68#define FILE_SIZE_MAX (0xffffffffu)
69#else
70/* file contents and size will be preserved by the APIs so long as ftruncate()
71 isn't used; bytes passed 2^31-1 will not accessible nor will writes succeed
72 that would extend the file beyond the max for a 32-bit off_t */
73#define FILE_SIZE_MAX (0x7fffffffu)
74#endif
75
76/* if file is "large(ish)", then get rid of the contents now rather than
77 lazily when the file is synced or closed in order to free-up space */
78#define O_TRUNC_THRESH 65536
79
80/* default attributes when creating new files and directories */
81#define ATTR_NEW_FILE (ATTR_ARCHIVE)
82#define ATTR_NEW_DIRECTORY (ATTR_DIRECTORY)
83
84#define ATTR_MOUNT_POINT (ATTR_VOLUME | ATTR_DIRECTORY)
85
86/** File sector cache **/
87
88enum filestr_cache_flags
89{
90 FSC_DIRTY = 0x1, /* buffer is dirty (needs writeback) */
91 FSC_NEW = 0x2, /* buffer is new (never yet written) */
92};
93
94struct filestr_cache
95{
96 uint8_t *buffer; /* buffer to hold sector */
97 unsigned long sector; /* file sector that is in buffer */
98 unsigned int flags; /* FSC_* bits */
99};
100
101void file_cache_init(struct filestr_cache *cachep);
102void file_cache_reset(struct filestr_cache *cachep);
103void file_cache_alloc(struct filestr_cache *cachep);
104void file_cache_free(struct filestr_cache *cachep);
105
106
107/** Common bitflags used throughout **/
108
109/* bitflags used by open files and descriptors */
110enum fildes_and_obj_flags
111{
112 /* used in descriptor and common */
113 FDO_BUSY = 0x0001, /* descriptor/object is in use */
114 /* only used in individual stream descriptor */
115 FD_WRITE = 0x0002, /* descriptor has write mode */
116 FD_WRONLY = 0x0004, /* descriptor is write mode only */
117 FD_APPEND = 0x0008, /* descriptor is append mode */
118 /* only used as common flags */
119 FO_DIRECTORY = 0x0010, /* fileobj is a directory */
120 FO_TRUNC = 0x0020, /* fileobj is opened to be truncated */
121 FO_REMOVED = 0x0040, /* fileobj was deleted while open */
122 FO_SINGLE = 0x0080, /* fileobj has only one stream open */
123 FDO_MASK = 0x00ff,
124 /* bitflags that instruct various 'open' functions how to behave */
125 FF_FILE = 0x0000, /* expect file; accept file only */
126 FF_DIR = 0x0100, /* expect dir; accept dir only */
127 FF_ANYTYPE = 0x0200, /* succeed if either file or dir */
128 FF_TYPEMASK = 0x0300, /* mask of typeflags */
129 FF_CREAT = 0x0400, /* create if file doesn't exist */
130 FF_EXCL = 0x0800, /* fail if creating and file exists */
131 FF_CHECKPREFIX = 0x1000, /* detect if file is prefix of path */
132 FF_NOISO = 0x2000, /* do not decode ISO filenames to UTF-8 */
133 FF_MASK = 0x3f00,
134 /* special values used in isolation */
135 FV_NONEXIST = 0x8000, /* closed but not freed (unmounted) */
136 FV_OPENSYSROOT = 0xc001, /* open sysroot, volume 0 not mounted */
137};
138
139
140/** Common data structures used throughout **/
141
142/* basic file information about its location */
143struct file_base_info
144{
145 union {
146#ifdef HAVE_MULTIVOLUME
147 int volume; /* file's volume (overlaps fatfile.volume) */
148#endif
149#if CONFIG_PLATFORM & PLATFORM_NATIVE
150 struct fat_file fatfile; /* FS driver file info */
151#endif
152 };
153#ifdef HAVE_DIRCACHE
154 struct dircache_file dcfile; /* dircache file info */
155#endif
156};
157
158#define BASEINFO_VOL(infop) \
159 IF_MV_VOL((infop)->volume)
160
161/* open files binding item */
162struct file_base_binding
163{
164 struct ll_node node; /* list item node (first!) */
165 struct file_base_info info; /* basic file info */
166};
167
168#define BASEBINDING_VOL(bindp) \
169 BASEINFO_VOL(&(bindp)->info)
170
171/* directory scanning position info */
172struct dirscan_info
173{
174#if CONFIG_PLATFORM & PLATFORM_NATIVE
175 struct fat_dirscan_info fatscan; /* FS driver scan info */
176#endif
177#ifdef HAVE_DIRCACHE
178 struct dircache_file dcscan; /* dircache scan info */
179#endif
180};
181
182/* describes the file as an open stream */
183struct filestr_base
184{
185 struct ll_node node; /* list item node (first!) */
186 uint16_t flags; /* FD_* bits of this stream */
187 uint16_t unused; /* not used */
188 struct filestr_cache cache; /* stream-local cache */
189 struct filestr_cache *cachep; /* the cache in use (local or shared) */
190 struct file_base_info *infop; /* base file information */
191 struct fat_filestr fatstr; /* FS driver information */
192 struct file_base_binding *bindp; /* common binding for file/dir */
193 struct mutex *mtx; /* serialization for this stream */
194};
195
196void filestr_base_init(struct filestr_base *stream);
197void filestr_base_destroy(struct filestr_base *stream);
198void filestr_alloc_cache(struct filestr_base *stream);
199void filestr_free_cache(struct filestr_base *stream);
200void filestr_assign_cache(struct filestr_base *stream,
201 struct filestr_cache *cachep);
202void filestr_copy_cache(struct filestr_base *stream,
203 struct filestr_cache *cachep);
204void filestr_discard_cache(struct filestr_base *stream);
205
206/* allocates a cache buffer if needed and returns the cache pointer */
207static inline struct filestr_cache *
208filestr_get_cache(struct filestr_base *stream)
209{
210 struct filestr_cache *cachep = stream->cachep;
211
212 if (!cachep->buffer)
213 filestr_alloc_cache(stream);
214
215 return cachep;
216}
217
218static inline void filestr_lock(struct filestr_base *stream)
219{
220 mutex_lock(stream->mtx);
221}
222
223static inline void filestr_unlock(struct filestr_base *stream)
224{
225 mutex_unlock(stream->mtx);
226}
227
228/* stream lock doesn't have to be used if getting RW lock writer access */
229#define FILESTR_WRITER 0
230#define FILESTR_READER 1
231
232#define FILESTR_LOCK(type, stream) \
233 ({ if (FILESTR_##type) filestr_lock(stream); })
234
235#define FILESTR_UNLOCK(type, stream) \
236 ({ if (FILESTR_##type) filestr_unlock(stream); })
237
238#define ATTR_PREFIX (0x8000) /* out of the way of all ATTR_* bits */
239
240/* structure to return detailed information about what you opened */
241struct path_component_info
242{
243 const char *name; /* pointer to name within 'path' */
244 size_t length; /* length of component within 'path' */
245 file_size_t filesize; /* size of the opened file (0 if dir) */
246 unsigned int attr; /* attributes of this component */
247 struct file_base_info *prefixp; /* base info to check as prefix (IN) */
248 struct file_base_info parentinfo; /* parent directory info of file */
249};
250
251int open_stream_internal(const char *path, unsigned int callflags,
252 struct filestr_base *stream,
253 struct path_component_info *compinfo);
254int close_stream_internal(struct filestr_base *stream);
255int create_stream_internal(struct file_base_info *parentinfop,
256 const char *basename, size_t length,
257 unsigned int attr, unsigned int callflags,
258 struct filestr_base *stream);
259int remove_stream_internal(const char *path, struct filestr_base *stream,
260 unsigned int callflags);
261int test_stream_exists_internal(const char *path, unsigned int callflags);
262
263int open_noiso_internal(const char *path, int oflag); /* file.c */
264
265struct dirent;
266int uncached_readdir_dirent(struct filestr_base *stream,
267 struct dirscan_info *scanp,
268 struct dirent *entry);
269void uncached_rewinddir_dirent(struct dirscan_info *scanp);
270
271int uncached_readdir_internal(struct filestr_base *stream,
272 struct file_base_info *infop,
273 struct fat_direntry *fatent);
274void uncached_rewinddir_internal(struct file_base_info *infop);
275
276int test_dir_empty_internal(struct filestr_base *stream);
277
278struct dirinfo_internal
279{
280 unsigned int attr;
281 file_size_t size;
282 uint16_t wrtdate;
283 uint16_t wrttime;
284};
285
286/** Synchronization used throughout **/
287
288/* acquire the filesystem lock as READER */
289static inline void file_internal_lock_READER(void)
290{
291 extern struct mrsw_lock file_internal_mrsw;
292 mrsw_read_acquire(&file_internal_mrsw);
293}
294
295/* release the filesystem lock as READER */
296static inline void file_internal_unlock_READER(void)
297{
298 extern struct mrsw_lock file_internal_mrsw;
299 mrsw_read_release(&file_internal_mrsw);
300}
301
302/* acquire the filesystem lock as WRITER */
303static inline void file_internal_lock_WRITER(void)
304{
305 extern struct mrsw_lock file_internal_mrsw;
306 mrsw_write_acquire(&file_internal_mrsw);
307}
308
309/* release the filesystem lock as WRITER */
310static inline void file_internal_unlock_WRITER(void)
311{
312 extern struct mrsw_lock file_internal_mrsw;
313 mrsw_write_release(&file_internal_mrsw);
314}
315
316#define ERRNO 0 /* maintain errno value */
317#define RC 0 /* maintain rc value */
318
319/* NOTES: if _errno is a non-constant expression, it must set an error
320 * number and not return the ERRNO constant which will merely set
321 * errno to zero, not preserve the current value; if you must set
322 * errno to zero, set it explicitly, not in the macro
323 *
324 * if _rc is constant-expression evaluation to 'RC', then rc will
325 * NOT be altered; i.e. if you must set rc to zero, set it explicitly,
326 * not in the macro
327 */
328
329/* set errno and rc and proceed to the "file_error:" label */
330#define FILE_ERROR(_errno, _rc) \
331 ({ __builtin_constant_p(_errno) ? \
332 ({ if ((_errno) != ERRNO) errno = (_errno); }) : \
333 ({ errno = (_errno); }); \
334 __builtin_constant_p(_rc) ? \
335 ({ if ((_rc) != RC) rc = (_rc); }) : \
336 ({ rc = (_rc); }); \
337 goto file_error; })
338
339/* set errno and return a value at the point of invocation */
340#define FILE_ERROR_RETURN(_errno, _rc...) \
341 ({ __builtin_constant_p(_errno) ? \
342 ({ if ((_errno) != ERRNO) errno = (_errno); }) : \
343 ({ errno = (_errno); }); \
344 return _rc; })
345
346
347/** Misc. stuff **/
348
349/* iterate through all the volumes if volume < 0, else just the given volume */
350#define FOR_EACH_VOLUME(volume, i) \
351 for (int i = (IF_MV_VOL(volume) >= 0 ? IF_MV_VOL(volume) : 0), \
352 _end = (IF_MV_VOL(volume) >= 0 ? i : NUM_VOLUMES-1); \
353 i <= _end; i++)
354
355/* return a pointer to the static struct fat_direntry */
356static inline struct fat_direntry *get_dir_fatent(void)
357{
358 extern struct fat_direntry dir_fatent;
359 return &dir_fatent;
360}
361
362void iso_decode_d_name(char *d_name);
363
364#ifdef HAVE_DIRCACHE
365void empty_dirent(struct dirent *entry);
366void fill_dirinfo_native(struct dirinfo_native *din);
367#endif /* HAVE_DIRCACHE */
368
369void filesystem_init(void) INIT_ATTR;
370
371#endif /* _FILE_INTERNAL_H_ */
diff --git a/firmware/include/fileobj_mgr.h b/firmware/include/fileobj_mgr.h
new file mode 100644
index 0000000000..c90a59bea0
--- /dev/null
+++ b/firmware/include/fileobj_mgr.h
@@ -0,0 +1,56 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 by Michael Sevakis
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _FILEOBJ_MGR_H_
22#define _FILEOBJ_MGR_H_
23
24#include "file_internal.h"
25
26void file_binding_insert_first(struct file_base_binding *bindp);
27void file_binding_insert_last(struct file_base_binding *bindp);
28void file_binding_remove(struct file_base_binding *bindp);
29void file_binding_remove_next(struct file_base_binding *prevp,
30 struct file_base_binding *bindp);
31
32void fileobj_fileop_open(struct filestr_base *stream,
33 const struct file_base_info *srcinfop,
34 unsigned int callflags);
35void fileobj_fileop_close(struct filestr_base *stream);
36void fileobj_fileop_create(struct filestr_base *stream,
37 const struct file_base_info *srcinfop,
38 unsigned int callflags);
39void fileobj_fileop_rename(struct filestr_base *stream,
40 const struct file_base_info *oldinfop);
41void fileobj_fileop_remove(struct filestr_base *stream,
42 const struct file_base_info *oldinfop);
43void fileobj_fileop_sync(struct filestr_base *stream);
44void fileobj_fileop_truncate(struct filestr_base *stream);
45extern void ftruncate_internal_callback(struct filestr_base *stream,
46 struct filestr_base *s);
47
48file_size_t * fileobj_get_sizep(const struct filestr_base *stream);
49unsigned int fileobj_get_flags(const struct filestr_base *stream);
50void fileobj_change_flags(struct filestr_base *stream,
51 unsigned int flags, unsigned int mask);
52void fileobj_mgr_unmount(IF_MV_NONVOID(int volume));
53
54void fileobj_mgr_init(void) INIT_ATTR;
55
56#endif /* _FILEOBJ_MGR_H_ */
diff --git a/firmware/include/filesystem-native.h b/firmware/include/filesystem-native.h
new file mode 100644
index 0000000000..640e179890
--- /dev/null
+++ b/firmware/include/filesystem-native.h
@@ -0,0 +1,107 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Björn Stenberg
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _FILESYSTEM_NATIVE_H_
22#define _FILESYSTEM_NATIVE_H_
23
24#if defined(PLUGIN) || defined(CODEC)
25#define FILEFUNCTIONS_DECLARED
26#define FILEFUNCTIONS_DEFINED
27#define DIRFUNCTIONS_DECLARED
28#define DIRFUNCTIONS_DEFINED
29#endif /* PLUGIN || CODEC */
30
31#define FS_PREFIX(_x_) _x_
32#endif /* _FILESYSTEM_NATIVE_H_ */
33
34#ifdef _FILE_H_
35#ifndef _FILESYSTEM_NATIVE__FILE_H_
36#define _FILESYSTEM_NATIVE__FILE_H_
37
38#ifdef RB_FILESYSTEM_OS
39#define FILEFUNCTIONS_DEFINED
40#endif
41
42#ifndef FILEFUNCTIONS_DECLARED
43#define __OPEN_MODE_ARG
44#define __CREAT_MODE_ARG
45
46int open(const char *name, int oflag);
47int creat(const char *name);
48int close(int fildes);
49int ftruncate(int fildes, off_t length);
50int fsync(int fildes);
51off_t lseek(int fildes, off_t offset, int whence);
52ssize_t read(int fildes, void *buf, size_t nbyte);
53ssize_t write(int fildes, const void *buf, size_t nbyte);
54int remove(const char *path);
55int rename(const char *old, const char *new);
56off_t filesize(int fildes);
57int fsamefile(int fildes1, int fildes2);
58int relate(const char *path1, const char *path2);
59bool file_exists(const char *path);
60#endif /* !FILEFUNCTIONS_DECLARED */
61
62#if !defined(RB_FILESYSTEM_OS) && !defined (FILEFUNCTIONS_DEFINED)
63#define open(path, oflag, ...) open(path, oflag)
64#define creat(path, mode) creat(path)
65#endif /* FILEFUNCTIONS_DEFINED */
66
67#endif /* _FILESYSTEM_NATIVE__FILE_H_ */
68#endif /* _FILE_H_ */
69
70#ifdef _DIR_H_
71#ifndef _FILESYSTEM_NATIVE__DIR_H_
72#define _FILESYSTEM_NATIVE__DIR_H_
73
74#define DIRENT dirent
75struct dirent;
76
77struct dirinfo_native
78{
79 unsigned int attr;
80 off_t size;
81 uint16_t wrtdate;
82 uint16_t wrttime;
83};
84
85typedef struct {} DIR;
86
87#ifndef DIRFUNCTIONS_DECLARED
88#define __MKDIR_MODE_ARG
89
90#ifdef RB_FILESYSTEM_OS
91#define DIRFUNCTIONS_DEFINED
92#endif
93
94DIR * opendir(const char *dirname);
95struct dirent * readdir(DIR *dirp);
96int readdir_r(DIR *dirp, struct dirent *entry,
97 struct dirent **result);
98void rewinddir(DIR *dirp);
99int closedir(DIR *dirp);
100int mkdir(const char *path);
101int rmdir(const char *path);
102int samedir(DIR *dirp1, DIR *dirp2);
103bool dir_exists(const char *dirname);
104#endif /* !DIRFUNCTIONS_DECLARED */
105
106#endif /* _FILESYSTEM_NATIVE__DIR_H_ */
107#endif /* _DIR_H_ */
diff --git a/firmware/include/fs_attr.h b/firmware/include/fs_attr.h
new file mode 100644
index 0000000000..0e1d25e1de
--- /dev/null
+++ b/firmware/include/fs_attr.h
@@ -0,0 +1,39 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 by Kévin Ferrare
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _FS_ATTR_H_
22#define _FS_ATTR_H_
23
24#include <stdbool.h>
25
26#undef MAX_PATH /* this avoids problems when building simulator */
27#define MAX_PATH 260
28
29/* also used by fat.c so values must not change */
30#define ATTR_READ_ONLY 0x01
31#define ATTR_HIDDEN 0x02
32#define ATTR_SYSTEM 0x04
33#define ATTR_VOLUME_ID 0x08
34#define ATTR_DIRECTORY 0x10
35#define ATTR_ARCHIVE 0x20
36#define ATTR_VOLUME 0x40 /* this is a volume, not a real directory */
37#define ATTR_LINK 0x80
38
39#endif /* _FS_ATTR_H_ */
diff --git a/firmware/include/rb-loader.h b/firmware/include/rb-loader.h
index e1e756dba9..86c5026af9 100644
--- a/firmware/include/rb-loader.h
+++ b/firmware/include/rb-loader.h
@@ -18,5 +18,4 @@
18 * 18 *
19 ****************************************************************************/ 19 ****************************************************************************/
20 20
21const char *rb_strerror(int8_t errno);
22int load_firmware(unsigned char* buf, const char* firmware, int buffer_size); 21int load_firmware(unsigned char* buf, const char* firmware, int buffer_size);
diff --git a/firmware/include/rbunicode.h b/firmware/include/rbunicode.h
index 3c28b3031e..077029304d 100644
--- a/firmware/include/rbunicode.h
+++ b/firmware/include/rbunicode.h
@@ -51,7 +51,8 @@ enum codepages {
51 KSX_1001, /* Korean */ 51 KSX_1001, /* Korean */
52 BIG_5, /* Trad. Chinese */ 52 BIG_5, /* Trad. Chinese */
53 UTF_8, /* Unicode */ 53 UTF_8, /* Unicode */
54 NUM_CODEPAGES 54 NUM_CODEPAGES,
55 INIT_CODEPAGE = ISO_8859_1,
55}; 56};
56 57
57#else /* !HAVE_LCD_BITMAP, reduced support */ 58#else /* !HAVE_LCD_BITMAP, reduced support */
@@ -65,7 +66,8 @@ enum codepages {
65 WIN_1250, /* Central European */ 66 WIN_1250, /* Central European */
66 WIN_1252, /* Western European */ 67 WIN_1252, /* Western European */
67 UTF_8, /* Unicode */ 68 UTF_8, /* Unicode */
68 NUM_CODEPAGES 69 NUM_CODEPAGES,
70 INIT_CODEPAGE = ISO_8859_1,
69}; 71};
70 72
71#endif 73#endif
@@ -78,9 +80,19 @@ unsigned char* utf16BEdecode(const unsigned char *utf16, unsigned char *utf8, in
78unsigned long utf8length(const unsigned char *utf8); 80unsigned long utf8length(const unsigned char *utf8);
79const unsigned char* utf8decode(const unsigned char *utf8, unsigned short *ucs); 81const unsigned char* utf8decode(const unsigned char *utf8, unsigned short *ucs);
80void set_codepage(int cp); 82void set_codepage(int cp);
83int get_codepage(void);
81int utf8seek(const unsigned char* utf8, int offset); 84int utf8seek(const unsigned char* utf8, int offset);
82const char* get_codepage_name(int cp); 85const char* get_codepage_name(int cp);
83#if defined(APPLICATION) && defined(__linux__) 86#ifdef APPLICATION
87#if defined(__linux__)
84const char *get_current_codepage_name_linux(void); 88const char *get_current_codepage_name_linux(void);
85#endif 89#endif
90#endif /* APPLICATION */
91
92#if 0 /* not needed just now */
93void unicode_init(void);
94#else
95#define unicode_init() do {} while (0)
96#endif
97
86#endif /* _RBUNICODE_H_ */ 98#endif /* _RBUNICODE_H_ */