kfile.c

Go to the documentation of this file.
00001 
00041 #include "kfile.h"
00042 
00043 #include "cfg/cfg_kfile.h"
00044 #include <cfg/debug.h>
00045 #include <cfg/log.h>
00046 
00047 #include <drv/timer.h>
00048 #include <mware/formatwr.h>
00049 
00050 #include <string.h>
00051 
00052 /*
00053  * Sanity check for config parameters required by this module.
00054  */
00055 #if !defined(CONFIG_KFILE_GETS) || ((CONFIG_KFILE_GETS != 0) && CONFIG_KFILE_GETS != 1)
00056     #error CONFIG_KFILE_GETS must be set to either 0 or 1 in appconfig.h
00057 #endif
00058 #if !defined(CONFIG_PRINTF)
00059     #error CONFIG_PRINTF missing in appconfig.h
00060 #endif
00061 
00062 
00066 int kfile_putc(int _c, struct KFile *fd)
00067 {
00068     unsigned char c = (unsigned char)_c;
00069 
00070     if (kfile_write(fd, &c, sizeof(c)) == sizeof(c))
00071         return (int)((unsigned char)_c);
00072     else
00073         return EOF;
00074 }
00075 
00079 int kfile_getc(struct KFile *fd)
00080 {
00081     unsigned char c;
00082 
00083     if (kfile_read(fd, &c, sizeof(c)) == sizeof(c))
00084         return (int)((unsigned char)c);
00085     else
00086         return EOF;
00087 }
00088 
00089 #if CONFIG_PRINTF
00090 
00093 int kfile_printf(struct KFile *fd, const char *format, ...)
00094 {
00095     va_list ap;
00096     int len;
00097 
00098     va_start(ap, format);
00099     len = _formatted_write(format, (void (*)(char, void *))kfile_putc, fd, ap);
00100     va_end(ap);
00101 
00102     return len;
00103 }
00104 #endif /* CONFIG_PRINTF */
00105 
00110 int kfile_print(struct KFile *fd, const char *s)
00111 {
00112     while (*s)
00113     {
00114         if (kfile_putc(*s++, fd) == EOF)
00115             return EOF;
00116     }
00117     return 0;
00118 }
00119 
00120 #if CONFIG_KFILE_GETS
00121 
00127 int kfile_gets(struct KFile *fd, char *buf, int size)
00128 {
00129     return kfile_gets_echo(fd, buf, size, false);
00130 }
00131 
00132 
00140 int kfile_gets_echo(struct KFile *fd, char *buf, int size, bool echo)
00141 {
00142     int i = 0;
00143     int c;
00144 
00145     for (;;)
00146     {
00147         if ((c = kfile_getc(fd)) == EOF)
00148         {
00149             buf[i] = '\0';
00150             return -1;
00151         }
00152 
00153         /* FIXME */
00154         if (c == '\r' || c == '\n' || i >= size-1)
00155         {
00156             buf[i] = '\0';
00157             if (echo)
00158                 kfile_print(fd, "\r\n");
00159             break;
00160         }
00161         buf[i++] = c;
00162         if (echo)
00163             kfile_putc(c, fd);
00164     }
00165 
00166     return i;
00167 }
00168 #endif /* !CONFIG_KFILE_GETS */
00169 
00170 
00177 kfile_off_t kfile_genericSeek(struct KFile *fd, kfile_off_t offset, KSeekMode whence)
00178 {
00179     kfile_off_t seek_pos;
00180 
00181     switch (whence)
00182     {
00183 
00184     case KSM_SEEK_SET:
00185         seek_pos = 0;
00186         break;
00187     case KSM_SEEK_END:
00188         seek_pos = fd->size;
00189         break;
00190     case KSM_SEEK_CUR:
00191         seek_pos = fd->seek_pos;
00192         break;
00193     default:
00194         ASSERT(0);
00195         return EOF;
00196         break;
00197     }
00198 
00199     #if LOG_LEVEL >= LOG_LVL_INFO
00200     /* Bound check */
00201     if (seek_pos + offset > fd->size)
00202         LOG_INFO("seek outside EOF\n");
00203     #endif
00204 
00205     fd->seek_pos = seek_pos + offset;
00206 
00207     return fd->seek_pos;
00208 }
00209 
00215 struct KFile * kfile_genericReopen(struct KFile *fd)
00216 {
00217     kfile_flush(fd);
00218     kfile_seek(fd, 0, KSM_SEEK_SET);
00219     return fd;
00220 }
00221 
00226 int kfile_genericClose(UNUSED_ARG(struct KFile *, fd))
00227 {
00228     return 0;
00229 };
00230 
00231 
00241 void kfile_resync(KFile *fd, mtime_t delay)
00242 {
00243     ticks_t start_time = timer_clock();
00244     for(;;)
00245     {
00246         if(kfile_getc(fd) != EOF)
00247             start_time = timer_clock();
00248 
00249         if ((timer_clock() - start_time) > ms_to_ticks(delay))
00250         {
00251             kfile_clearerr(fd);
00252             break;
00253         }
00254 
00255     }
00256 }
00257 
00262 static int kfile_generic(UNUSED_ARG(struct KFile *, fd))
00263 {
00264     return 0;
00265 };
00266 
00267 
00271 void kfile_init(struct KFile *fd)
00272 {
00273     ASSERT(fd);
00274     memset(fd, 0, sizeof(*fd));
00275     fd->clearerr = (ClearErrFunc_t)kfile_generic;
00276     fd->close =  kfile_genericClose;
00277     fd->error = kfile_generic;
00278     fd->flush = kfile_generic;
00279     fd->read = (ReadFunc_t)kfile_generic;
00280     fd->reopen = kfile_genericReopen;
00281     fd->seek = kfile_genericSeek;
00282     fd->write = (WriteFunc_t)kfile_generic;
00283 }
00284