mbed library sources
Dependents: frdm_kl05z_gpio_test
Fork of mbed-src by
Diff: cpp/FileSystemLike.cpp
- Revision:
- 0:fd0d7bdfcdc2
- Child:
- 1:62685faffa05
diff -r 000000000000 -r fd0d7bdfcdc2 cpp/FileSystemLike.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cpp/FileSystemLike.cpp Tue Nov 20 17:24:08 2012 +0000 @@ -0,0 +1,162 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2012 ARM Limited + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "FileSystemLike.h" + +namespace mbed { + +FileSystemLike::FileSystemLike(const char *name) { + _name = name; + + if (name != NULL) { + // put this object at head of the list + _next = _head; + _head = this; + } else { + _next = NULL; + } +} + +FileSystemLike::~FileSystemLike() { + if (_name != NULL) { + // remove this object from the list + if (_head == this) { // first in the list, so just drop me + _head = _next; + } else { // find the object before me, then drop me + FileSystemLike* p = _head; + while (p->_next != this) { + p = p->_next; + } + p->_next = _next; + } + } +} + +FileSystemLike *FileSystemLike::lookup(const char *name, unsigned int len) { + FileSystemLike *p = _head; + while (p != NULL) { + /* Check that p->_name matches name and is the correct length */ + if (p->_name != NULL && std::strncmp(p->_name, name, len) == 0 && std::strlen(p->_name) == len) { + return p; + } + p = p->_next; + } + return NULL; +} + +class BaseDirHandle : public DirHandle { +public: + /* + We keep track of our current location as the n'th object in the + FileSystemLike list. Using a Base* instead would cause problems if that + object were to be destroyed between readdirs. + Using this method does mean though that destroying/creating objects can + give unusual results from readdir. + */ + off_t n; + struct dirent cur_entry; + + BaseDirHandle() { + n = 0; + } + + virtual int closedir() { + delete this; + return 0; + } + + virtual struct dirent *readdir() { + FileSystemLike *ptr = FileSystemLike::_head; + /* Find the n'th FileLike or FileSystemLike object in the Base list */ + int m = 0; + while (1) { + if (ptr == NULL) { + /* No such object */ + return NULL; + } + if (m == n) break; + + m++; + ptr = ptr->_next; + } + /* Increment n, so next readdir gets the next item */ + n++; + /* Setup curentry and return a pointer to it */ + std::strncpy(cur_entry.d_name, ptr->_name, NAME_MAX); + return &cur_entry; + } + + virtual off_t telldir() { + return n; + } + + virtual void seekdir(off_t offset) { + n = offset; + } + + virtual void rewinddir() { + n = 0; + } +}; + +DirHandle *FileSystemLike::opendir() { + return new BaseDirHandle(); +} + +FileSystemLike *FileSystemLike::_head = NULL; + + +FilePath::FilePath(const char* file_path) : file_name(NULL), fs(NULL) { + if ((file_path[0] != '/') || (file_path[1] == 0)) return; + + const char* file_system = &file_path[1]; + file_name = file_system; + int len = 0; + while (true) { + char c = *file_name++; + if (c == '/') { // end of object name + /* file now points to one char after the '/' */ + break; + } + if (c == 0) { // end of object name, with no filename + file_name = NULL; + break; + } + len++; + } + + fs = FileSystemLike::lookup(file_system, len); +} + +const char* FilePath::fileName(void) { + return file_name; +} + +FileSystemLike* FilePath::fileSystem(void) { + return fs; +} + +FileSystemLike* FilePath::getFileSystem(const char* path) { + FilePath f(path); + return f.fs; +} + +} // namespace mbed