/** * Creates a new directory with the given name and location * * @param name The fully qualified name of the new directory. * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if the path is invalid, or MICROBT_NO_RESOURCES if the FileSystem is full. */ int MicroBitFileSystem::createDirectory(char const *name) { DirectoryEntry* directory; // Directory holding this file. DirectoryEntry* dirent; // Entry in the direcoty of this file. // Protect against accidental re-initialisation if ((status & MBFS_STATUS_INITIALISED) == 0) return MICROBIT_NOT_SUPPORTED; // Reject invalid filenames. if (!isValidFilename(name)) return MICROBIT_INVALID_PARAMETER; // Determine the directory for this file. directory = getDirectoryOf(name); if (directory == NULL) return MICROBIT_INVALID_PARAMETER; // Find the DirectoryEntry associated with the given name (if it exists). // We don't permit files or directories with the same name. dirent = getDirectoryEntry(name, directory); if (dirent) return MICROBIT_INVALID_PARAMETER; dirent = createFile(name, directory, true); if (dirent == NULL) return MICROBIT_NO_RESOURCES; return MICROBIT_OK; }
std::string prefixSanityFix(std::string prefix) { prefix.erase(std::remove_if(prefix.begin(), prefix.end(), ::isspace), prefix.end()); prefix.erase(std::remove(prefix.begin(), prefix.end(), '/'), prefix.end()); prefix.erase(std::remove(prefix.begin(), prefix.end(), '\\'), prefix.end()); prefix.erase(std::remove(prefix.begin(), prefix.end(), '.'), prefix.end()); prefix.erase(std::remove(prefix.begin(), prefix.end(), ':'), prefix.end()); if (!isValidFilename(prefix)) { return { }; } return prefix; }
/** * Open a new file, and obtain a new file handle (int) to * read/write/seek the file. The flags are: * - MB_READ : read from the file. * - MB_WRITE : write to the file. * - MB_CREAT : create a new file, if it doesn't already exist. * * If a file is opened that doesn't exist, and MB_CREAT isn't passed, * an error is returned, otherwise the file is created. * * @param filename name of the file to open, must contain only printable characters. * @param flags One or more of MB_READ, MB_WRITE or MB_CREAT. * @return return the file handle,MICROBIT_NOT_SUPPORTED if the file system has * not been initialised MICROBIT_INVALID_PARAMETER if the filename is * too large, MICROBIT_NO_RESOURCES if the file system is full. * * @code * MicroBitFileSystem f(); * int fd = f.open("test.txt", MB_WRITE|MB_CREAT); * if(fd<0) * print("file open error"); * @endcode */ int MicroBitFileSystem::open(char const * filename, uint32_t flags) { FileDescriptor *file; // File Descriptor of this file. DirectoryEntry* directory; // Directory holding this file. DirectoryEntry* dirent; // Entry in the direcoty of this file. int id; // FileDescriptor id to be return to the caller. // Protect against accidental re-initialisation if ((status & MBFS_STATUS_INITIALISED) == 0) return MICROBIT_NOT_SUPPORTED; // Reject invalid filenames. if(!isValidFilename(filename)) return MICROBIT_INVALID_PARAMETER; // Determine the directory for this file. directory = getDirectoryOf(filename); if (directory == NULL) return MICROBIT_INVALID_PARAMETER; // Find the DirectoryEntry assoviate with the given file (if it exists). dirent = getDirectoryEntry(filename, directory); // Only permit files to be opened once... // also, detemrine a valid ID for this open file as we go. file = openFiles; id = 0; while (file && dirent) { if (file->dirent == dirent) return MICROBIT_NOT_SUPPORTED; if (file->id == id) { id++; file = openFiles; continue; } file = file->next; } if (dirent == NULL) { // If the file doesn't exist, and we haven't been asked to create it, then there's nothing we can do. if (!(flags & MB_CREAT)) return MICROBIT_INVALID_PARAMETER; dirent = createFile(filename, directory, false); if (dirent == NULL) return MICROBIT_NO_RESOURCES; } // Try to add a new FileDescriptor into this directory. file = new FileDescriptor; if (file == NULL) return MICROBIT_NO_RESOURCES; // Populate the FileDescriptor file->flags = (flags & ~(MB_CREAT)); file->id = id; file->length = dirent->flags == MBFS_DIRECTORY_ENTRY_NEW ? 0 : dirent->length; file->seek = (flags & MB_APPEND) ? file->length : 0; file->dirent = dirent; file->directory = directory; file->cacheLength = 0; // Add the file descriptor to the chain of open files. file->next = openFiles; openFiles = file; // Return the FileDescriptor id to the user return file->id; }