summaryrefslogtreecommitdiff
path: root/firmware/common
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-05-07 16:01:53 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-05-07 16:01:53 +0000
commit4bd870360af595a3f90b9ccc5a09d1414fd654e9 (patch)
treefccdc0da07d36d858560129f9a3b4c66d4669943 /firmware/common
parent44b1a21f17975c896fd41dfff2e128a81ca77fc3 (diff)
downloadrockbox-4bd870360af595a3f90b9ccc5a09d1414fd654e9.tar.gz
rockbox-4bd870360af595a3f90b9ccc5a09d1414fd654e9.zip
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
Diffstat (limited to 'firmware/common')
-rw-r--r--firmware/common/dir.c1
-rw-r--r--firmware/common/dir.h1
-rw-r--r--firmware/common/file.c170
-rw-r--r--firmware/common/file.h7
4 files changed, 176 insertions, 3 deletions
diff --git a/firmware/common/dir.c b/firmware/common/dir.c
index b0927c09c6..acc412c570 100644
--- a/firmware/common/dir.c
+++ b/firmware/common/dir.c
@@ -94,6 +94,7 @@ struct dirent* readdir(DIR* dir)
94 strncpy(theent.d_name, entry.name, sizeof( theent.d_name ) ); 94 strncpy(theent.d_name, entry.name, sizeof( theent.d_name ) );
95 theent.attribute = entry.attr; 95 theent.attribute = entry.attr;
96 theent.size = entry.filesize; 96 theent.size = entry.filesize;
97 theent.startcluster = entry.firstcluster;
97 98
98 return &theent; 99 return &theent;
99} 100}
diff --git a/firmware/common/dir.h b/firmware/common/dir.h
index e03d50901c..274c0b1ea4 100644
--- a/firmware/common/dir.h
+++ b/firmware/common/dir.h
@@ -32,6 +32,7 @@ struct dirent {
32 unsigned char d_name[256]; 32 unsigned char d_name[256];
33 int attribute; 33 int attribute;
34 int size; 34 int size;
35 int startcluster;
35}; 36};
36#endif 37#endif
37 38
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Björn Stenberg
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <string.h>
20#include "file.h"
21#include "fat.h"
22#include "types.h"
23#include "dir.h"
24#include "debug.h"
25
26#define MAX_OPEN_FILES 4
27
28struct filedesc {
29 unsigned char sector[SECTOR_SIZE];
30 int offset;
31 struct fat_file fatfile;
32 bool busy;
33};
34
35static struct filedesc openfiles[MAX_OPEN_FILES];
36
37int open(char* pathname, int flags)
38{
39 DIR* dir;
40 struct dirent* entry;
41 int fd;
42 char* name;
43 int namelen;
44
45 if ( pathname[0] != '/' ) {
46 DEBUGF("'%s' is not an absolute path.\n",pathname);
47 DEBUGF("Only absolute pathnames supported at the moment\n");
48 return -1;
49 }
50
51 /* find a free file descriptor */
52 for ( fd=0; fd<MAX_OPEN_FILES; fd++ )
53 if ( !openfiles[fd].busy )
54 break;
55
56 if ( fd == MAX_OPEN_FILES ) {
57 DEBUGF("Too many files open\n");
58 return -1;
59 }
60
61 /* locate filename */
62 name=strrchr(pathname+1,'/');
63 if ( name ) {
64 *name = 0;
65 dir = opendir(pathname);
66 *name = '/';
67 name++;
68 }
69 else {
70 dir = opendir("/");
71 name = pathname+1;
72 }
73 if (!dir) {
74 DEBUGF("Failed opening dir\n");
75 return -1;
76 }
77
78 /* scan dir for name */
79 namelen = strlen(name);
80 while ((entry = readdir(dir))) {
81 if ( !strncmp(name, entry->d_name, namelen) ) {
82 fat_open(entry->startcluster, &(openfiles[fd].fatfile));
83 break;
84 }
85 else {
86 DEBUGF("entry: %s\n",entry->d_name);
87 }
88 }
89 closedir(dir);
90 if ( !entry ) {
91 DEBUGF("Couldn't find %s in %s\n",name,pathname);
92 /* fixme: we need to use proper error codes */
93 return -1;
94 }
95
96 openfiles[fd].offset = 0;
97 openfiles[fd].busy = TRUE;
98 return fd;
99}
100
101int close(int fd)
102{
103 openfiles[fd].busy = FALSE;
104 return 0;
105}
106
107int read(int fd, void* buf, int count)
108{
109 int sectors;
110 int nread=0;
111
112 /* are we in the middle of a cached sector? */
113 if ( openfiles[fd].offset ) {
114 if ( count > (SECTOR_SIZE - openfiles[fd].offset) ) {
115 memcpy( buf, openfiles[fd].sector,
116 SECTOR_SIZE - openfiles[fd].offset );
117 openfiles[fd].offset = 0;
118 nread = SECTOR_SIZE - openfiles[fd].offset;
119 count -= nread;
120 }
121 else {
122 memcpy( buf, openfiles[fd].sector, count );
123 openfiles[fd].offset += count;
124 nread = count;
125 count = 0;
126 }
127 }
128
129 /* read whole sectors right into the supplied buffer */
130 sectors = count / SECTOR_SIZE;
131 if ( sectors ) {
132 if ( fat_read(&(openfiles[fd].fatfile), sectors, buf+nread ) < 0 ) {
133 DEBUGF("Failed reading %d sectors\n",sectors);
134 return -1;
135 }
136 nread += sectors * SECTOR_SIZE;
137 count -= sectors * SECTOR_SIZE;
138 openfiles[fd].offset = 0;
139 }
140
141 /* trailing odd bytes? */
142 if ( count ) {
143 /* do we already have the sector cached? */
144 if ( count < (SECTOR_SIZE - openfiles[fd].offset) ) {
145 memcpy( buf + nread, openfiles[fd].sector, count );
146 openfiles[fd].offset += count;
147 nread += count;
148 count = 0;
149 }
150 else {
151 /* cache one sector and copy the trailing bytes */
152 if ( fat_read(&(openfiles[fd].fatfile), 1,
153 &(openfiles[fd].sector)) < 0 ) {
154 DEBUGF("Failed reading odd sector\n");
155 return -1;
156 }
157 memcpy( buf + nread, openfiles[fd].sector, count );
158 openfiles[fd].offset = nread;
159 nread += count;
160 }
161 }
162
163 return nread;
164}
165
166/*
167 * local variables:
168 * eval: (load-file "../rockbox-mode.el")
169 * end:
170 */
diff --git a/firmware/common/file.h b/firmware/common/file.h
index 58fb22d881..9d0d6f0501 100644
--- a/firmware/common/file.h
+++ b/firmware/common/file.h
@@ -33,14 +33,15 @@
33#ifndef SIMULATOR 33#ifndef SIMULATOR
34extern int open(char* pathname, int flags); 34extern int open(char* pathname, int flags);
35extern int close(int fd); 35extern int close(int fd);
36
37extern int read(int fd, void* buf, int count); 36extern int read(int fd, void* buf, int count);
38extern int write(int fd, void* buf, int count);
39
40extern int lseek(int fd, int offset, int whence); 37extern int lseek(int fd, int offset, int whence);
41 38
39#ifdef DISK_WRITE
40extern int write(int fd, void* buf, int count);
42extern int remove(char* pathname); 41extern int remove(char* pathname);
43extern int rename(char* oldname, char* newname); 42extern int rename(char* oldname, char* newname);
43#endif
44
44#else 45#else
45#ifdef WIN32 46#ifdef WIN32
46#include <io.h> 47#include <io.h>