summaryrefslogtreecommitdiff
path: root/firmware/common/file.c
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/file.c
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/file.c')
-rw-r--r--firmware/common/file.c170
1 files changed, 170 insertions, 0 deletions
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 */