123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- // interface to file system
- //
- // Copyright (c) 2009 Openmoko Inc.
- //
- // Authors Christopher Hall <hsw@openmoko.com>
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // 1. Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- //
- // 2. Redistributions in binary form must reproduce the above copyright
- // notice, this list of conditions and the following disclaimer in
- // the documentation and/or other materials provided with the
- // distribution.
- //
- // THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY
- // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
- // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- // BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #include <stddef.h>
- #include <stdbool.h>
- #include <string.h>
- #include <tff.h>
- #include <diskio.h>
- #include "forth.h"
- #include "FileSystem.h"
- #define SizeOfArray(a) (sizeof(a) / sizeof((a)[0]))
- // a type that can hold the path to the file
- typedef char FilenameType[128 + 1];
- // this determines the maximum files that can be open simultaneously
- typedef struct {
- bool IsOpen;
- FIL file;
- FilenameType filename;
- uint8_t ReadBuffer[1024];
- int ReadRemaining;
- int ReadOffset;
- } FileType;
- static FileType FileControlBlock[20];
- // this determines the maximum directoriess that can be open simultaneously
- typedef struct {
- bool IsOpen;
- DIR directory;
- FilenameType directoryname;
- } DirectoryType;
- static DirectoryType DirectoryControlBlock[10];
- // state for the entire file system
- static FATFS TheFileSystem;
- static bool ForthBufferToCString(char *buffer, size_t length,
- Forth_PointerType SourceBuffer, Forth_CellType SourceLength)
- {
- if (NULL == buffer || NULL == SourceBuffer) {
- return false;
- }
- if (SourceLength >= length) {
- --length;
- } else {
- length = SourceLength;
- }
- if (length > 0) {
- memcpy(buffer, SourceBuffer, length);
- buffer[length] = '\0';
- return true;
- }
- return false;
- }
- // ensure: 1 <= handle <= array size
- static FileType *ValidateFileHandle(Forth_ReturnType *r, Forth_CellType handle)
- {
- r->rc = FR_OK;
- r->result = 0;
- if (1 > handle || SizeOfArray(FileControlBlock) < handle) {
- r->rc = FR_INVALID_OBJECT;
- return NULL;
- }
- if (!FileControlBlock[handle - 1].IsOpen) {
- r->rc = FR_DENIED;
- return NULL;
- }
- return &FileControlBlock[handle - 1];
- }
- // ensure: 1 <= handle <= array size
- static DirectoryType *ValidateDirectoryHandle(Forth_ReturnType *r, Forth_CellType handle)
- {
- r->rc = FR_OK;
- r->result = 0;
- if (1 > handle || SizeOfArray(DirectoryControlBlock) < handle) {
- r->rc = FR_INVALID_OBJECT;
- return NULL;
- }
- if (!DirectoryControlBlock[handle - 1].IsOpen) {
- r->rc = FR_DENIED;
- return NULL;
- }
- return &DirectoryControlBlock[handle - 1];
- }
- void FileSystem_initialise(void)
- {
- size_t i = 0;
- for (i = 0; i < SizeOfArray(FileControlBlock); i++) {
- FileControlBlock[i].IsOpen = false;
- FileControlBlock[i].filename[0] = '\0';
- }
- for (i = 0; i < SizeOfArray(DirectoryControlBlock); i++) {
- DirectoryControlBlock[i].IsOpen = false;
- DirectoryControlBlock[i].directoryname[0] = '\0';
- }
- memset(&TheFileSystem, 0, sizeof(TheFileSystem));
- {
- uint8_t b = 0;
- disk_ioctl(0, CTRL_POWER, &b);
- disk_initialize(0);
- }
- f_mount(0, &TheFileSystem); // only possible value is zero
- }
- // closes all open handles, both files and directories
- void FileSystem_CloseAll(void)
- {
- size_t i = 0;
- for (i = 0; i < SizeOfArray(FileControlBlock); i++) {
- FileSystem_close(i + 1);
- }
- for (i = 0; i < SizeOfArray(DirectoryControlBlock); i++) {
- FileSystem_CloseDirectory(i + 1);
- }
- FileSystem_initialise();
- }
- Forth_ReturnType FileSystem_open(const Forth_PointerType filename, Forth_CellType length, Forth_CellType fam)
- {
- Forth_ReturnType r = {0, FR_OK};
- size_t i = 0;
- for (i = 0; i < SizeOfArray(FileControlBlock); i++) {
- if (!FileControlBlock[i].IsOpen) {
- if (!ForthBufferToCString(FileControlBlock[i].filename,
- sizeof(FileControlBlock[i].filename),
- filename, length)) {
- r.rc = FR_INVALID_NAME;
- return r;
- }
- r.rc = f_open(&FileControlBlock[i].file, FileControlBlock[i].filename, fam);
- if (FR_OK == r.rc) {
- FileControlBlock[i].IsOpen = true;
- FileControlBlock[i].ReadRemaining = 0;
- FileControlBlock[i].ReadOffset = 0;
- r.result = i + 1; // handle starts at one(1), not zero(0)
- return r;
- }
- break;
- }
- }
- r.rc = FR_DENIED;
- return r;
- }
- Forth_ReturnType FileSystem_rename(const Forth_PointerType OldFilename, Forth_CellType OldLength,
- const Forth_PointerType NewFilename, Forth_CellType NewLength)
- {
- Forth_ReturnType r = {0, FR_OK};
- FilenameType TempOldFilename;
- FilenameType TempNewFilename;
- if (!ForthBufferToCString(TempOldFilename, sizeof(TempOldFilename), OldFilename, OldLength)
- || !ForthBufferToCString(TempNewFilename, sizeof(TempNewFilename), NewFilename, NewLength)) {
- r.rc = FR_INVALID_NAME;
- return r;
- }
- r.rc = f_rename(TempOldFilename, TempNewFilename);
- return r;
- }
- Forth_ReturnType FileSystem_delete(const Forth_PointerType filename, Forth_CellType length)
- {
- Forth_ReturnType r = {0, FR_OK};
- FilenameType TempFilename;
- if (!ForthBufferToCString(TempFilename, sizeof(TempFilename), filename, length)) {
- r.rc = FR_INVALID_NAME;
- return r;
- }
- r.rc = f_unlink(TempFilename);
- return r;
- }
- Forth_ReturnType FileSystem_create(const Forth_PointerType filename, Forth_CellType length, Forth_CellType fam)
- {
- return FileSystem_open(filename, length, fam | FA_CREATE_NEW | FA_CREATE_ALWAYS);
- }
- Forth_ReturnType FileSystem_close(Forth_CellType handle)
- {
- Forth_ReturnType r = {0, FR_OK};
- FileType *file = ValidateFileHandle(&r, handle);
- if (NULL != file) {
- r.rc = f_close(&file->file);
- file->IsOpen = false;
- }
- return r;
- }
- Forth_ReturnType FileSystem_read(Forth_CellType handle, void *buffer, Forth_CellType length)
- {
- Forth_ReturnType r = {0, FR_OK};
- FileType *file = ValidateFileHandle(&r, handle);
- if (NULL != file) {
- //UINT count = 0;
- if (0 == file->ReadRemaining) {
- r.rc = f_read(&file->file, file->ReadBuffer, sizeof(file->ReadBuffer), &file->ReadRemaining);
- file->ReadOffset = 0;
- }
- if (length <= file->ReadRemaining) {
- r.result = length;
- memcpy(buffer, &file->ReadBuffer[file->ReadOffset], length);
- file->ReadRemaining -= length;
- file->ReadOffset += length;
- } else {
- r.result = file->ReadRemaining;
- memcpy(buffer, &file->ReadBuffer[file->ReadOffset], file->ReadRemaining);
- file->ReadRemaining = 0;
- file->ReadOffset = 0;
- }
- //r.rc = f_read(&file->file, buffer, length, &count);
- //r.result = count;
- }
- return r;
- }
- Forth_ReturnType FileSystem_write(Forth_CellType handle, void *buffer, Forth_CellType length)
- {
- Forth_ReturnType r = {0, FR_OK};
- FileType *file = ValidateFileHandle(&r, handle);
- if (NULL != file) {
- UINT count = 0;
- r.rc = f_write(&file->file, buffer, length, &count);
- r.result = count;
- }
- return r;
- }
- Forth_ReturnType FileSystem_sync(Forth_CellType handle)
- {
- Forth_ReturnType r = {0, FR_OK};
- FileType *file = ValidateFileHandle(&r, handle);
- if (NULL != file) {
- r.rc = f_sync(&file->file);
- }
- return r;
- }
- Forth_ReturnType FileSystem_lseek(Forth_CellType handle, Forth_CellType pos)
- {
- Forth_ReturnType r = {0, FR_OK};
- FileType *file = ValidateFileHandle(&r, handle);
- if (NULL != file) {
- r.rc = f_lseek(&file->file, pos);
- }
- return r;
- }
- Forth_ReturnType FileSystem_ltell(Forth_CellType handle)
- {
- Forth_ReturnType r = {0, FR_OK};
- FileType *file = ValidateFileHandle(&r, handle);
- if (NULL != file) {
- // not available :- just error
- //r.rc = f_ltell(&file->file, pos);
- r.rc = FR_DENIED;
- }
- return r;
- }
- Forth_ReturnType FileSystem_lsize(Forth_CellType handle)
- {
- Forth_ReturnType r = {0, FR_OK};
- FileType *file = ValidateFileHandle(&r, handle);
- if (NULL != file) {
- FILINFO stat;
- r.rc = f_stat(file->filename, &stat);
- r.result = stat.fsize;
- }
- return r;
- }
- Forth_CellType FileSystem_ReadOnly(void)
- {
- return FA_READ;
- }
- Forth_CellType FileSystem_ReadWrite(void)
- {
- return FA_READ | FA_WRITE;
- }
- Forth_CellType FileSystem_WriteOnly(void)
- {
- return FA_WRITE;
- }
- Forth_CellType FileSystem_bin(Forth_CellType fam)
- {
- return fam;
- }
- Forth_ReturnType FileSystem_CreateDirectory(const Forth_PointerType directoryname, Forth_CellType length)
- {
- Forth_ReturnType r = {0, FR_OK};
- FilenameType DirectoryNameBuffer;
- if (!ForthBufferToCString(DirectoryNameBuffer, sizeof(DirectoryNameBuffer),
- directoryname, length)) {
- r.rc = FR_INVALID_NAME;
- return r;
- }
- r.rc = f_mkdir(DirectoryNameBuffer);
- return r;
- }
- Forth_ReturnType FileSystem_OpenDirectory(const Forth_PointerType directoryname, Forth_CellType length)
- {
- Forth_ReturnType r = {0, FR_OK};
- size_t i = 0;
- for (i = 0; i < SizeOfArray(DirectoryControlBlock); i++) {
- if (!DirectoryControlBlock[i].IsOpen) {
- if (!ForthBufferToCString(DirectoryControlBlock[i].directoryname,
- sizeof(DirectoryControlBlock[i].directoryname),
- directoryname, length)) {
- r.rc = FR_INVALID_NAME;
- return r;
- }
- r.rc = f_opendir(&DirectoryControlBlock[i].directory, DirectoryControlBlock[i].directoryname);
- if (FR_OK == r.rc) {
- DirectoryControlBlock[i].IsOpen = true;
- r.result = i + 1; // directory handle starts at one(1), not zero(0)
- return r;
- }
- break;
- }
- }
- r.rc = FR_DENIED;
- return r;
- }
- Forth_ReturnType FileSystem_CloseDirectory(Forth_CellType handle)
- {
- Forth_ReturnType r = {0, FR_OK};
- DirectoryType *directory = ValidateDirectoryHandle(&r, handle);
- if (NULL != directory) {
- //r.rc = f_dirclose(&directory->directory);
- directory->IsOpen = false;
- }
- return r;
- }
- Forth_ReturnType FileSystem_ReadDirectory(Forth_CellType handle, void *buffer, Forth_CellType length)
- {
- Forth_ReturnType r = {0, FR_OK};
- DirectoryType *directory = ValidateDirectoryHandle(&r, handle);
- if (NULL != directory) {
- FILINFO info;
- r.rc = f_readdir(&directory->directory, &info);
- if (FR_OK == r.rc){
- size_t count = strlen(info.fname);
- if (count > length) {
- count = length;
- }
- if (0 != count) {
- memcpy(buffer, info.fname, count);
- }
- r.result = count;
- }
- }
- return r;
- }
- Forth_ReturnType FileSystem_AbsoluteRead(Forth_CellType sector, void *buffer, Forth_CellType count)
- {
- Forth_ReturnType r = {0, FR_OK};
- r.rc = disk_read(0, buffer, sector, count);
- return r;
- }
- Forth_ReturnType FileSystem_AbsoluteWrite(Forth_CellType sector, const void *buffer, Forth_CellType count)
- {
- Forth_ReturnType r = {0, FR_OK};
- r.rc = disk_write(0, buffer, sector, count);
- return r;
- }
- // 31-25: Year(0-127 +1980)
- // 24-21: Month(1-12)
- // 20-16: Day(1-31)
- // 15-11: Hour(0-23)
- // 10- 5: Minute(0-59)
- // 4- 0: Second(0-29 *2)
- #define YEAR (2009 - 1980)
- #define MONTH 3
- #define DAY 30
- #define HOUR 17
- #define MINUTE 58
- #define SECOND 41
- DWORD get_fattime (void)
- {
- return
- (YEAR << 25) |
- (MONTH << 21) |
- (DAY << 16) |
- (HOUR << 11) |
- (MINUTE << 5) |
- (SECOND << 0);
- }
|