From 4bd870360af595a3f90b9ccc5a09d1414fd654e9 Mon Sep 17 00:00:00 2001 From: Björn Stenberg Date: Tue, 7 May 2002 16:01:53 +0000 Subject: Added open/close/read. read() only works on whole sectors right now. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@498 a1c6a512-1295-4272-9138-f99709370657 --- firmware/common/file.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 firmware/common/file.c (limited to 'firmware/common/file.c') diff --git a/firmware/common/file.c b/firmware/common/file.c new file mode 100644 index 0000000000..86e1099918 --- /dev/null +++ b/firmware/common/file.c @@ -0,0 +1,170 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Björn Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include "file.h" +#include "fat.h" +#include "types.h" +#include "dir.h" +#include "debug.h" + +#define MAX_OPEN_FILES 4 + +struct filedesc { + unsigned char sector[SECTOR_SIZE]; + int offset; + struct fat_file fatfile; + bool busy; +}; + +static struct filedesc openfiles[MAX_OPEN_FILES]; + +int open(char* pathname, int flags) +{ + DIR* dir; + struct dirent* entry; + int fd; + char* name; + int namelen; + + if ( pathname[0] != '/' ) { + DEBUGF("'%s' is not an absolute path.\n",pathname); + DEBUGF("Only absolute pathnames supported at the moment\n"); + return -1; + } + + /* find a free file descriptor */ + for ( fd=0; fdd_name, namelen) ) { + fat_open(entry->startcluster, &(openfiles[fd].fatfile)); + break; + } + else { + DEBUGF("entry: %s\n",entry->d_name); + } + } + closedir(dir); + if ( !entry ) { + DEBUGF("Couldn't find %s in %s\n",name,pathname); + /* fixme: we need to use proper error codes */ + return -1; + } + + openfiles[fd].offset = 0; + openfiles[fd].busy = TRUE; + return fd; +} + +int close(int fd) +{ + openfiles[fd].busy = FALSE; + return 0; +} + +int read(int fd, void* buf, int count) +{ + int sectors; + int nread=0; + + /* are we in the middle of a cached sector? */ + if ( openfiles[fd].offset ) { + if ( count > (SECTOR_SIZE - openfiles[fd].offset) ) { + memcpy( buf, openfiles[fd].sector, + SECTOR_SIZE - openfiles[fd].offset ); + openfiles[fd].offset = 0; + nread = SECTOR_SIZE - openfiles[fd].offset; + count -= nread; + } + else { + memcpy( buf, openfiles[fd].sector, count ); + openfiles[fd].offset += count; + nread = count; + count = 0; + } + } + + /* read whole sectors right into the supplied buffer */ + sectors = count / SECTOR_SIZE; + if ( sectors ) { + if ( fat_read(&(openfiles[fd].fatfile), sectors, buf+nread ) < 0 ) { + DEBUGF("Failed reading %d sectors\n",sectors); + return -1; + } + nread += sectors * SECTOR_SIZE; + count -= sectors * SECTOR_SIZE; + openfiles[fd].offset = 0; + } + + /* trailing odd bytes? */ + if ( count ) { + /* do we already have the sector cached? */ + if ( count < (SECTOR_SIZE - openfiles[fd].offset) ) { + memcpy( buf + nread, openfiles[fd].sector, count ); + openfiles[fd].offset += count; + nread += count; + count = 0; + } + else { + /* cache one sector and copy the trailing bytes */ + if ( fat_read(&(openfiles[fd].fatfile), 1, + &(openfiles[fd].sector)) < 0 ) { + DEBUGF("Failed reading odd sector\n"); + return -1; + } + memcpy( buf + nread, openfiles[fd].sector, count ); + openfiles[fd].offset = nread; + nread += count; + } + } + + return nread; +} + +/* + * local variables: + * eval: (load-file "../rockbox-mode.el") + * end: + */ -- cgit v1.2.3