mbed library sources

Fork of mbed-src by mbed official

Revision:
0:fd0d7bdfcdc2
Child:
1:62685faffa05
--- /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