mFS file system library for EEPROM memory chips.
mfs.cpp@13:142b6be3e3c8, 2011-02-24 (annotated)
- Committer:
- HBP
- Date:
- Thu Feb 24 09:28:32 2011 +0000
- Revision:
- 13:142b6be3e3c8
- Parent:
- 12:928346513c87
- Better handling of empty files
- doesn\t write EOF on AWRITE if EOF is not reached
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
HBP | 10:211cb54339a0 | 1 | /** @file mfs.cpp */ |
HBP | 5:a0fe74dce80d | 2 | /*CPP************************************************************************** |
HBP | 7:5ac5121bb4e0 | 3 | * FILENAME : mfs.cpp * |
HBP | 7:5ac5121bb4e0 | 4 | * * |
HBP | 7:5ac5121bb4e0 | 5 | * DESCRIPTION : * |
HBP | 7:5ac5121bb4e0 | 6 | * mFS file system implementation for mBED with external I2C EEEPROM. * |
HBP | 7:5ac5121bb4e0 | 7 | * * |
HBP | 7:5ac5121bb4e0 | 8 | * AUTHOR : Olli Vanhoja START DATE : 2011-02-21 * |
HBP | 7:5ac5121bb4e0 | 9 | *****************************************************************************/ |
HBP | 0:cbf45dde2b49 | 10 | |
HBP | 0:cbf45dde2b49 | 11 | #include "mbed.h" |
HBP | 0:cbf45dde2b49 | 12 | #include "mfs.h" |
HBP | 0:cbf45dde2b49 | 13 | #include "i2c_eeprom.h" |
HBP | 0:cbf45dde2b49 | 14 | |
HBP | 12:928346513c87 | 15 | #define BLOCK_LLEN 2 /**< Block number link length in bytes */ |
HBP | 12:928346513c87 | 16 | #define RB 1+2*BLOCK_LLEN /**< Reseved bytes per block (1 attrb B, 2 B for next/prev pointers */ |
HBP | 12:928346513c87 | 17 | #define I2C_SPEED 200000 /**< I2C bus speed in Hz */ |
HBP | 12:928346513c87 | 18 | #define DEBUG /**< Adds extra safety in reading and writing */ |
HBP | 0:cbf45dde2b49 | 19 | |
HBP | 10:211cb54339a0 | 20 | DigitalOut FlushLed(LED2); /**< Flush led */ |
HBP | 0:cbf45dde2b49 | 21 | |
HBP | 0:cbf45dde2b49 | 22 | mfs::mfs(int i2c_address) |
HBP | 0:cbf45dde2b49 | 23 | { |
HBP | 10:211cb54339a0 | 24 | mem = new i2c_eeprom(i2c_address, I2C_SPEED); |
HBP | 0:cbf45dde2b49 | 25 | } |
HBP | 0:cbf45dde2b49 | 26 | |
HBP | 10:211cb54339a0 | 27 | char mfs::read(char *data, uint32_t block, uint32_t byte, uint32_t n) |
HBP | 0:cbf45dde2b49 | 28 | { |
HBP | 0:cbf45dde2b49 | 29 | // Faster reading without DEBUG mode |
HBP | 0:cbf45dde2b49 | 30 | #ifdef DEBUG |
HBP | 0:cbf45dde2b49 | 31 | if ((byte+n-1 >= BS)) |
HBP | 0:cbf45dde2b49 | 32 | return 1; |
HBP | 0:cbf45dde2b49 | 33 | #endif |
HBP | 0:cbf45dde2b49 | 34 | mem->read(BS*block+byte, n, data); |
HBP | 12:928346513c87 | 35 | |
HBP | 0:cbf45dde2b49 | 36 | return 0; |
HBP | 0:cbf45dde2b49 | 37 | } |
HBP | 0:cbf45dde2b49 | 38 | |
HBP | 10:211cb54339a0 | 39 | char mfs::write(char *data, uint32_t block, uint32_t byte, uint32_t n) |
HBP | 0:cbf45dde2b49 | 40 | { |
HBP | 0:cbf45dde2b49 | 41 | // Faster writing without DEBUG mode |
HBP | 0:cbf45dde2b49 | 42 | #ifdef DEBUG |
HBP | 0:cbf45dde2b49 | 43 | if (byte+n >= BS) |
HBP | 0:cbf45dde2b49 | 44 | return 1; |
HBP | 0:cbf45dde2b49 | 45 | #endif |
HBP | 0:cbf45dde2b49 | 46 | mem->write(data, BS*block+byte, n); |
HBP | 12:928346513c87 | 47 | |
HBP | 0:cbf45dde2b49 | 48 | return 0; |
HBP | 0:cbf45dde2b49 | 49 | } |
HBP | 0:cbf45dde2b49 | 50 | |
HBP | 10:211cb54339a0 | 51 | char mfs::getNextFreeBlock(uint32_t *blockOut) |
HBP | 0:cbf45dde2b49 | 52 | { |
HBP | 0:cbf45dde2b49 | 53 | // Locate free block by seeking EERPOM |
HBP | 0:cbf45dde2b49 | 54 | char cFlags[1]; |
HBP | 0:cbf45dde2b49 | 55 | |
HBP | 0:cbf45dde2b49 | 56 | for (*blockOut=0; *blockOut < BC; (*blockOut)++) |
HBP | 0:cbf45dde2b49 | 57 | { |
HBP | 0:cbf45dde2b49 | 58 | read(cFlags, *blockOut, 0, 1); |
HBP | 0:cbf45dde2b49 | 59 | if (cFlags[0] == 0x04) |
HBP | 0:cbf45dde2b49 | 60 | break; |
HBP | 0:cbf45dde2b49 | 61 | if (*blockOut >= BC-1) |
HBP | 0:cbf45dde2b49 | 62 | return 1; |
HBP | 0:cbf45dde2b49 | 63 | } |
HBP | 0:cbf45dde2b49 | 64 | |
HBP | 0:cbf45dde2b49 | 65 | return 0; |
HBP | 0:cbf45dde2b49 | 66 | } |
HBP | 0:cbf45dde2b49 | 67 | |
HBP | 10:211cb54339a0 | 68 | char mfs::findNextFile(uint32_t block, char *filenameOut, uint32_t *blockOut) |
HBP | 0:cbf45dde2b49 | 69 | { |
HBP | 9:52c01cb100ac | 70 | uint32_t i=block; |
HBP | 0:cbf45dde2b49 | 71 | char cFlags[1]; |
HBP | 0:cbf45dde2b49 | 72 | |
HBP | 0:cbf45dde2b49 | 73 | while (i < BC) |
HBP | 0:cbf45dde2b49 | 74 | { |
HBP | 0:cbf45dde2b49 | 75 | read(cFlags, i, 0, 1); |
HBP | 0:cbf45dde2b49 | 76 | |
HBP | 0:cbf45dde2b49 | 77 | if ((cFlags[0] & 0x8C) == 0x8C) |
HBP | 0:cbf45dde2b49 | 78 | break; // File found |
HBP | 0:cbf45dde2b49 | 79 | else |
HBP | 0:cbf45dde2b49 | 80 | i++; |
HBP | 0:cbf45dde2b49 | 81 | } |
HBP | 0:cbf45dde2b49 | 82 | |
HBP | 0:cbf45dde2b49 | 83 | if(i == BC) |
HBP | 0:cbf45dde2b49 | 84 | { |
HBP | 0:cbf45dde2b49 | 85 | strcpy(filenameOut, ""); |
HBP | 10:211cb54339a0 | 86 | return 1; // Empty fs |
HBP | 0:cbf45dde2b49 | 87 | } |
HBP | 0:cbf45dde2b49 | 88 | |
HBP | 0:cbf45dde2b49 | 89 | // Read filename |
HBP | 10:211cb54339a0 | 90 | read(filenameOut, i, RB, 20); |
HBP | 10:211cb54339a0 | 91 | *blockOut = i; // Return block number |
HBP | 10:211cb54339a0 | 92 | return 0; |
HBP | 0:cbf45dde2b49 | 93 | } |
HBP | 0:cbf45dde2b49 | 94 | |
HBP | 10:211cb54339a0 | 95 | char mfs::getFirstBlockOfFile(char filename[20], uint32_t *blockOut) |
HBP | 0:cbf45dde2b49 | 96 | { |
HBP | 10:211cb54339a0 | 97 | *blockOut=0; |
HBP | 0:cbf45dde2b49 | 98 | char tmpFilename[20]=""; |
HBP | 0:cbf45dde2b49 | 99 | |
HBP | 10:211cb54339a0 | 100 | while (1) |
HBP | 0:cbf45dde2b49 | 101 | { |
HBP | 10:211cb54339a0 | 102 | if (findNextFile(*blockOut, tmpFilename, blockOut) == 0) |
HBP | 0:cbf45dde2b49 | 103 | { |
HBP | 0:cbf45dde2b49 | 104 | if(strcmp(tmpFilename, filename) == 0) |
HBP | 10:211cb54339a0 | 105 | return 0; // File exists |
HBP | 0:cbf45dde2b49 | 106 | } |
HBP | 10:211cb54339a0 | 107 | else return 1; // File doesn't exist |
HBP | 10:211cb54339a0 | 108 | (*blockOut)++; |
HBP | 0:cbf45dde2b49 | 109 | } |
HBP | 0:cbf45dde2b49 | 110 | } |
HBP | 0:cbf45dde2b49 | 111 | |
HBP | 0:cbf45dde2b49 | 112 | char mfs::createFile(char filename[20]) |
HBP | 0:cbf45dde2b49 | 113 | { |
HBP | 0:cbf45dde2b49 | 114 | char tmpFilename[20]; |
HBP | 9:52c01cb100ac | 115 | uint32_t n; |
HBP | 10:211cb54339a0 | 116 | uint32_t fb; |
HBP | 0:cbf45dde2b49 | 117 | |
HBP | 0:cbf45dde2b49 | 118 | for (n=0; n < BC; n++) |
HBP | 0:cbf45dde2b49 | 119 | { |
HBP | 10:211cb54339a0 | 120 | if(findNextFile(n, tmpFilename, &n) == 0) |
HBP | 0:cbf45dde2b49 | 121 | { |
HBP | 0:cbf45dde2b49 | 122 | if(strcmp(tmpFilename, filename) == 0) |
HBP | 0:cbf45dde2b49 | 123 | return 1; // File exist |
HBP | 0:cbf45dde2b49 | 124 | } |
HBP | 0:cbf45dde2b49 | 125 | else break; // We already reached the edge of the universe |
HBP | 0:cbf45dde2b49 | 126 | n++; |
HBP | 0:cbf45dde2b49 | 127 | } |
HBP | 0:cbf45dde2b49 | 128 | |
HBP | 10:211cb54339a0 | 129 | if(getNextFreeBlock(&fb) != 0) |
HBP | 0:cbf45dde2b49 | 130 | return 2; // Out of space |
HBP | 0:cbf45dde2b49 | 131 | |
HBP | 13:142b6be3e3c8 | 132 | char cData[RB+20+1]; |
HBP | 13:142b6be3e3c8 | 133 | cData[0] = '\xCC'; // Necessary flags for a file |
HBP | 13:142b6be3e3c8 | 134 | cData[1] = '\0'; // No more blocks yet |
HBP | 12:928346513c87 | 135 | cData[2] = '\0'; |
HBP | 13:142b6be3e3c8 | 136 | cData[3] = '\0'; // First block so there is no prev blocks |
HBP | 12:928346513c87 | 137 | cData[4] = '\0'; |
HBP | 13:142b6be3e3c8 | 138 | cData[RB+20] = mEOF; // Set EOF at the begining |
HBP | 0:cbf45dde2b49 | 139 | |
HBP | 0:cbf45dde2b49 | 140 | for (char i=0; i < 20; i++) |
HBP | 10:211cb54339a0 | 141 | cData[RB+i] = filename[i]; |
HBP | 0:cbf45dde2b49 | 142 | |
HBP | 0:cbf45dde2b49 | 143 | // Create file |
HBP | 13:142b6be3e3c8 | 144 | write(cData, fb, 0, RB+20+1); |
HBP | 0:cbf45dde2b49 | 145 | |
HBP | 0:cbf45dde2b49 | 146 | return 0; |
HBP | 0:cbf45dde2b49 | 147 | } |
HBP | 0:cbf45dde2b49 | 148 | |
HBP | 0:cbf45dde2b49 | 149 | char mfs::removeFile(char filename[20]) |
HBP | 0:cbf45dde2b49 | 150 | { |
HBP | 9:52c01cb100ac | 151 | uint32_t block; |
HBP | 12:928346513c87 | 152 | char cData[RB-BLOCK_LLEN]; |
HBP | 12:928346513c87 | 153 | char cDataNew[RB] = {'\x04', '\0', '\0', '\0', '\0'}; |
HBP | 12:928346513c87 | 154 | uint32_t i=0; |
HBP | 0:cbf45dde2b49 | 155 | |
HBP | 0:cbf45dde2b49 | 156 | // Check if file exists |
HBP | 11:6c4fcb9d6193 | 157 | if (getFirstBlockOfFile(filename, &block) != 0) |
HBP | 0:cbf45dde2b49 | 158 | return 1; // File not found |
HBP | 0:cbf45dde2b49 | 159 | |
HBP | 12:928346513c87 | 160 | read(cData, block, 0, RB-BLOCK_LLEN); |
HBP | 12:928346513c87 | 161 | |
HBP | 12:928346513c87 | 162 | // Check credentials |
HBP | 12:928346513c87 | 163 | if (((cData[0] & 0x01)|((cData[0] & 0x10) >> 3)|((cData[0] & 0x20) >> 3) & 0x04) != 0) |
HBP | 12:928346513c87 | 164 | return 2; // RO file |
HBP | 12:928346513c87 | 165 | |
HBP | 12:928346513c87 | 166 | // Clear blocks reserved by the file |
HBP | 0:cbf45dde2b49 | 167 | while(1) |
HBP | 0:cbf45dde2b49 | 168 | { |
HBP | 12:928346513c87 | 169 | write(cDataNew, block, 0, RB); |
HBP | 12:928346513c87 | 170 | if ((cData[0] & 0x4C) == 0x4C) |
HBP | 12:928346513c87 | 171 | break; // End of file found |
HBP | 12:928346513c87 | 172 | else block = (uint32_t)(cData[1])<<8|cData[2]; // Set next block number |
HBP | 0:cbf45dde2b49 | 173 | i++; |
HBP | 12:928346513c87 | 174 | if (i > BC) |
HBP | 12:928346513c87 | 175 | return 1; // fs is corrupted |
HBP | 12:928346513c87 | 176 | read(cData, block, 0, RB-BLOCK_LLEN); |
HBP | 0:cbf45dde2b49 | 177 | } |
HBP | 0:cbf45dde2b49 | 178 | |
HBP | 0:cbf45dde2b49 | 179 | return 0; // Everything went better than expected |
HBP | 0:cbf45dde2b49 | 180 | } |
HBP | 0:cbf45dde2b49 | 181 | |
HBP | 7:5ac5121bb4e0 | 182 | char mfs::renameFile(char oldFilename[20], char newFilename[20]) |
HBP | 7:5ac5121bb4e0 | 183 | { |
HBP | 9:52c01cb100ac | 184 | uint32_t block; |
HBP | 12:928346513c87 | 185 | char cData[1]; |
HBP | 7:5ac5121bb4e0 | 186 | |
HBP | 7:5ac5121bb4e0 | 187 | // Check if file exists |
HBP | 10:211cb54339a0 | 188 | if (getFirstBlockOfFile(oldFilename, &block) != 0) |
HBP | 7:5ac5121bb4e0 | 189 | return 1; // File not found |
HBP | 7:5ac5121bb4e0 | 190 | |
HBP | 12:928346513c87 | 191 | // Check credentials |
HBP | 12:928346513c87 | 192 | read(cData, block, 0, 1); |
HBP | 12:928346513c87 | 193 | char flags = (cData[0] & 0x01)|((cData[0] & 0x10) >> 3)|((cData[0] & 0x20) >> 3); |
HBP | 12:928346513c87 | 194 | if ((flags & 0x04) != 0) |
HBP | 12:928346513c87 | 195 | return 2; // RO file |
HBP | 12:928346513c87 | 196 | |
HBP | 10:211cb54339a0 | 197 | write(newFilename, block, RB, 20); |
HBP | 7:5ac5121bb4e0 | 198 | |
HBP | 7:5ac5121bb4e0 | 199 | return 0; // Everything went better than expected |
HBP | 7:5ac5121bb4e0 | 200 | } |
HBP | 7:5ac5121bb4e0 | 201 | |
HBP | 0:cbf45dde2b49 | 202 | char mfs::setFileFlags(char *flags, char filename[20]) |
HBP | 0:cbf45dde2b49 | 203 | { |
HBP | 0:cbf45dde2b49 | 204 | /* RO|HIDDEN|LOCK * |
HBP | 0:cbf45dde2b49 | 205 | * H L */ |
HBP | 0:cbf45dde2b49 | 206 | |
HBP | 9:52c01cb100ac | 207 | uint32_t n; |
HBP | 0:cbf45dde2b49 | 208 | char cData[1] = {'\0'}; |
HBP | 12:928346513c87 | 209 | char cFlags; |
HBP | 0:cbf45dde2b49 | 210 | |
HBP | 0:cbf45dde2b49 | 211 | // Check if file exists |
HBP | 10:211cb54339a0 | 212 | if (getFirstBlockOfFile(filename, &n) != 0) |
HBP | 0:cbf45dde2b49 | 213 | return 1; // File not found |
HBP | 0:cbf45dde2b49 | 214 | |
HBP | 0:cbf45dde2b49 | 215 | read(cData, n, 0, 1); |
HBP | 12:928346513c87 | 216 | cFlags = ((flags[0] & 0x01)|((flags[0] & 0x02) << 3)|((flags[0] & 0x04) << 3)); |
HBP | 12:928346513c87 | 217 | cData[0] = cData[0] & (~0x31) | cFlags; |
HBP | 0:cbf45dde2b49 | 218 | write(cData, n, 0, 1); |
HBP | 0:cbf45dde2b49 | 219 | |
HBP | 0:cbf45dde2b49 | 220 | return 0; |
HBP | 0:cbf45dde2b49 | 221 | } |
HBP | 0:cbf45dde2b49 | 222 | |
HBP | 0:cbf45dde2b49 | 223 | char mfs::getFileFlags(char *flags, char filename[20]) |
HBP | 0:cbf45dde2b49 | 224 | { |
HBP | 0:cbf45dde2b49 | 225 | /* RO|HIDDEN|LOCK * |
HBP | 0:cbf45dde2b49 | 226 | * H L */ |
HBP | 0:cbf45dde2b49 | 227 | |
HBP | 9:52c01cb100ac | 228 | uint32_t n; |
HBP | 0:cbf45dde2b49 | 229 | char cData[1] = {'\0'}; |
HBP | 0:cbf45dde2b49 | 230 | |
HBP | 0:cbf45dde2b49 | 231 | // Check if file exists |
HBP | 10:211cb54339a0 | 232 | if (getFirstBlockOfFile(filename, &n) != 0) |
HBP | 0:cbf45dde2b49 | 233 | return 1; // File not found |
HBP | 0:cbf45dde2b49 | 234 | |
HBP | 0:cbf45dde2b49 | 235 | read(cData, n, 0, 1); |
HBP | 0:cbf45dde2b49 | 236 | flags[0] = (cData[0] & 0x01)|((cData[0] & 0x10) >> 3)|((cData[0] & 0x20) >> 3); |
HBP | 0:cbf45dde2b49 | 237 | |
HBP | 0:cbf45dde2b49 | 238 | return 0; |
HBP | 0:cbf45dde2b49 | 239 | } |
HBP | 0:cbf45dde2b49 | 240 | |
HBP | 0:cbf45dde2b49 | 241 | // Return number of free blocks |
HBP | 10:211cb54339a0 | 242 | uint32_t mfs::free() |
HBP | 0:cbf45dde2b49 | 243 | { |
HBP | 10:211cb54339a0 | 244 | uint32_t blocks=0; |
HBP | 10:211cb54339a0 | 245 | uint32_t r; |
HBP | 0:cbf45dde2b49 | 246 | char cFlags[1]; |
HBP | 0:cbf45dde2b49 | 247 | |
HBP | 0:cbf45dde2b49 | 248 | for (r=0; r < BC; r++) |
HBP | 0:cbf45dde2b49 | 249 | { |
HBP | 0:cbf45dde2b49 | 250 | read(cFlags, r, 0, 1); |
HBP | 0:cbf45dde2b49 | 251 | if (cFlags[0] == 0x04) |
HBP | 0:cbf45dde2b49 | 252 | blocks++; |
HBP | 0:cbf45dde2b49 | 253 | if (r >= BC-1) |
HBP | 0:cbf45dde2b49 | 254 | return blocks; |
HBP | 0:cbf45dde2b49 | 255 | } |
HBP | 0:cbf45dde2b49 | 256 | |
HBP | 0:cbf45dde2b49 | 257 | return 0; |
HBP | 0:cbf45dde2b49 | 258 | } |
HBP | 0:cbf45dde2b49 | 259 | |
HBP | 10:211cb54339a0 | 260 | uint32_t mfs::mkfs(bool createLabel) |
HBP | 0:cbf45dde2b49 | 261 | { |
HBP | 10:211cb54339a0 | 262 | uint32_t iAddr = 0; |
HBP | 10:211cb54339a0 | 263 | uint32_t i = 0; |
HBP | 10:211cb54339a0 | 264 | uint32_t bad = 0; // For counting bad block headers |
HBP | 12:928346513c87 | 265 | char cFlags[RB] = {'\0', '\0', '\0', '\0', '\0'}, o[1]; |
HBP | 0:cbf45dde2b49 | 266 | |
HBP | 10:211cb54339a0 | 267 | if (createLabel == true) |
HBP | 0:cbf45dde2b49 | 268 | { |
HBP | 0:cbf45dde2b49 | 269 | // Write Volume label |
HBP | 0:cbf45dde2b49 | 270 | cFlags[0] = '\x0E'; |
HBP | 12:928346513c87 | 271 | mem->write(cFlags, iAddr, RB); |
HBP | 0:cbf45dde2b49 | 272 | iAddr = BS; |
HBP | 0:cbf45dde2b49 | 273 | i = 1; |
HBP | 0:cbf45dde2b49 | 274 | } |
HBP | 0:cbf45dde2b49 | 275 | |
HBP | 0:cbf45dde2b49 | 276 | cFlags[0] = '\x04'; |
HBP | 0:cbf45dde2b49 | 277 | for (; i < BC; i++) |
HBP | 0:cbf45dde2b49 | 278 | { |
HBP | 12:928346513c87 | 279 | mem->write(cFlags, iAddr, RB); |
HBP | 12:928346513c87 | 280 | mem->read(iAddr, 1, o); |
HBP | 12:928346513c87 | 281 | if (o[0] != cFlags[0]) |
HBP | 0:cbf45dde2b49 | 282 | bad++; |
HBP | 0:cbf45dde2b49 | 283 | iAddr += BS; |
HBP | 0:cbf45dde2b49 | 284 | } |
HBP | 0:cbf45dde2b49 | 285 | |
HBP | 0:cbf45dde2b49 | 286 | return bad; |
HBP | 0:cbf45dde2b49 | 287 | } |
HBP | 0:cbf45dde2b49 | 288 | |
HBP | 12:928346513c87 | 289 | file::file(mfs *fs_ref, char filename[20], FileOpenMode operation) |
HBP | 0:cbf45dde2b49 | 290 | { |
HBP | 12:928346513c87 | 291 | fMode = operation; |
HBP | 0:cbf45dde2b49 | 292 | |
HBP | 0:cbf45dde2b49 | 293 | fs = fs_ref; // Don't forget this :) |
HBP | 0:cbf45dde2b49 | 294 | |
HBP | 9:52c01cb100ac | 295 | uint32_t n; |
HBP | 12:928346513c87 | 296 | char cData[1] = {'\0'}; |
HBP | 0:cbf45dde2b49 | 297 | |
HBP | 0:cbf45dde2b49 | 298 | // Check if file exists |
HBP | 10:211cb54339a0 | 299 | if (fs->getFirstBlockOfFile(filename, &n) != 0) |
HBP | 0:cbf45dde2b49 | 300 | error("Oops, file \"%s\" not found! n=0x%X", filename, n); // File not found |
HBP | 0:cbf45dde2b49 | 301 | |
HBP | 0:cbf45dde2b49 | 302 | fs->read(cData, n, 0, 1); |
HBP | 0:cbf45dde2b49 | 303 | char flags = (cData[0] & 0x01)|((cData[0] & 0x10) >> 3)|((cData[0] & 0x20) >> 3); |
HBP | 0:cbf45dde2b49 | 304 | |
HBP | 12:928346513c87 | 305 | if ((fMode != RO) && ((flags & 0x04) != 0)) |
HBP | 12:928346513c87 | 306 | error("Oops, cant open in RW mode!"); |
HBP | 0:cbf45dde2b49 | 307 | |
HBP | 0:cbf45dde2b49 | 308 | // Store FBOF number |
HBP | 0:cbf45dde2b49 | 309 | firstBlock = n; |
HBP | 0:cbf45dde2b49 | 310 | currBlock = n; |
HBP | 0:cbf45dde2b49 | 311 | blockPos = RB+20; // skip flags + pointers + filename |
HBP | 12:928346513c87 | 312 | byteCount = 0; // First byte of the file |
HBP | 0:cbf45dde2b49 | 313 | |
HBP | 0:cbf45dde2b49 | 314 | // Initialize buffer |
HBP | 0:cbf45dde2b49 | 315 | for (unsigned int i=0; i < BUF; i++) |
HBP | 0:cbf45dde2b49 | 316 | buffer[i] = '\0'; |
HBP | 0:cbf45dde2b49 | 317 | bufPos = 0; |
HBP | 0:cbf45dde2b49 | 318 | } |
HBP | 0:cbf45dde2b49 | 319 | |
HBP | 0:cbf45dde2b49 | 320 | file::~file() |
HBP | 0:cbf45dde2b49 | 321 | { |
HBP | 0:cbf45dde2b49 | 322 | flush(); |
HBP | 0:cbf45dde2b49 | 323 | } |
HBP | 0:cbf45dde2b49 | 324 | |
HBP | 12:928346513c87 | 325 | char file::getBlockLink(BlockLinkType linkSelection, uint32_t *blockOut) |
HBP | 12:928346513c87 | 326 | { |
HBP | 12:928346513c87 | 327 | char cData[1+BLOCK_LLEN]; |
HBP | 12:928346513c87 | 328 | |
HBP | 12:928346513c87 | 329 | if (linkSelection == NEXT) |
HBP | 12:928346513c87 | 330 | { |
HBP | 12:928346513c87 | 331 | // Fetch link to next block |
HBP | 12:928346513c87 | 332 | fs->read(cData, currBlock, 0, 1+BLOCK_LLEN); |
HBP | 12:928346513c87 | 333 | if ((cData[0] & 0x40) == 0) |
HBP | 12:928346513c87 | 334 | { |
HBP | 12:928346513c87 | 335 | *blockOut = ((uint32_t)(cData[1])) << 8; // Hbyte of next block link |
HBP | 12:928346513c87 | 336 | *blockOut |= (uint32_t)cData[2]; // Lbyte of next block link |
HBP | 12:928346513c87 | 337 | return 0; |
HBP | 12:928346513c87 | 338 | } else return 1; // Already at last block |
HBP | 12:928346513c87 | 339 | } else if (linkSelection == PREV) |
HBP | 12:928346513c87 | 340 | { |
HBP | 12:928346513c87 | 341 | if (currBlock != firstBlock) |
HBP | 12:928346513c87 | 342 | { |
HBP | 12:928346513c87 | 343 | fs->read(cData, currBlock, 1+BLOCK_LLEN, BLOCK_LLEN); |
HBP | 12:928346513c87 | 344 | *blockOut = ((uint32_t)(cData[0])) << 8; // Hbyte of next block link |
HBP | 12:928346513c87 | 345 | *blockOut |= (uint32_t)cData[1]; // Lbyte of next block link |
HBP | 12:928346513c87 | 346 | return 0; |
HBP | 12:928346513c87 | 347 | } else return 1; // Already at first block |
HBP | 12:928346513c87 | 348 | } |
HBP | 12:928346513c87 | 349 | |
HBP | 12:928346513c87 | 350 | return 0; |
HBP | 12:928346513c87 | 351 | } |
HBP | 12:928346513c87 | 352 | |
HBP | 12:928346513c87 | 353 | char file::removeFollowingBlocks(uint32_t block) |
HBP | 12:928346513c87 | 354 | { |
HBP | 12:928346513c87 | 355 | char cData[RB-BLOCK_LLEN]; |
HBP | 12:928346513c87 | 356 | char cDataNew[RB] = {'\x04', '\0', '\0', '\0', '\0'}; |
HBP | 12:928346513c87 | 357 | uint32_t i=0; |
HBP | 12:928346513c87 | 358 | |
HBP | 12:928346513c87 | 359 | while(1) |
HBP | 12:928346513c87 | 360 | { |
HBP | 12:928346513c87 | 361 | fs->read(cData, block, 0, RB-BLOCK_LLEN); |
HBP | 12:928346513c87 | 362 | fs->write(cDataNew, block, 0, RB); |
HBP | 12:928346513c87 | 363 | if ((cData[0] & 0x4C) == 0x4C) |
HBP | 12:928346513c87 | 364 | break; // End of file found |
HBP | 12:928346513c87 | 365 | else block = (uint32_t)(cData[0])<<8|cData[1]; // Set next block number |
HBP | 12:928346513c87 | 366 | i++; |
HBP | 12:928346513c87 | 367 | if (i > BC) |
HBP | 12:928346513c87 | 368 | return 1; // fs is corrupted |
HBP | 12:928346513c87 | 369 | } |
HBP | 12:928346513c87 | 370 | |
HBP | 12:928346513c87 | 371 | return 0; |
HBP | 12:928346513c87 | 372 | } |
HBP | 12:928346513c87 | 373 | |
HBP | 0:cbf45dde2b49 | 374 | void file::rewind() |
HBP | 0:cbf45dde2b49 | 375 | { |
HBP | 0:cbf45dde2b49 | 376 | flush(); |
HBP | 0:cbf45dde2b49 | 377 | currBlock = firstBlock; |
HBP | 0:cbf45dde2b49 | 378 | blockPos = RB+20; // skip flags & pointers + filename |
HBP | 12:928346513c87 | 379 | byteCount = 0; |
HBP | 0:cbf45dde2b49 | 380 | } |
HBP | 0:cbf45dde2b49 | 381 | |
HBP | 9:52c01cb100ac | 382 | char file::rewind(uint32_t n) |
HBP | 5:a0fe74dce80d | 383 | { |
HBP | 9:52c01cb100ac | 384 | uint32_t i; |
HBP | 12:928346513c87 | 385 | uint32_t block; |
HBP | 12:928346513c87 | 386 | uint32_t varBlockOffset; |
HBP | 5:a0fe74dce80d | 387 | |
HBP | 9:52c01cb100ac | 388 | flush(); // Check if flush is needed |
HBP | 5:a0fe74dce80d | 389 | |
HBP | 5:a0fe74dce80d | 390 | for (i=0; i < n; i++) |
HBP | 5:a0fe74dce80d | 391 | { |
HBP | 5:a0fe74dce80d | 392 | blockPos--; |
HBP | 12:928346513c87 | 393 | byteCount--; |
HBP | 5:a0fe74dce80d | 394 | |
HBP | 5:a0fe74dce80d | 395 | // Change Block? |
HBP | 12:928346513c87 | 396 | if (blockPos == firstBlock) |
HBP | 12:928346513c87 | 397 | varBlockOffset = RB+20; |
HBP | 12:928346513c87 | 398 | else |
HBP | 12:928346513c87 | 399 | varBlockOffset = RB; |
HBP | 12:928346513c87 | 400 | if ((blockPos < varBlockOffset) && (currBlock > firstBlock)) |
HBP | 5:a0fe74dce80d | 401 | { |
HBP | 12:928346513c87 | 402 | // Fetch link to previous block |
HBP | 12:928346513c87 | 403 | if(getBlockLink(PREV, &block) == 0) |
HBP | 5:a0fe74dce80d | 404 | { |
HBP | 12:928346513c87 | 405 | currBlock = block; |
HBP | 12:928346513c87 | 406 | blockPos = BS-1; // blockPos should be set at the end of block |
HBP | 5:a0fe74dce80d | 407 | } else { |
HBP | 5:a0fe74dce80d | 408 | blockPos++; |
HBP | 12:928346513c87 | 409 | byteCount++; |
HBP | 12:928346513c87 | 410 | return 1; // This is the first block and byte |
HBP | 5:a0fe74dce80d | 411 | } |
HBP | 5:a0fe74dce80d | 412 | } |
HBP | 5:a0fe74dce80d | 413 | } |
HBP | 5:a0fe74dce80d | 414 | |
HBP | 5:a0fe74dce80d | 415 | return 0; // OK |
HBP | 5:a0fe74dce80d | 416 | } |
HBP | 5:a0fe74dce80d | 417 | |
HBP | 0:cbf45dde2b49 | 418 | char file::forward() |
HBP | 0:cbf45dde2b49 | 419 | { |
HBP | 5:a0fe74dce80d | 420 | return forward(1); |
HBP | 5:a0fe74dce80d | 421 | } |
HBP | 5:a0fe74dce80d | 422 | |
HBP | 9:52c01cb100ac | 423 | char file::forward(uint32_t n) |
HBP | 5:a0fe74dce80d | 424 | { |
HBP | 9:52c01cb100ac | 425 | uint32_t i; |
HBP | 12:928346513c87 | 426 | uint32_t block; // Next block number |
HBP | 12:928346513c87 | 427 | char cData[1]; |
HBP | 0:cbf45dde2b49 | 428 | |
HBP | 9:52c01cb100ac | 429 | flush(); // Check if flush is needed |
HBP | 5:a0fe74dce80d | 430 | |
HBP | 5:a0fe74dce80d | 431 | for (i=0; i < n; i++) |
HBP | 5:a0fe74dce80d | 432 | { |
HBP | 13:142b6be3e3c8 | 433 | // If this is empty file EOF will be at first byte |
HBP | 13:142b6be3e3c8 | 434 | fs->read(cData, currBlock, blockPos, 1); |
HBP | 13:142b6be3e3c8 | 435 | if (cData[0] == mEOF) |
HBP | 13:142b6be3e3c8 | 436 | { |
HBP | 13:142b6be3e3c8 | 437 | return 1; |
HBP | 13:142b6be3e3c8 | 438 | } |
HBP | 13:142b6be3e3c8 | 439 | |
HBP | 5:a0fe74dce80d | 440 | blockPos++; |
HBP | 12:928346513c87 | 441 | byteCount++; |
HBP | 0:cbf45dde2b49 | 442 | |
HBP | 5:a0fe74dce80d | 443 | // Change Block? |
HBP | 12:928346513c87 | 444 | if (blockPos >= BS) |
HBP | 5:a0fe74dce80d | 445 | { |
HBP | 5:a0fe74dce80d | 446 | // Fetch link to next block |
HBP | 12:928346513c87 | 447 | if (getBlockLink(NEXT, &block) == 0) |
HBP | 5:a0fe74dce80d | 448 | { |
HBP | 12:928346513c87 | 449 | currBlock = block; |
HBP | 5:a0fe74dce80d | 450 | blockPos = RB; // Reset block position offset |
HBP | 5:a0fe74dce80d | 451 | } else { |
HBP | 5:a0fe74dce80d | 452 | blockPos--; |
HBP | 12:928346513c87 | 453 | byteCount--; |
HBP | 12:928346513c87 | 454 | return 1; // This is the last block & byte |
HBP | 5:a0fe74dce80d | 455 | } |
HBP | 5:a0fe74dce80d | 456 | } |
HBP | 5:a0fe74dce80d | 457 | fs->read(cData, currBlock, blockPos, 1); |
HBP | 5:a0fe74dce80d | 458 | if (cData[0] == mEOF) |
HBP | 10:211cb54339a0 | 459 | { |
HBP | 12:928346513c87 | 460 | rewind(1); // Get back to the byte before EOF |
HBP | 5:a0fe74dce80d | 461 | return 1; |
HBP | 10:211cb54339a0 | 462 | } |
HBP | 5:a0fe74dce80d | 463 | } |
HBP | 0:cbf45dde2b49 | 464 | |
HBP | 0:cbf45dde2b49 | 465 | return 0; // OK |
HBP | 0:cbf45dde2b49 | 466 | } |
HBP | 0:cbf45dde2b49 | 467 | |
HBP | 12:928346513c87 | 468 | char file::seek(uint32_t byte) |
HBP | 12:928346513c87 | 469 | { |
HBP | 12:928346513c87 | 470 | if (byte > byteCount) |
HBP | 12:928346513c87 | 471 | return forward(byte-byteCount); |
HBP | 12:928346513c87 | 472 | else if (byte < byteCount) |
HBP | 12:928346513c87 | 473 | return rewind(byteCount-byte); |
HBP | 12:928346513c87 | 474 | else return 0; |
HBP | 12:928346513c87 | 475 | } |
HBP | 12:928346513c87 | 476 | |
HBP | 0:cbf45dde2b49 | 477 | // Respects mEOF and automatically sets '\0' at the end of string |
HBP | 9:52c01cb100ac | 478 | void file::read(char *data, uint32_t n) |
HBP | 0:cbf45dde2b49 | 479 | { |
HBP | 9:52c01cb100ac | 480 | uint32_t i; |
HBP | 12:928346513c87 | 481 | uint32_t block; |
HBP | 12:928346513c87 | 482 | char cData[1]; |
HBP | 0:cbf45dde2b49 | 483 | |
HBP | 9:52c01cb100ac | 484 | flush(); |
HBP | 0:cbf45dde2b49 | 485 | |
HBP | 0:cbf45dde2b49 | 486 | for (i=0; i < n; i++) |
HBP | 0:cbf45dde2b49 | 487 | { |
HBP | 0:cbf45dde2b49 | 488 | // Change block? |
HBP | 12:928346513c87 | 489 | if (blockPos >= BS-1) |
HBP | 0:cbf45dde2b49 | 490 | { |
HBP | 0:cbf45dde2b49 | 491 | // Fetch link to next block |
HBP | 12:928346513c87 | 492 | if (getBlockLink(NEXT, &block) == 0) |
HBP | 0:cbf45dde2b49 | 493 | { |
HBP | 12:928346513c87 | 494 | currBlock = block; |
HBP | 12:928346513c87 | 495 | blockPos = RB; // Reset block position offset |
HBP | 0:cbf45dde2b49 | 496 | } else goto stop; |
HBP | 0:cbf45dde2b49 | 497 | } |
HBP | 0:cbf45dde2b49 | 498 | |
HBP | 0:cbf45dde2b49 | 499 | // Read data |
HBP | 0:cbf45dde2b49 | 500 | fs->read(cData, currBlock, blockPos, 1); |
HBP | 0:cbf45dde2b49 | 501 | if (cData[0] == mEOF) |
HBP | 0:cbf45dde2b49 | 502 | { |
HBP | 0:cbf45dde2b49 | 503 | stop: |
HBP | 0:cbf45dde2b49 | 504 | data[i]='\0'; |
HBP | 0:cbf45dde2b49 | 505 | return; |
HBP | 5:a0fe74dce80d | 506 | } else { |
HBP | 5:a0fe74dce80d | 507 | data[i] = cData[0]; |
HBP | 5:a0fe74dce80d | 508 | blockPos++; |
HBP | 12:928346513c87 | 509 | byteCount++; |
HBP | 5:a0fe74dce80d | 510 | } |
HBP | 0:cbf45dde2b49 | 511 | } |
HBP | 12:928346513c87 | 512 | if (data[n-1] != '\0') |
HBP | 12:928346513c87 | 513 | data[n-1] = '\0'; |
HBP | 0:cbf45dde2b49 | 514 | } |
HBP | 0:cbf45dde2b49 | 515 | |
HBP | 0:cbf45dde2b49 | 516 | // Ignores mEOF and doesn't set '\0' markings |
HBP | 9:52c01cb100ac | 517 | void file::readBin(char *data, uint32_t n) |
HBP | 0:cbf45dde2b49 | 518 | { |
HBP | 9:52c01cb100ac | 519 | uint32_t i; |
HBP | 12:928346513c87 | 520 | uint32_t block; |
HBP | 12:928346513c87 | 521 | char cData[1]; |
HBP | 0:cbf45dde2b49 | 522 | |
HBP | 0:cbf45dde2b49 | 523 | for (i=0; i < n; i++) |
HBP | 0:cbf45dde2b49 | 524 | { |
HBP | 0:cbf45dde2b49 | 525 | // Change block? |
HBP | 0:cbf45dde2b49 | 526 | if (blockPos == BS-1) |
HBP | 0:cbf45dde2b49 | 527 | { |
HBP | 0:cbf45dde2b49 | 528 | // Fetch link to next block |
HBP | 12:928346513c87 | 529 | if (getBlockLink(NEXT, &block) == 0) |
HBP | 0:cbf45dde2b49 | 530 | { |
HBP | 12:928346513c87 | 531 | currBlock = block; |
HBP | 0:cbf45dde2b49 | 532 | blockPos = RB; // Reset block position offset |
HBP | 0:cbf45dde2b49 | 533 | } else return; |
HBP | 0:cbf45dde2b49 | 534 | } |
HBP | 0:cbf45dde2b49 | 535 | |
HBP | 0:cbf45dde2b49 | 536 | // Read data |
HBP | 0:cbf45dde2b49 | 537 | fs->read(cData, currBlock, blockPos, 1); |
HBP | 0:cbf45dde2b49 | 538 | data[i] = cData[0]; |
HBP | 0:cbf45dde2b49 | 539 | |
HBP | 0:cbf45dde2b49 | 540 | blockPos++; |
HBP | 12:928346513c87 | 541 | byteCount++; |
HBP | 0:cbf45dde2b49 | 542 | } |
HBP | 0:cbf45dde2b49 | 543 | } |
HBP | 0:cbf45dde2b49 | 544 | |
HBP | 0:cbf45dde2b49 | 545 | // Always binary |
HBP | 9:52c01cb100ac | 546 | char file::write(char *data, uint32_t n) |
HBP | 0:cbf45dde2b49 | 547 | { |
HBP | 12:928346513c87 | 548 | if (fMode == RO) return 1; |
HBP | 0:cbf45dde2b49 | 549 | |
HBP | 9:52c01cb100ac | 550 | for (uint32_t i=0; i < n; i++) |
HBP | 0:cbf45dde2b49 | 551 | { |
HBP | 0:cbf45dde2b49 | 552 | // write to the buffer |
HBP | 0:cbf45dde2b49 | 553 | buffer[bufPos] = data[i]; |
HBP | 0:cbf45dde2b49 | 554 | bufPos++; |
HBP | 0:cbf45dde2b49 | 555 | |
HBP | 0:cbf45dde2b49 | 556 | // If the buffer is full then flush |
HBP | 0:cbf45dde2b49 | 557 | if(bufPos == BUF) |
HBP | 0:cbf45dde2b49 | 558 | { |
HBP | 0:cbf45dde2b49 | 559 | if(flush() != 0); |
HBP | 0:cbf45dde2b49 | 560 | return 1; // Flush failed |
HBP | 0:cbf45dde2b49 | 561 | } |
HBP | 0:cbf45dde2b49 | 562 | } |
HBP | 0:cbf45dde2b49 | 563 | |
HBP | 0:cbf45dde2b49 | 564 | return 0; |
HBP | 0:cbf45dde2b49 | 565 | } |
HBP | 0:cbf45dde2b49 | 566 | |
HBP | 0:cbf45dde2b49 | 567 | char file::flush() |
HBP | 0:cbf45dde2b49 | 568 | { |
HBP | 12:928346513c87 | 569 | char cData[RB], cDataOB[RB-BLOCK_LLEN], c[1]; |
HBP | 10:211cb54339a0 | 570 | uint32_t nextFree; |
HBP | 9:52c01cb100ac | 571 | uint32_t i; |
HBP | 12:928346513c87 | 572 | uint32_t leftSpaceEOF; |
HBP | 12:928346513c87 | 573 | |
HBP | 12:928346513c87 | 574 | bool destructiveFlag = false; // Set this true if there is any data to be removed |
HBP | 12:928346513c87 | 575 | uint32_t destructiveBlock=0; // First block to be removed by DWRITE |
HBP | 0:cbf45dde2b49 | 576 | |
HBP | 13:142b6be3e3c8 | 577 | static bool fEOFow = false; /* END of file found while appending (and overwritten). |
HBP | 13:142b6be3e3c8 | 578 | Must be static because we don't want to found many EOF's. */ |
HBP | 13:142b6be3e3c8 | 579 | |
HBP | 13:142b6be3e3c8 | 580 | |
HBP | 0:cbf45dde2b49 | 581 | if (bufPos == 0) return 0; // File up-to date |
HBP | 12:928346513c87 | 582 | if (fMode == RO) return 1; |
HBP | 0:cbf45dde2b49 | 583 | |
HBP | 12:928346513c87 | 584 | for (i=0; i <= bufPos; i++) |
HBP | 0:cbf45dde2b49 | 585 | { |
HBP | 0:cbf45dde2b49 | 586 | if(i%2) |
HBP | 0:cbf45dde2b49 | 587 | FlushLed = 1; |
HBP | 0:cbf45dde2b49 | 588 | else |
HBP | 0:cbf45dde2b49 | 589 | FlushLed = 0; |
HBP | 0:cbf45dde2b49 | 590 | |
HBP | 0:cbf45dde2b49 | 591 | // Change Block? |
HBP | 12:928346513c87 | 592 | if ((bufPos - i) == 1) |
HBP | 12:928346513c87 | 593 | leftSpaceEOF = 1; |
HBP | 12:928346513c87 | 594 | else |
HBP | 12:928346513c87 | 595 | leftSpaceEOF = 0; |
HBP | 12:928346513c87 | 596 | if (blockPos >= BS-leftSpaceEOF) |
HBP | 0:cbf45dde2b49 | 597 | { |
HBP | 0:cbf45dde2b49 | 598 | // Fetch new unused block number |
HBP | 0:cbf45dde2b49 | 599 | if(fs->getNextFreeBlock(&nextFree) != 0) |
HBP | 12:928346513c87 | 600 | return 2; // No free space left |
HBP | 0:cbf45dde2b49 | 601 | |
HBP | 12:928346513c87 | 602 | // Read flags from current block |
HBP | 12:928346513c87 | 603 | fs->read(cDataOB, currBlock, 0, RB-BLOCK_LLEN); |
HBP | 9:52c01cb100ac | 604 | |
HBP | 12:928346513c87 | 605 | /* If destructive write is set then check if there is something |
HBP | 12:928346513c87 | 606 | to be marked for removal */ |
HBP | 12:928346513c87 | 607 | if (((cDataOB[0] & 0x40) != 0x40) && (fMode == DWRITE)) |
HBP | 12:928346513c87 | 608 | { |
HBP | 12:928346513c87 | 609 | destructiveFlag = true; |
HBP | 12:928346513c87 | 610 | destructiveBlock = (uint32_t)cDataOB[1]<<8|cDataOB[2]; |
HBP | 12:928346513c87 | 611 | goto allocate_new_block; |
HBP | 12:928346513c87 | 612 | } else if ((cDataOB[0] & 0x40) != 0x40) // fMode == AWRITE |
HBP | 12:928346513c87 | 613 | { |
HBP | 12:928346513c87 | 614 | // Update current block info |
HBP | 12:928346513c87 | 615 | currBlock = (uint32_t)cDataOB[1]<<8|cDataOB[2]; |
HBP | 12:928346513c87 | 616 | blockPos = RB; // Reset block position offset |
HBP | 12:928346513c87 | 617 | } else // There is no block to append so we allocate a new one |
HBP | 12:928346513c87 | 618 | { |
HBP | 12:928346513c87 | 619 | allocate_new_block: |
HBP | 12:928346513c87 | 620 | // Allocate new block for use |
HBP | 12:928346513c87 | 621 | cData[0] = 0x4C; // New flags |
HBP | 12:928346513c87 | 622 | cData[1] = '\0'; // Hbyte of Next Block link |
HBP | 12:928346513c87 | 623 | cData[2] = '\0'; // Lbyte of Next Block link |
HBP | 12:928346513c87 | 624 | cData[3] = (char)((currBlock & 0xff00) >> 8); // Hbyte of Prev Block link |
HBP | 12:928346513c87 | 625 | cData[4] = (char)(currBlock & 0x00ff); // Lbyte of Prev Block link |
HBP | 12:928346513c87 | 626 | fs->write(cData, nextFree, 0, RB); // Update Block Data |
HBP | 0:cbf45dde2b49 | 627 | |
HBP | 12:928346513c87 | 628 | // Link old block with new block |
HBP | 12:928346513c87 | 629 | cDataOB[0] &= ~0x40; // Clear LBOF flag if set |
HBP | 12:928346513c87 | 630 | cDataOB[1] = (char)((nextFree & 0xff00) >> 8); // Hbyte of Next Block link |
HBP | 12:928346513c87 | 631 | cDataOB[2] = (char)(nextFree & 0x00ff); // Lbyte of Next Block link |
HBP | 12:928346513c87 | 632 | fs->write(cDataOB, currBlock, 0, RB-BLOCK_LLEN); // Update Block Data |
HBP | 9:52c01cb100ac | 633 | |
HBP | 12:928346513c87 | 634 | // Update current block info |
HBP | 12:928346513c87 | 635 | currBlock = nextFree; |
HBP | 12:928346513c87 | 636 | blockPos = RB; // Reset block position offset |
HBP | 12:928346513c87 | 637 | } |
HBP | 0:cbf45dde2b49 | 638 | } |
HBP | 0:cbf45dde2b49 | 639 | |
HBP | 13:142b6be3e3c8 | 640 | if (fMode == AWRITE) // Check if EOF is here |
HBP | 13:142b6be3e3c8 | 641 | { |
HBP | 13:142b6be3e3c8 | 642 | fs->read(c, currBlock, blockPos, 1); |
HBP | 13:142b6be3e3c8 | 643 | if ((c[0] == mEOF) && (fEOFow == false)) |
HBP | 13:142b6be3e3c8 | 644 | fEOFow = true; |
HBP | 13:142b6be3e3c8 | 645 | } |
HBP | 13:142b6be3e3c8 | 646 | |
HBP | 0:cbf45dde2b49 | 647 | // Write file |
HBP | 0:cbf45dde2b49 | 648 | c[0]=buffer[i]; |
HBP | 0:cbf45dde2b49 | 649 | fs->write(c, currBlock, blockPos, 1); |
HBP | 0:cbf45dde2b49 | 650 | blockPos++; |
HBP | 12:928346513c87 | 651 | byteCount++; |
HBP | 13:142b6be3e3c8 | 652 | |
HBP | 13:142b6be3e3c8 | 653 | // For fail safe, write EOF now |
HBP | 13:142b6be3e3c8 | 654 | if ((fMode == DWRITE)||(fEOFow == true)) |
HBP | 13:142b6be3e3c8 | 655 | fs->write((char[]){mEOF}, currBlock, blockPos, 1); // Write mEOF |
HBP | 0:cbf45dde2b49 | 656 | } |
HBP | 0:cbf45dde2b49 | 657 | |
HBP | 0:cbf45dde2b49 | 658 | bufPos = 0; // Reset buffer position counter |
HBP | 0:cbf45dde2b49 | 659 | |
HBP | 12:928346513c87 | 660 | /* If destructive write flag is set |
HBP | 12:928346513c87 | 661 | and there is data to be removed then remove data now */ |
HBP | 12:928346513c87 | 662 | if (destructiveFlag == true) |
HBP | 12:928346513c87 | 663 | if(removeFollowingBlocks(destructiveBlock) != 0) |
HBP | 12:928346513c87 | 664 | return 3; |
HBP | 12:928346513c87 | 665 | |
HBP | 0:cbf45dde2b49 | 666 | FlushLed = 0; |
HBP | 0:cbf45dde2b49 | 667 | return 0; |
HBP | 0:cbf45dde2b49 | 668 | } |