diff options
Diffstat (limited to 'firmware/include')
| -rw-r--r-- | firmware/include/dir.h | 91 | ||||
| -rw-r--r-- | firmware/include/dir_uncached.h | 107 | ||||
| -rw-r--r-- | firmware/include/dircache.h | 209 | ||||
| -rw-r--r-- | firmware/include/dircache_redirect.h | 198 | ||||
| -rw-r--r-- | firmware/include/disk_cache.h | 83 | ||||
| -rw-r--r-- | firmware/include/file.h | 125 | ||||
| -rw-r--r-- | firmware/include/file_internal.h | 371 | ||||
| -rw-r--r-- | firmware/include/fileobj_mgr.h | 56 | ||||
| -rw-r--r-- | firmware/include/filesystem-native.h | 107 | ||||
| -rw-r--r-- | firmware/include/fs_attr.h | 39 | ||||
| -rw-r--r-- | firmware/include/rb-loader.h | 1 | ||||
| -rw-r--r-- | firmware/include/rbunicode.h | 18 |
12 files changed, 1133 insertions, 272 deletions
diff --git a/firmware/include/dir.h b/firmware/include/dir.h index 6e8b705..f771982 100644 --- a/firmware/include/dir.h +++ b/firmware/include/dir.h @@ -18,46 +18,71 @@ * KIND, either express or implied. * ****************************************************************************/ - #ifndef _DIR_H_ #define _DIR_H_ +#include <sys/types.h> +#include <fcntl.h> +#include <time.h> #include "config.h" +#include "fs_attr.h" -#define ATTR_READ_ONLY 0x01 -#define ATTR_HIDDEN 0x02 -#define ATTR_SYSTEM 0x04 -#define ATTR_VOLUME_ID 0x08 -#define ATTR_DIRECTORY 0x10 -#define ATTR_ARCHIVE 0x20 -#define ATTR_VOLUME 0x40 /* this is a volume, not a real directory */ -#define ATTR_LINK 0x80 - -#ifdef HAVE_DIRCACHE -# include "dircache.h" -# define DIR DIR_CACHED -# define dirent dirent_cached -# define opendir opendir_cached -# define closedir closedir_cached -# define readdir readdir_cached -# define closedir closedir_cached -# define mkdir mkdir_cached -# define rmdir rmdir_cached +#if defined (APPLICATION) +#include "filesystem-app.h" +#elif defined(SIMULATOR) || defined(__PCTOOL__) +#include "../../uisimulator/common/filesystem-sim.h" #else -# include "dir_uncached.h" -# define DIR DIR_UNCACHED -# define dirent dirent_uncached -# define opendir opendir_uncached -# define closedir closedir_uncached -# define readdir readdir_uncached -# define closedir closedir_uncached -# define mkdir mkdir_uncached -# define rmdir rmdir_uncached +#include "filesystem-native.h" +#endif + +#ifndef DIRFUNCTIONS_DEFINED +#ifndef opendir +#define opendir FS_PREFIX(opendir) +#endif +#ifndef readdir +#define readdir FS_PREFIX(readdir) +#endif +#ifndef readdir_r +#define readdir_r FS_PREFIX(readdir_r) +#endif +#ifndef rewinddir +#define rewinddir FS_PREFIX(rewinddir) #endif +#ifndef closedir +#define closedir FS_PREFIX(closedir) +#endif +#ifndef mkdir +#define mkdir FS_PREFIX(mkdir) +#endif +#ifndef rmdir +#define rmdir FS_PREFIX(rmdir) +#endif +#ifndef samedir +#define samedir FS_PREFIX(samedir) +#endif +#ifndef dir_exists +#define dir_exists FS_PREFIX(dir_exists) +#endif +#endif /* !DIRFUNCTIONS_DEFINED */ +#ifndef DIRENT_DEFINED +struct DIRENT +{ + struct dirinfo_native info; /* platform extra info */ + char d_name[MAX_PATH]; /* UTF-8 name of entry (last!) */ +}; +#endif /* DIRENT_DEFINED */ -typedef DIR* (*opendir_func)(const char* name); -typedef int (*closedir_func)(DIR* dir); -typedef struct dirent* (*readdir_func)(DIR* dir); +struct dirinfo +{ + unsigned int attribute; /* attribute bits of file */ + off_t size; /* binary size of file */ + time_t mtime; /* local file time */ +}; -#endif +#ifndef DIRFUNCTIONS_DECLARED +/* TIP: set errno to zero before calling to see if anything failed */ +struct dirinfo dir_get_info(DIR *dirp, struct DIRENT *entry); +#endif /* !DIRFUNCTIONS_DECLARED */ + +#endif /* _DIR_H_ */ diff --git a/firmware/include/dir_uncached.h b/firmware/include/dir_uncached.h deleted file mode 100644 index 6443d5b..0000000 --- a/firmware/include/dir_uncached.h +++ /dev/null @@ -1,107 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id: dir.h 13741 2007-06-30 02:08:27Z jethead71 $ - * - * Copyright (C) 2002 by Björn Stenberg - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#ifndef _DIR_UNCACHED_H_ -#define _DIR_UNCACHED_H_ - -#include "config.h" - -struct dirinfo { - int attribute; - long size; - unsigned short wrtdate; - unsigned short wrttime; -}; - -#include <stdbool.h> -#include "file.h" - -#if defined(SIMULATOR) || defined(__PCTOOL__) -# define dirent_uncached sim_dirent -# define DIR_UNCACHED SIM_DIR -# define opendir_uncached sim_opendir -# define readdir_uncached sim_readdir -# define closedir_uncached sim_closedir -# define mkdir_uncached sim_mkdir -# define rmdir_uncached sim_rmdir -#elif defined(APPLICATION) -# include "rbpaths.h" -# define DIRENT_DEFINED -# define DIR_DEFINED -# define dirent_uncached dirent -# define DIR_UNCACHED DIR -# define opendir_uncached app_opendir -# define readdir_uncached app_readdir -# define closedir_uncached app_closedir -# define mkdir_uncached app_mkdir -# define rmdir_uncached app_rmdir -#endif - - -#ifndef DIRENT_DEFINED -struct dirent_uncached { - unsigned char d_name[MAX_PATH]; - struct dirinfo info; - long startcluster; -}; -#endif - -#include "fat.h" - -#ifndef DIR_DEFINED -typedef struct { -#if (CONFIG_PLATFORM & PLATFORM_NATIVE) - struct fat_dir fatdir CACHEALIGN_ATTR; - bool busy; - long startcluster; - struct dirent_uncached theent; -#ifdef HAVE_MULTIVOLUME - int volumecounter; /* running counter for faked volume entries */ -#endif -#else - /* simulator/application: */ - void *dir; /* actually a DIR* dir */ - char *name; -#endif -} DIR_UNCACHED CACHEALIGN_ATTR; -#endif - -#ifdef HAVE_HOTSWAP -char *get_volume_name(int volume); -#endif - -#ifdef HAVE_MULTIVOLUME - int strip_volume(const char*, char*); -#endif - -#ifndef DIRFUNCTIONS_DEFINED - -extern DIR_UNCACHED* opendir_uncached(const char* name); -extern int closedir_uncached(DIR_UNCACHED* dir); -extern int mkdir_uncached(const char* name); -extern int rmdir_uncached(const char* name); - -extern struct dirent_uncached* readdir_uncached(DIR_UNCACHED* dir); - -extern int release_dirs(int volume); - -#endif /* DIRFUNCTIONS_DEFINED */ - -#endif diff --git a/firmware/include/dircache.h b/firmware/include/dircache.h index 019ccf4..7e8c764 100644 --- a/firmware/include/dircache.h +++ b/firmware/include/dircache.h @@ -8,6 +8,7 @@ * $Id$ * * Copyright (C) 2005 by Miika Pekkarinen + * Copyright (C) 2014 by Michael Sevakis * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -21,84 +22,154 @@ #ifndef _DIRCACHE_H #define _DIRCACHE_H -#include "config.h" -#include "dir_uncached.h" -#include <string.h> /* size_t */ +#include "mv.h" +#include <string.h> /* size_t */ +#include <sys/types.h> /* ssize_t */ #ifdef HAVE_DIRCACHE -#define DIRCACHE_RESERVE (1024*64) -#define DIRCACHE_LIMIT (1024*1024*6) - -#define DIRCACHE_APPFLAG_TAGCACHE 0x0001 -#define DIRCACHE_APPFLAG_PLAYLIST 0x0002 - -/* Internal structures. */ -struct travel_data { - struct dircache_entry *first; - struct dircache_entry *ce; - struct dircache_entry *down_entry; -#if (CONFIG_PLATFORM & PLATFORM_HOSTED) - DIR_UNCACHED *dir, *newdir; - struct dirent_uncached *entry; -#else - struct fat_dir *dir; - struct fat_dir newdir; - struct fat_direntry entry; +/**************************************************************************** + ** Configurable values + **/ + +#if 0 +/* enable dumping code */ +#define DIRCACHE_DUMPSTER +#define DIRCACHE_DUMPSTER_BIN "/dircache_dump.bin" +#define DIRCACHE_DUMPSTER_CSV "/dircache_dump.csv" #endif - int pathpos; + +/* dircache builds won't search below this but will work down to this point + while below it the cache will just pass requests through to the storage; + the limiting factor is the scanning thread stack size, not the + implementation -- tune the two together */ +#define DIRCACHE_MAX_DEPTH 15 +#define DIRCACHE_STACK_SIZE (DEFAULT_STACK_SIZE + 0x100) + +/* memory buffer constants that control allocation */ +#define DIRCACHE_RESERVE (1024*64) /* 64 KB - new entry slack */ +#define DIRCACHE_MIN (1024*1024*1) /* 1 MB - provision min size */ +#define DIRCACHE_LIMIT (1024*1024*6) /* 6 MB - provision max size */ + +/* make it easy to change serialnumber size without modifying anything else; + 32 bits allows 21845 builds before wrapping in a 6MB cache that is filled + exclusively with entries and nothing else (32 byte entries), making that + figure pessimistic */ +typedef uint32_t dc_serial_t; + +/** + ****************************************************************************/ + +#if CONFIG_PLATFORM & PLATFORM_NATIVE +/* native dircache is lower-level than on a hosted target */ +#define DIRCACHE_NATIVE +#endif + +struct dircache_file +{ + int idx; /* this file's cache index */ + dc_serial_t serialnum; /* this file's serial number */ }; -struct dirent_cached { - struct dirinfo info; - char *d_name; - long startcluster; +enum dircache_status +{ + DIRCACHE_IDLE = 0, /* no volume is initialized */ + DIRCACHE_SCANNING = 1, /* dircache is scanning a volume */ + DIRCACHE_READY = 2, /* dircache is ready to be used */ +}; + +/** Dircache control **/ +void dircache_wait(void); +void dircache_suspend(void); +int dircache_resume(void); +int dircache_enable(void); +void dircache_disable(void); +void dircache_free_buffer(void); + +/** Volume mounting **/ +void dircache_mount(void); /* always tries building everything it can */ +void dircache_unmount(IF_MV_NONVOID(int volume)); + + +/** File API service functions **/ + +/* avoid forcing #include of file_internal.h, fat.h and dir.h */ +struct filestr_base; +struct file_base_info; +struct file_base_binding; +struct dirent; +struct dirscan_info; +struct dirinfo_native; + +int dircache_readdir_dirent(struct filestr_base *stream, + struct dirscan_info *scanp, + struct dirent *entry); +void dircache_rewinddir_dirent(struct dirscan_info *scanp); + +#ifdef DIRCACHE_NATIVE +struct fat_direntry; +int dircache_readdir_internal(struct filestr_base *stream, + struct file_base_info *infop, + struct fat_direntry *fatent); +void dircache_rewinddir_internal(struct file_base_info *info); +#endif /* DIRCACHE_NATIVE */ + + +/** Dircache live updating **/ + +void dircache_get_rootinfo(struct file_base_info *infop); +void dircache_bind_file(struct file_base_binding *bindp); +void dircache_unbind_file(struct file_base_binding *bindp); +void dircache_fileop_create(struct file_base_info *dirinfop, + struct file_base_binding *bindp, + const char *basename, + const struct dirinfo_native *dinp); +void dircache_fileop_rename(struct file_base_info *dirinfop, + struct file_base_binding *bindp, + const char *basename); +void dircache_fileop_remove(struct file_base_binding *bindp); +void dircache_fileop_sync(struct file_base_binding *infop, + const struct dirinfo_native *dinp); + + +/** Dircache paths and files **/ +ssize_t dircache_get_path(const struct dircache_file *dcfilep, char *buf, + size_t size); +int dircache_get_file(const char *path, struct dircache_file *dcfilep); + + +/** Debug screen/info stuff **/ + +struct dircache_info +{ + enum dircache_status status; /* current composite status value */ + const char *statusdesc; /* pointer to string describing 'status' */ + size_t last_size; /* cache size after last build */ + size_t size; /* total size of entries (with holes) */ + size_t sizeused; /* bytes of 'size' actually utilized */ + size_t size_limit; /* maximum possible size */ + size_t reserve; /* size of reserve area */ + size_t reserve_used; /* amount of reserve used */ + unsigned int entry_count; /* number of cache entries */ + long build_ticks; /* total time used to build cache */ }; -typedef struct { - bool busy; - struct dirent_cached theent; /* .attribute is set to -1 on init(opendir) */ - int internal_entry; /* the current entry in the directory */ - DIR_UNCACHED *regulardir; -} DIR_CACHED; +void dircache_get_info(struct dircache_info *info); +#ifdef DIRCACHE_DUMPSTER +void dircache_dump(void); +#endif /* DIRCACHE_DUMPSTER */ + -void dircache_init(void) INIT_ATTR; +/** Misc. stuff **/ +void dircache_dcfile_init(struct dircache_file *dcfilep); + +#ifdef HAVE_EEPROM_SETTINGS int dircache_load(void); int dircache_save(void); -int dircache_build(int last_size); -void* dircache_steal_buffer(size_t *size); -bool dircache_is_enabled(void); -bool dircache_is_initializing(void); -void dircache_set_appflag(long mask); -bool dircache_get_appflag(long mask); -int dircache_get_entry_count(void); -int dircache_get_cache_size(void); -int dircache_get_reserve_used(void); -int dircache_get_build_ticks(void); -void dircache_disable(void); -void dircache_suspend(void); -bool dircache_resume(void); -int dircache_get_entry_id(const char *filename); -size_t dircache_copy_path(int index, char *buf, size_t size); - -/* the next two are internal for file.c */ -long _dircache_get_entry_startcluster(int id); -struct dirinfo* _dircache_get_entry_dirinfo(int id); - -void dircache_bind(int fd, const char *path); -void dircache_update_filesize(int fd, long newsize, long startcluster); -void dircache_update_filetime(int fd); -void dircache_mkdir(const char *path); -void dircache_rmdir(const char *path); -void dircache_remove(const char *name); -void dircache_rename(const char *oldpath, const char *newpath); -void dircache_add_file(const char *path, long startcluster); - -DIR_CACHED* opendir_cached(const char* name); -struct dirent_cached* readdir_cached(DIR_CACHED* dir); -int closedir_cached(DIR_CACHED *dir); -int mkdir_cached(const char *name); -int rmdir_cached(const char* name); -#endif /* !HAVE_DIRCACHE */ +#endif /* HAVE_EEPROM_SETTINGS */ -#endif +void dircache_init(size_t last_size) INIT_ATTR; + +#endif /* HAVE_DIRCACHE */ + +#endif /* _DIRCACHE_H */ diff --git a/firmware/include/dircache_redirect.h b/firmware/include/dircache_redirect.h new file mode 100644 index 0000000..15fb4bc --- /dev/null +++ b/firmware/include/dircache_redirect.h @@ -0,0 +1,198 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2014 by Michael Sevakis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _DIRCACHE_REDIRECT_H_ + +#include "dir.h" + +/*** + ** Internal redirects that depend upon whether or not dircache is made + **/ + +/** File binding **/ + +static inline void get_rootinfo_internal(struct file_base_info *infop) +{ +#ifdef HAVE_DIRCACHE + dircache_get_rootinfo(infop); +#else + (void)infop; +#endif +} + +static inline void fileobj_bind_file(struct file_base_binding *bindp) +{ +#ifdef HAVE_DIRCACHE + dircache_bind_file(bindp); +#else + file_binding_insert_last(bindp); +#endif +} + +static inline void fileobj_unbind_file(struct file_base_binding *bindp) +{ +#ifdef HAVE_DIRCACHE + dircache_unbind_file(bindp); +#else + file_binding_remove(bindp); +#endif +} + + +/** File event handlers **/ + +static inline void fileop_onopen_internal(struct filestr_base *stream, + struct file_base_info *srcinfop, + unsigned int callflags) +{ + fileobj_fileop_open(stream, srcinfop, callflags); +} + +static inline void fileop_onclose_internal(struct filestr_base *stream) +{ + fileobj_fileop_close(stream); +} + +static inline void fileop_oncreate_internal(struct filestr_base *stream, + struct file_base_info *srcinfop, + unsigned int callflags, + struct file_base_info *dirinfop, + const char *basename) +{ +#ifdef HAVE_DIRCACHE + dircache_dcfile_init(&srcinfop->dcfile); +#endif + fileobj_fileop_create(stream, srcinfop, callflags); +#ifdef HAVE_DIRCACHE + struct dirinfo_native din; + fill_dirinfo_native(&din); + dircache_fileop_create(dirinfop, stream->bindp, basename, &din); +#endif + (void)dirinfop; (void)basename; +} + +static inline void fileop_onremove_internal(struct filestr_base *stream, + struct file_base_info *oldinfop) +{ + fileobj_fileop_remove(stream, oldinfop); +#ifdef HAVE_DIRCACHE + dircache_fileop_remove(stream->bindp); +#endif +} + +static inline void fileop_onrename_internal(struct filestr_base *stream, + struct file_base_info *oldinfop, + struct file_base_info *dirinfop, + const char *basename) +{ + fileobj_fileop_rename(stream, oldinfop); +#ifdef HAVE_DIRCACHE + dircache_fileop_rename(dirinfop, stream->bindp, basename); +#endif + (void)dirinfop; (void)basename; +} + +static inline void fileop_onsync_internal(struct filestr_base *stream) +{ + fileobj_fileop_sync(stream); +#ifdef HAVE_DIRCACHE + struct dirinfo_native din; + fill_dirinfo_native(&din); + dircache_fileop_sync(stream->bindp, &din); +#endif +} + +static inline void fileop_ontruncate_internal(struct filestr_base *stream) +{ + fileobj_fileop_truncate(stream); +} + +static inline void volume_onmount_internal(IF_MV_NONVOID(int volume)) +{ +#ifdef HAVE_DIRCACHE + dircache_mount(); +#endif + IF_MV( (void)volume; ) +} + +static inline void volume_onunmount_internal(IF_MV_NONVOID(int volume)) +{ + fileobj_mgr_unmount(IF_MV(volume)); +#ifdef HAVE_DIRCACHE + dircache_unmount(IF_MV(volume)); +#endif +} + + +/** Directory reading **/ + +static inline int readdir_dirent(struct filestr_base *stream, + struct dirscan_info *scanp, + struct dirent *entry) +{ +#ifdef HAVE_DIRCACHE + return dircache_readdir_dirent(stream, scanp, entry); +#else + return uncached_readdir_dirent(stream, scanp, entry); +#endif +} + +static inline void rewinddir_dirent(struct dirscan_info *scanp) +{ +#ifdef HAVE_DIRCACHE + dircache_rewinddir_dirent(scanp); +#else + uncached_rewinddir_dirent(scanp); +#endif +} + +static inline int readdir_internal(struct filestr_base *stream, + struct file_base_info *infop, + struct fat_direntry *fatent) +{ +#ifdef HAVE_DIRCACHE + return dircache_readdir_internal(stream, infop, fatent); +#else + return uncached_readdir_internal(stream, infop, fatent); +#endif +} + +static inline void rewinddir_internal(struct file_base_info *infop) +{ +#ifdef HAVE_DIRCACHE + dircache_rewinddir_internal(infop); +#else + uncached_rewinddir_internal(infop); +#endif +} + + +/** Misc. stuff **/ + +static inline struct fat_direntry *get_dir_fatent_dircache(void) +{ +#ifdef HAVE_DIRCACHE + return get_dir_fatent(); +#else + return NULL; +#endif +} + +#endif /* _DIRCACHE_REDIRECT_H_ */ diff --git a/firmware/include/disk_cache.h b/firmware/include/disk_cache.h new file mode 100644 index 0000000..725b377 --- /dev/null +++ b/firmware/include/disk_cache.h @@ -0,0 +1,83 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2014 by Michael Sevakis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef DISK_CACHE_H +#define DISK_CACHE_H + +/* This needs enough for all file handles to have a buffer in the worst case + * plus at least one reserved exclusively for the cache client and a couple + * for other file system code. The buffers are put to use by the cache if not + * taken for another purpose (meaning nothing is wasted sitting fallow). + * + * One map per volume is maintained in order to avoid collisions between + * volumes that would slow cache probing. DC_MAP_NUM_ENTRIES is the number + * for each map per volume. The buffers themselves are shared. + */ +#if MEMORYSIZE < 8 +#define DC_NUM_ENTRIES 32 +#define DC_MAP_NUM_ENTRIES 128 +#elif MEMORYSIZE <= 32 +#define DC_NUM_ENTRIES 48 +#define DC_MAP_NUM_ENTRIES 128 +#else /* MEMORYSIZE > 32 */ +#define DC_NUM_ENTRIES 64 +#define DC_MAP_NUM_ENTRIES 256 +#endif /* MEMORYSIZE */ + +/* this _could_ be larger than a sector if that would ever be useful */ +#define DC_CACHE_BUFSIZE SECTOR_SIZE + +#include "mutex.h" +#include "mv.h" + +static inline void dc_lock_cache(void) +{ + extern struct mutex disk_cache_mutex; + mutex_lock(&disk_cache_mutex); +} + +static inline void dc_unlock_cache(void) +{ + extern struct mutex disk_cache_mutex; + mutex_unlock(&disk_cache_mutex); +} + +void * dc_cache_probe(IF_MV(int volume,) unsigned long secnum, + unsigned int *flags); +void dc_dirty_buf(void *buf); +void dc_discard_buf(void *buf); +void dc_commit_all(IF_MV_NONVOID(int volume)); +void dc_discard_all(IF_MV_NONVOID(int volume)); + +void dc_init(void) INIT_ATTR; + +/* in addition to filling, writeback is implemented by the client */ +extern void dc_writeback_callback(IF_MV(int volume, ) unsigned long sector, + void *buf); + + +/** These synchronize and can be called by anyone **/ + +/* expropriate a buffer from the cache of DC_CACHE_BUFSIZE bytes */ +void * dc_get_buffer(void); +/* return buffer to the cache by buffer */ +void dc_release_buffer(void *buf); + +#endif /* DISK_CACHE_H */ diff --git a/firmware/include/file.h b/firmware/include/file.h index 7793086..8e5bace 100644 --- a/firmware/include/file.h +++ b/firmware/include/file.h @@ -18,81 +18,88 @@ * KIND, either express or implied. * ****************************************************************************/ - #ifndef _FILE_H_ #define _FILE_H_ #include <sys/types.h> -#include "config.h" -#include "gcc_extensions.h" +#include <stdbool.h> #include <fcntl.h> #ifdef WIN32 /* this has SEEK_SET et al */ #include <stdio.h> #endif - +#include "config.h" +#include "gcc_extensions.h" #undef MAX_PATH /* this avoids problems when building simulator */ #define MAX_PATH 260 -#define MAX_OPEN_FILES 11 -#if !defined(PLUGIN) && !defined(CODEC) -#if defined(APPLICATION) && !defined(__PCTOOL__) -#include "rbpaths.h" -# define open(x, ...) app_open(x, __VA_ARGS__) -# define creat(x,m) app_creat(x, m) -# define remove(x) app_remove(x) -# define rename(x,y) app_rename(x,y) -# define readlink(x,y,z) app_readlink(x,y,z) -# if (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA)) -/* SDL overrides a few more */ -# define read(x,y,z) sim_read(x,y,z) -# define write(x,y,z) sim_write(x,y,z) -# endif -#elif defined(SIMULATOR) || defined(DBTOOL) -# define open(x, ...) sim_open(x, __VA_ARGS__) -# define creat(x,m) sim_creat(x,m) -# define remove(x) sim_remove(x) -# define rename(x,y) sim_rename(x,y) -# define fsync(x) sim_fsync(x) -# define ftruncate(x,y) sim_ftruncate(x,y) -# define lseek(x,y,z) sim_lseek(x,y,z) -# define read(x,y,z) sim_read(x,y,z) -# define write(x,y,z) sim_write(x,y,z) -# define close(x) sim_close(x) -/* readlink() not used in the sim yet */ -extern int sim_open(const char *name, int o, ...); -extern int sim_creat(const char *name, mode_t mode); -#endif +enum relate_result +{ + /* < 0 == failure */ + RELATE_DIFFERENT = 0, /* the two paths are different objects */ + RELATE_SAME, /* the two paths are the same object */ + RELATE_PREFIX, /* the path2 contains path1 as a prefix */ +}; -typedef int (*open_func)(const char* pathname, int flags, ...); -typedef ssize_t (*read_func)(int fd, void *buf, size_t count); -typedef int (*creat_func)(const char *pathname, mode_t mode); -typedef ssize_t (*write_func)(int fd, const void *buf, size_t count); -typedef void (*qsort_func)(void *base, size_t nmemb, size_t size, - int(*_compar)(const void *, const void *)); +#if defined(APPLICATION) +#include "filesystem-app.h" +#elif defined(SIMULATOR) || defined(__PCTOOL__) +#include "../../uisimulator/common/filesystem-sim.h" +#else +#include "filesystem-native.h" +#endif -extern int file_open(const char* pathname, int flags); -extern int close(int fd); -extern int fsync(int fd); -extern ssize_t read(int fd, void *buf, size_t count); -extern off_t lseek(int fildes, off_t offset, int whence); -extern int file_creat(const char *pathname); -#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) && !defined(__PCTOOL__)) || \ - defined(TEST_FAT) -#define creat(x, y) file_creat(x) +#ifndef FILEFUNCTIONS_DECLARED +int fdprintf(int fildes, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3); +#endif /* FILEFUNCTIONS_DECLARED */ -#if !defined(CODEC) && !defined(PLUGIN) -#define open(x, y, ...) file_open(x,y) +#ifndef FILEFUNCTIONS_DEFINED +#ifndef open +#define open FS_PREFIX(open) #endif +#ifndef creat +#define creat FS_PREFIX(creat) #endif - -extern ssize_t write(int fd, const void *buf, size_t count); -extern int remove(const char* pathname); -extern int rename(const char* path, const char* newname); -extern int ftruncate(int fd, off_t length); -extern off_t filesize(int fd); -extern int release_files(int volume); -int fdprintf (int fd, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3); -#endif /* !CODEC && !PLUGIN */ +#ifndef close +#define close FS_PREFIX(close) +#endif +#ifndef ftruncate +#define ftruncate FS_PREFIX(ftruncate) +#endif +#ifndef fsync +#define fsync FS_PREFIX(fsync) #endif +#ifndef lseek +#define lseek FS_PREFIX(lseek) +#endif +#ifndef read +#define read FS_PREFIX(read) +#endif +#ifndef write +#define write FS_PREFIX(write) +#endif +#ifndef remove +#define remove FS_PREFIX(remove) +#endif +#ifndef rename +#define rename FS_PREFIX(rename) +#endif +#ifndef filesize +#define filesize FS_PREFIX(filesize) +#endif +#ifndef fsamefile +#define fsamefile FS_PREFIX(fsamefile) +#endif +#ifndef file_exists +#define file_exists FS_PREFIX(file_exists) +#endif +#ifndef relate +#define relate FS_PREFIX(relate) +#endif +#ifndef readlink +#define readlink FS_PREFIX(readlink) +#endif +#endif /* FILEFUNCTIONS_DEFINED */ + +#endif /* _FILE_H_ */ diff --git a/firmware/include/file_internal.h b/firmware/include/file_internal.h new file mode 100644 index 0000000..d1bb674 --- /dev/null +++ b/firmware/include/file_internal.h @@ -0,0 +1,371 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2014 by Michael Sevakis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _FILE_INTERNAL_H_ +#define _FILE_INTERNAL_H_ + +#include <sys/types.h> +#include <stdlib.h> +#include "mv.h" +#include "linked_list.h" +#include "mutex.h" +#include "mrsw_lock.h" +#include "fs_attr.h" +#include "fat.h" +#ifdef HAVE_DIRCACHE +#include "dircache.h" +#endif + +/** Tuneable parameters **/ + +/* limits for number of open descriptors - if you increase these values, make + certain that the disk cache has enough available buffers */ +#define MAX_OPEN_FILES 11 +#define MAX_OPEN_DIRS 12 +#define MAX_OPEN_HANDLES (MAX_OPEN_FILES+MAX_OPEN_DIRS) + +/* internal functions open streams as well; make sure they don't fail if all + user descs are busy; this needs to be at least the greatest quantity needed + at once by all internal functions */ +#ifdef HAVE_DIRCACHE +#define AUX_FILEOBJS 3 +#else +#define AUX_FILEOBJS 2 +#endif + +/* number of components statically allocated to handle the vast majority + of path depths; should maybe be tuned for >= 90th percentile but for now, + imma just guessing based on something like: + root + 'Music' + 'Artist' + 'Album' + 'Disc N' + filename */ +#define STATIC_PATHCOMP_NUM 6 + +#define MAX_NAME 255 + +/* unsigned value that will also hold the off_t range we need without + overflow */ +#define file_size_t uint32_t + +#ifdef __USE_FILE_OFFSET64 +/* if we want, we can deal with files up to 2^32-1 bytes-- the full FAT16/32 + range */ +#define FILE_SIZE_MAX (0xffffffffu) +#else +/* file contents and size will be preserved by the APIs so long as ftruncate() + isn't used; bytes passed 2^31-1 will not accessible nor will writes succeed + that would extend the file beyond the max for a 32-bit off_t */ +#define FILE_SIZE_MAX (0x7fffffffu) +#endif + +/* if file is "large(ish)", then get rid of the contents now rather than + lazily when the file is synced or closed in order to free-up space */ +#define O_TRUNC_THRESH 65536 + +/* default attributes when creating new files and directories */ +#define ATTR_NEW_FILE (ATTR_ARCHIVE) +#define ATTR_NEW_DIRECTORY (ATTR_DIRECTORY) + +#define ATTR_MOUNT_POINT (ATTR_VOLUME | ATTR_DIRECTORY) + +/** File sector cache **/ + +enum filestr_cache_flags +{ + FSC_DIRTY = 0x1, /* buffer is dirty (needs writeback) */ + FSC_NEW = 0x2, /* buffer is new (never yet written) */ +}; + +struct filestr_cache +{ + uint8_t *buffer; /* buffer to hold sector */ + unsigned long sector; /* file sector that is in buffer */ + unsigned int flags; /* FSC_* bits */ +}; + +void file_cache_init(struct filestr_cache *cachep); +void file_cache_reset(struct filestr_cache *cachep); +void file_cache_alloc(struct filestr_cache *cachep); +void file_cache_free(struct filestr_cache *cachep); + + +/** Common bitflags used throughout **/ + +/* bitflags used by open files and descriptors */ +enum fildes_and_obj_flags +{ + /* used in descriptor and common */ + FDO_BUSY = 0x0001, /* descriptor/object is in use */ + /* only used in individual stream descriptor */ + FD_WRITE = 0x0002, /* descriptor has write mode */ + FD_WRONLY = 0x0004, /* descriptor is write mode only */ + FD_APPEND = 0x0008, /* descriptor is append mode */ + /* only used as common flags */ + FO_DIRECTORY = 0x0010, /* fileobj is a directory */ + FO_TRUNC = 0x0020, /* fileobj is opened to be truncated */ + FO_REMOVED = 0x0040, /* fileobj was deleted while open */ + FO_SINGLE = 0x0080, /* fileobj has only one stream open */ + FDO_MASK = 0x00ff, + /* bitflags that instruct various 'open' functions how to behave */ + FF_FILE = 0x0000, /* expect file; accept file only */ + FF_DIR = 0x0100, /* expect dir; accept dir only */ + FF_ANYTYPE = 0x0200, /* succeed if either file or dir */ + FF_TYPEMASK = 0x0300, /* mask of typeflags */ + FF_CREAT = 0x0400, /* create if file doesn't exist */ + FF_EXCL = 0x0800, /* fail if creating and file exists */ + FF_CHECKPREFIX = 0x1000, /* detect if file is prefix of path */ + FF_NOISO = 0x2000, /* do not decode ISO filenames to UTF-8 */ + FF_MASK = 0x3f00, + /* special values used in isolation */ + FV_NONEXIST = 0x8000, /* closed but not freed (unmounted) */ + FV_OPENSYSROOT = 0xc001, /* open sysroot, volume 0 not mounted */ +}; + + +/** Common data structures used throughout **/ + +/* basic file information about its location */ +struct file_base_info +{ + union { +#ifdef HAVE_MULTIVOLUME + int volume; /* file's volume (overlaps fatfile.volume) */ +#endif +#if CONFIG_PLATFORM & PLATFORM_NATIVE + struct fat_file fatfile; /* FS driver file info */ +#endif + }; +#ifdef HAVE_DIRCACHE + struct dircache_file dcfile; /* dircache file info */ +#endif +}; + +#define BASEINFO_VOL(infop) \ + IF_MV_VOL((infop)->volume) + +/* open files binding item */ +struct file_base_binding +{ + struct ll_node node; /* list item node (first!) */ + struct file_base_info info; /* basic file info */ +}; + +#define BASEBINDING_VOL(bindp) \ + BASEINFO_VOL(&(bindp)->info) + +/* directory scanning position info */ +struct dirscan_info +{ +#if CONFIG_PLATFORM & PLATFORM_NATIVE + struct fat_dirscan_info fatscan; /* FS driver scan info */ +#endif +#ifdef HAVE_DIRCACHE + struct dircache_file dcscan; /* dircache scan info */ +#endif +}; + +/* describes the file as an open stream */ +struct filestr_base +{ + struct ll_node node; /* list item node (first!) */ + uint16_t flags; /* FD_* bits of this stream */ + uint16_t unused; /* not used */ + struct filestr_cache cache; /* stream-local cache */ + struct filestr_cache *cachep; /* the cache in use (local or shared) */ + struct file_base_info *infop; /* base file information */ + struct fat_filestr fatstr; /* FS driver information */ + struct file_base_binding *bindp; /* common binding for file/dir */ + struct mutex *mtx; /* serialization for this stream */ +}; + +void filestr_base_init(struct filestr_base *stream); +void filestr_base_destroy(struct filestr_base *stream); +void filestr_alloc_cache(struct filestr_base *stream); +void filestr_free_cache(struct filestr_base *stream); +void filestr_assign_cache(struct filestr_base *stream, + struct filestr_cache *cachep); +void filestr_copy_cache(struct filestr_base *stream, + struct filestr_cache *cachep); +void filestr_discard_cache(struct filestr_base *stream); + +/* allocates a cache buffer if needed and returns the cache pointer */ +static inline struct filestr_cache * +filestr_get_cache(struct filestr_base *stream) +{ + struct filestr_cache *cachep = stream->cachep; + + if (!cachep->buffer) + filestr_alloc_cache(stream); + + return cachep; +} + +static inline void filestr_lock(struct filestr_base *stream) +{ + mutex_lock(stream->mtx); +} + +static inline void filestr_unlock(struct filestr_base *stream) +{ + mutex_unlock(stream->mtx); +} + +/* stream lock doesn't have to be used if getting RW lock writer access */ +#define FILESTR_WRITER 0 +#define FILESTR_READER 1 + +#define FILESTR_LOCK(type, stream) \ + ({ if (FILESTR_##type) filestr_lock(stream); }) + +#define FILESTR_UNLOCK(type, stream) \ + ({ if (FILESTR_##type) filestr_unlock(stream); }) + +#define ATTR_PREFIX (0x8000) /* out of the way of all ATTR_* bits */ + +/* structure to return detailed information about what you opened */ +struct path_component_info +{ + const char *name; /* pointer to name within 'path' */ + size_t length; /* length of component within 'path' */ + file_size_t filesize; /* size of the opened file (0 if dir) */ + unsigned int attr; /* attributes of this component */ + struct file_base_info *prefixp; /* base info to check as prefix (IN) */ + struct file_base_info parentinfo; /* parent directory info of file */ +}; + +int open_stream_internal(const char *path, unsigned int callflags, + struct filestr_base *stream, + struct path_component_info *compinfo); +int close_stream_internal(struct filestr_base *stream); +int create_stream_internal(struct file_base_info *parentinfop, + const char *basename, size_t length, + unsigned int attr, unsigned int callflags, + struct filestr_base *stream); +int remove_stream_internal(const char *path, struct filestr_base *stream, + unsigned int callflags); +int test_stream_exists_internal(const char *path, unsigned int callflags); + +int open_noiso_internal(const char *path, int oflag); /* file.c */ + +struct dirent; +int uncached_readdir_dirent(struct filestr_base *stream, + struct dirscan_info *scanp, + struct dirent *entry); +void uncached_rewinddir_dirent(struct dirscan_info *scanp); + +int uncached_readdir_internal(struct filestr_base *stream, + struct file_base_info *infop, + struct fat_direntry *fatent); +void uncached_rewinddir_internal(struct file_base_info *infop); + +int test_dir_empty_internal(struct filestr_base *stream); + +struct dirinfo_internal +{ + unsigned int attr; + file_size_t size; + uint16_t wrtdate; + uint16_t wrttime; +}; + +/** Synchronization used throughout **/ + +/* acquire the filesystem lock as READER */ +static inline void file_internal_lock_READER(void) +{ + extern struct mrsw_lock file_internal_mrsw; + mrsw_read_acquire(&file_internal_mrsw); +} + +/* release the filesystem lock as READER */ +static inline void file_internal_unlock_READER(void) +{ + extern struct mrsw_lock file_internal_mrsw; + mrsw_read_release(&file_internal_mrsw); +} + +/* acquire the filesystem lock as WRITER */ +static inline void file_internal_lock_WRITER(void) +{ + extern struct mrsw_lock file_internal_mrsw; + mrsw_write_acquire(&file_internal_mrsw); +} + +/* release the filesystem lock as WRITER */ +static inline void file_internal_unlock_WRITER(void) +{ + extern struct mrsw_lock file_internal_mrsw; + mrsw_write_release(&file_internal_mrsw); +} + +#define ERRNO 0 /* maintain errno value */ +#define RC 0 /* maintain rc value */ + +/* NOTES: if _errno is a non-constant expression, it must set an error + * number and not return the ERRNO constant which will merely set + * errno to zero, not preserve the current value; if you must set + * errno to zero, set it explicitly, not in the macro + * + * if _rc is constant-expression evaluation to 'RC', then rc will + * NOT be altered; i.e. if you must set rc to zero, set it explicitly, + * not in the macro + */ + +/* set errno and rc and proceed to the "file_error:" label */ +#define FILE_ERROR(_errno, _rc) \ + ({ __builtin_constant_p(_errno) ? \ + ({ if ((_errno) != ERRNO) errno = (_errno); }) : \ + ({ errno = (_errno); }); \ + __builtin_constant_p(_rc) ? \ + ({ if ((_rc) != RC) rc = (_rc); }) : \ + ({ rc = (_rc); }); \ + goto file_error; }) + +/* set errno and return a value at the point of invocation */ +#define FILE_ERROR_RETURN(_errno, _rc...) \ + ({ __builtin_constant_p(_errno) ? \ + ({ if ((_errno) != ERRNO) errno = (_errno); }) : \ + ({ errno = (_errno); }); \ + return _rc; }) + + +/** Misc. stuff **/ + +/* iterate through all the volumes if volume < 0, else just the given volume */ +#define FOR_EACH_VOLUME(volume, i) \ + for (int i = (IF_MV_VOL(volume) >= 0 ? IF_MV_VOL(volume) : 0), \ + _end = (IF_MV_VOL(volume) >= 0 ? i : NUM_VOLUMES-1); \ + i <= _end; i++) + +/* return a pointer to the static struct fat_direntry */ +static inline struct fat_direntry *get_dir_fatent(void) +{ + extern struct fat_direntry dir_fatent; + return &dir_fatent; +} + +void iso_decode_d_name(char *d_name); + +#ifdef HAVE_DIRCACHE +void empty_dirent(struct dirent *entry); +void fill_dirinfo_native(struct dirinfo_native *din); +#endif /* HAVE_DIRCACHE */ + +void filesystem_init(void) INIT_ATTR; + +#endif /* _FILE_INTERNAL_H_ */ diff --git a/firmware/include/fileobj_mgr.h b/firmware/include/fileobj_mgr.h new file mode 100644 index 0000000..c90a59b --- /dev/null +++ b/firmware/include/fileobj_mgr.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2014 by Michael Sevakis + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _FILEOBJ_MGR_H_ +#define _FILEOBJ_MGR_H_ + +#include "file_internal.h" + +void file_binding_insert_first(struct file_base_binding *bindp); +void file_binding_insert_last(struct file_base_binding *bindp); +void file_binding_remove(struct file_base_binding *bindp); +void file_binding_remove_next(struct file_base_binding *prevp, + struct file_base_binding *bindp); + +void fileobj_fileop_open(struct filestr_base *stream, + const struct file_base_info *srcinfop, + unsigned int callflags); +void fileobj_fileop_close(struct filestr_base *stream); +void fileobj_fileop_create(struct filestr_base *stream, + const struct file_base_info *srcinfop, + unsigned int callflags); +void fileobj_fileop_rename(struct filestr_base *stream, + const struct file_base_info *oldinfop); +void fileobj_fileop_remove(struct filestr_base *stream, + const struct file_base_info *oldinfop); +void fileobj_fileop_sync(struct filestr_base *stream); +void fileobj_fileop_truncate(struct filestr_base *stream); +extern void ftruncate_internal_callback(struct filestr_base *stream, + struct filestr_base *s); + +file_size_t * fileobj_get_sizep(const struct filestr_base *stream); +unsigned int fileobj_get_flags(const struct filestr_base *stream); +void fileobj_change_flags(struct filestr_base *stream, + unsigned int flags, unsigned int mask); +void fileobj_mgr_unmount(IF_MV_NONVOID(int volume)); + +void fileobj_mgr_init(void) INIT_ATTR; + +#endif /* _FILEOBJ_MGR_H_ */ diff --git a/firmware/include/filesystem-native.h b/firmware/include/filesystem-native.h new file mode 100644 index 0000000..640e179 --- /dev/null +++ b/firmware/include/filesystem-native.h @@ -0,0 +1,107 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Björn Stenberg + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _FILESYSTEM_NATIVE_H_ +#define _FILESYSTEM_NATIVE_H_ + +#if defined(PLUGIN) || defined(CODEC) +#define FILEFUNCTIONS_DECLARED +#define FILEFUNCTIONS_DEFINED +#define DIRFUNCTIONS_DECLARED +#define DIRFUNCTIONS_DEFINED +#endif /* PLUGIN || CODEC */ + +#define FS_PREFIX(_x_) _x_ +#endif /* _FILESYSTEM_NATIVE_H_ */ + +#ifdef _FILE_H_ +#ifndef _FILESYSTEM_NATIVE__FILE_H_ +#define _FILESYSTEM_NATIVE__FILE_H_ + +#ifdef RB_FILESYSTEM_OS +#define FILEFUNCTIONS_DEFINED +#endif + +#ifndef FILEFUNCTIONS_DECLARED +#define __OPEN_MODE_ARG +#define __CREAT_MODE_ARG + +int open(const char *name, int oflag); +int creat(const char *name); +int close(int fildes); +int ftruncate(int fildes, off_t length); +int fsync(int fildes); +off_t lseek(int fildes, off_t offset, int whence); +ssize_t read(int fildes, void *buf, size_t nbyte); +ssize_t write(int fildes, const void *buf, size_t nbyte); +int remove(const char *path); +int rename(const char *old, const char *new); +off_t filesize(int fildes); +int fsamefile(int fildes1, int fildes2); +int relate(const char *path1, const char *path2); +bool file_exists(const char *path); +#endif /* !FILEFUNCTIONS_DECLARED */ + +#if !defined(RB_FILESYSTEM_OS) && !defined (FILEFUNCTIONS_DEFINED) +#define open(path, oflag, ...) open(path, oflag) +#define creat(path, mode) creat(path) +#endif /* FILEFUNCTIONS_DEFINED */ + +#endif /* _FILESYSTEM_NATIVE__FILE_H_ */ +#endif /* _FILE_H_ */ + +#ifdef _DIR_H_ +#ifndef _FILESYSTEM_NATIVE__DIR_H_ +#define _FILESYSTEM_NATIVE__DIR_H_ + +#define DIRENT dirent +struct dirent; + +struct dirinfo_native +{ + unsigned int attr; + off_t size; + uint16_t wrtdate; + uint16_t wrttime; +}; + +typedef struct {} DIR; + +#ifndef DIRFUNCTIONS_DECLARED +#define __MKDIR_MODE_ARG + +#ifdef RB_FILESYSTEM_OS +#define DIRFUNCTIONS_DEFINED +#endif + +DIR * opendir(const char *dirname); +struct dirent * readdir(DIR *dirp); +int readdir_r(DIR *dirp, struct dirent *entry, + struct dirent **result); +void rewinddir(DIR *dirp); +int closedir(DIR *dirp); +int mkdir(const char *path); +int rmdir(const char *path); +int samedir(DIR *dirp1, DIR *dirp2); +bool dir_exists(const char *dirname); +#endif /* !DIRFUNCTIONS_DECLARED */ + +#endif /* _FILESYSTEM_NATIVE__DIR_H_ */ +#endif /* _DIR_H_ */ diff --git a/firmware/include/fs_attr.h b/firmware/include/fs_attr.h new file mode 100644 index 0000000..0e1d25e --- /dev/null +++ b/firmware/include/fs_attr.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Kévin Ferrare + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef _FS_ATTR_H_ +#define _FS_ATTR_H_ + +#include <stdbool.h> + +#undef MAX_PATH /* this avoids problems when building simulator */ +#define MAX_PATH 260 + +/* also used by fat.c so values must not change */ +#define ATTR_READ_ONLY 0x01 +#define ATTR_HIDDEN 0x02 +#define ATTR_SYSTEM 0x04 +#define ATTR_VOLUME_ID 0x08 +#define ATTR_DIRECTORY 0x10 +#define ATTR_ARCHIVE 0x20 +#define ATTR_VOLUME 0x40 /* this is a volume, not a real directory */ +#define ATTR_LINK 0x80 + +#endif /* _FS_ATTR_H_ */ diff --git a/firmware/include/rb-loader.h b/firmware/include/rb-loader.h index e1e756d..86c5026 100644 --- a/firmware/include/rb-loader.h +++ b/firmware/include/rb-loader.h @@ -18,5 +18,4 @@ * ****************************************************************************/ -const char *rb_strerror(int8_t errno); int load_firmware(unsigned char* buf, const char* firmware, int buffer_size); diff --git a/firmware/include/rbunicode.h b/firmware/include/rbunicode.h index 3c28b30..0770293 100644 --- a/firmware/include/rbunicode.h +++ b/firmware/include/rbunicode.h @@ -51,7 +51,8 @@ enum codepages { KSX_1001, /* Korean */ BIG_5, /* Trad. Chinese */ UTF_8, /* Unicode */ - NUM_CODEPAGES + NUM_CODEPAGES, + INIT_CODEPAGE = ISO_8859_1, }; #else /* !HAVE_LCD_BITMAP, reduced support */ @@ -65,7 +66,8 @@ enum codepages { WIN_1250, /* Central European */ WIN_1252, /* Western European */ UTF_8, /* Unicode */ - NUM_CODEPAGES + NUM_CODEPAGES, + INIT_CODEPAGE = ISO_8859_1, }; #endif @@ -78,9 +80,19 @@ unsigned char* utf16BEdecode(const unsigned char *utf16, unsigned char *utf8, in unsigned long utf8length(const unsigned char *utf8); const unsigned char* utf8decode(const unsigned char *utf8, unsigned short *ucs); void set_codepage(int cp); +int get_codepage(void); int utf8seek(const unsigned char* utf8, int offset); const char* get_codepage_name(int cp); -#if defined(APPLICATION) && defined(__linux__) +#ifdef APPLICATION +#if defined(__linux__) const char *get_current_codepage_name_linux(void); #endif +#endif /* APPLICATION */ + +#if 0 /* not needed just now */ +void unicode_init(void); +#else +#define unicode_init() do {} while (0) +#endif + #endif /* _RBUNICODE_H_ */ |