void SDCard::ls() { SdBaseFile file; Com::printFLN(Com::tBeginFileList); fat.chdir(); file.openRoot(fat.vol()); file.ls(0, 0); Com::printFLN(Com::tEndFileList); }
/** Change a volume's working directory * * Changes the volume working directory to the \a path subdirectory. * Optionally set the current working directory to the volume's * working directory. * * Example: If the volume's working directory is "/DIR", chdir("SUB") * will change the volume's working directory from "/DIR" to "/DIR/SUB". * * If path is "/", the volume's working directory will be changed to the * root directory * * \param[in] path The name of the subdirectory. * * \param[in] set_cwd Set the current working directory to this volume's * working directory if true. * * \return The value one, true, is returned for success and * the value zero, false, is returned for failure. */ bool SdFat::chdir(const char *path, bool set_cwd) { SdBaseFile dir; if (path[0] == '/' && path[1] == '\0') return chdir(set_cwd); if (!dir.open(&m_vwd, path, O_READ)) goto fail; if (!dir.isDir()) goto fail; m_vwd = dir; if (set_cwd) SdBaseFile::setCwd(&m_vwd); return true; fail: return false; }
/** * Dive into a folder and recurse depth-first to perform a pre-set operation lsAction: * LS_Count - Add +1 to nrFiles for every file within the parent * LS_GetFilename - Get the filename of the file indexed by nrFiles */ void CardReader::lsDive(SdBaseFile parent, const char* const match/*=NULL*/) { dir_t* p; uint8_t cnt = 0; // Read the next entry from a directory while ((p = parent.getLongFilename(p, fullName, 0, NULL)) != NULL) { char pn0 = p->name[0]; if (pn0 == DIR_NAME_FREE) break; if (pn0 == DIR_NAME_DELETED || pn0 == '.') continue; if (fullName[0] == '.') continue; if (!DIR_IS_FILE_OR_SUBDIR(p)) continue; filenameIsDir = DIR_IS_SUBDIR(p); if (!filenameIsDir && (p->name[8] != 'G' || p->name[9] == '~')) continue; switch (lsAction) { case LS_Count: nrFiles++; break; case LS_GetFilename: if (match != NULL) { if (strcasecmp(match, fullName) == 0) return; } else if (cnt == nrFiles) return; cnt++; break; } } // while readDir }
void CardReader::chdir(const char* relpath) { SdBaseFile newfile; SdBaseFile* parent = &root; if (workDir.isOpen()) parent = &workDir; if (!newfile.open(parent, relpath, O_READ)) { ECHO_LMT(DB, SERIAL_SD_CANT_ENTER_SUBDIR, relpath); } else { if (workDirDepth < SD_MAX_FOLDER_DEPTH) { ++workDirDepth; for (int d = workDirDepth; d--;) workDirParents[d + 1] = workDirParents[d]; workDirParents[0] = *parent; } workDir = newfile; } }
//int8_t IniFile::readLine(SdBaseFile &file, char *buffer, size_t len, uint32_t &pos) IniFile::error_t IniFile::readLine(SdBaseFile &file, char *buffer, size_t len, uint32_t &pos) { if (!file.isOpen()) return errorFileNotOpen; if (len < 3) return errorBufferTooSmall; if (!file.seekSet(pos)) return errorSeekError; size_t bytesRead = file.read(buffer, len); if (!bytesRead) { buffer[0] = '\0'; //return 1; // done return errorEndOfFile; } for (size_t i = 0; i < bytesRead && i < len-1; ++i) { // Test for '\n' with optional '\r' too // if (endOfLineTest(buffer, len, i, '\n', '\r') if (buffer[i] == '\n' || buffer[i] == '\r') { char match = buffer[i]; char otherNewline = (match == '\n' ? '\r' : '\n'); // end of line, discard any trailing character of the other sort // of newline buffer[i] = '\0'; if (buffer[i+1] == otherNewline) ++i; pos += (i + 1); // skip past newline(s) //return (i+1 == bytesRead && !file.available()); return errorNoError; } } if (!file.available()) { // end of file without a newline buffer[bytesRead] = '\0'; // return 1; //done return errorEndOfFile; } buffer[len-1] = '\0'; // terminate the string return errorBufferTooSmall; }
void CardReader::parsejson(SdBaseFile &file) { fileSize = file.fileSize(); filamentNeeded = 0.0; objectHeight = 0.0; firstlayerHeight = 0.0; layerHeight = 0.0; if (!file.isOpen()) return; bool genByFound = false, firstlayerHeightFound = false, layerHeightFound = false, filamentNeedFound = false; #if CPU_ARCH==ARCH_AVR #define GCI_BUF_SIZE 120 #else #define GCI_BUF_SIZE 1024 #endif // READ 4KB FROM THE BEGINNING char buf[GCI_BUF_SIZE]; for (int i = 0; i < 4096; i += GCI_BUF_SIZE - 50) { if(!file.seekSet(i)) break; file.read(buf, GCI_BUF_SIZE); if (!genByFound && findGeneratedBy(buf, generatedBy)) genByFound = true; if (!firstlayerHeightFound && findFirstLayerHeight(buf, firstlayerHeight)) firstlayerHeightFound = true; if (!layerHeightFound && findLayerHeight(buf, layerHeight)) layerHeightFound = true; if (!filamentNeedFound && findFilamentNeed(buf, filamentNeeded)) filamentNeedFound = true; if(genByFound && layerHeightFound && filamentNeedFound) goto get_objectHeight; } // READ 4KB FROM END for (int i = 0; i < 4096; i += GCI_BUF_SIZE - 50) { if(!file.seekEnd(-4096 + i)) break; file.read(buf, GCI_BUF_SIZE); if (!genByFound && findGeneratedBy(buf, generatedBy)) genByFound = true; if (!firstlayerHeightFound && findFirstLayerHeight(buf, firstlayerHeight)) firstlayerHeightFound = true; if (!layerHeightFound && findLayerHeight(buf, layerHeight)) layerHeightFound = true; if (!filamentNeedFound && findFilamentNeed(buf, filamentNeeded)) filamentNeedFound = true; if(genByFound && layerHeightFound && filamentNeedFound) goto get_objectHeight; } get_objectHeight: // MOVE FROM END UP IN 1KB BLOCKS UP TO 30KB for (int i = GCI_BUF_SIZE; i < 30000; i += GCI_BUF_SIZE - 50) { if(!file.seekEnd(-i)) break; file.read(buf, GCI_BUF_SIZE); if (findTotalHeight(buf, objectHeight)) break; } file.seekSet(0); }
void SDCard::JSONFileInfo(const char* filename) { SdBaseFile targetFile; GCodeFileInfo *info,tmpInfo; if (strlen(filename) == 0) { targetFile = file; info = &fileInfo; } else { if (!targetFile.open(fat.vwd(), filename, O_READ) || targetFile.isDir()) { Com::printF(Com::tJSONErrorStart); Com::printF(Com::tFileOpenFailed); Com::printFLN(Com::tJSONErrorEnd); return; } info = &tmpInfo; info->init(targetFile); } if (!targetFile.isOpen()) { Com::printF(Com::tJSONErrorStart); Com::printF(Com::tNotSDPrinting); Com::printFLN(Com::tJSONErrorEnd); return; } // {"err":0,"size":457574,"height":4.00,"layerHeight":0.25,"filament":[6556.3],"generatedBy":"Slic3r 1.1.7 on 2014-11-09 at 17:11:32"} Com::printF(Com::tJSONFileInfoStart); Com::print(info->fileSize); Com::printF(Com::tJSONFileInfoHeight); Com::print(info->objectHeight); Com::printF(Com::tJSONFileInfoLayerHeight); Com::print(info->layerHeight); Com::printF(Com::tJSONFileInfoFilament); Com::print(info->filamentNeeded); Com::printF(Com::tJSONFileInfoGeneratedBy); Com::print(info->generatedBy); Com::print('"'); if (strlen(filename) == 0) { Com::printF(Com::tJSONFileInfoName); file.printName(); Com::print('"'); } Com::print('}'); Com::println(); };
void SDCard::lsJSON(const char *filename) { SdBaseFile dir; fat.chdir(); if (*filename == 0) { dir.openRoot(fat.vol()); } else { if (!dir.open(fat.vwd(), filename, O_READ) || !dir.isDir()) { Com::printF(Com::tJSONErrorStart); Com::printF(Com::tFileOpenFailed); Com::printFLN(Com::tJSONErrorEnd); return; } } Com::printF(Com::tJSONDir); SDCard::printEscapeChars(filename); Com::printF(Com::tJSONFiles); dir.lsJSON(); Com::printFLN(Com::tJSONArrayEnd); }
/** Truncate a file to a specified length. The current file position * will be maintained if it is less than or equal to \a length otherwise * it will be set to end of file. * * \param[in] path A path with a valid 8.3 DOS name for the file. * \param[in] length The desired length for the file. * * \return The value one, true, is returned for success and * the value zero, false, is returned for failure. * Reasons for failure include file is read only, file is a directory, * \a length is greater than the current file size or an I/O error occurs. */ bool SdFat::truncate(const char* path, uint32_t length) { SdBaseFile file; if (!file.open(path, O_WRITE)) return false; return file.truncate(length); }
/** Remove a subdirectory from the volume's working directory. * * \param[in] path A path with a valid 8.3 DOS name for the subdirectory. * * The subdirectory file will be removed only if it is empty. * * \return The value one, true, is returned for success and * the value zero, false, is returned for failure. */ bool SdFat::rmdir(const char* path) { SdBaseFile sub; if (!sub.open(path, O_READ)) return false; return sub.rmdir(); }
/** Rename a file or subdirectory. * * \param[in] oldPath Path name to the file or subdirectory to be renamed. * * \param[in] newPath New path name of the file or subdirectory. * * The \a newPath object must not exist before the rename call. * * The file to be renamed must not be open. The directory entry may be * moved and file system corruption could occur if the file is accessed by * a file object that was opened before the rename() call. * * \return The value one, true, is returned for success and * the value zero, false, is returned for failure. */ bool SdFat::rename(const char *oldPath, const char *newPath) { SdBaseFile file; if (!file.open(oldPath, O_READ)) return false; return file.rename(&m_vwd, newPath); }
/** Make a subdirectory in the volume working directory. * * \param[in] path A path with a valid 8.3 DOS name for the subdirectory. * * \param[in] pFlag Create missing parent directories if true. * * \return The value one, true, is returned for success and * the value zero, false, is returned for failure. */ bool SdFat::mkdir(const char* path, bool pFlag) { SdBaseFile sub; return sub.mkdir(&m_vwd, path, pFlag); }
void startBinLogger(void (*dateTime)(uint16_t *date, uint16_t *time)){ #ifdef LOGGER_DEBUG Serial.print("Size of Struct: "); Serial.println(sizeof(salus_data_t)); Serial.print("Data_DIM: "); Serial.println(DATA_DIM); Serial.print("FILL_DIM: "); Serial.println(FILL_DIM); Serial.print("Sizeof Block: "); Serial.println(sizeof(block_t)); Serial.println(); #endif if (!sd.begin(SD_CHIPSELECT, SD_SPI_SPEED)) { sd.initErrorHalt(); } int number = 0; char sName[80]; // Find a filename that hasn't been used already do { sprintf(sName, "Salus_Results_%d.bin", number++); } while (sd.exists(sName)); binFile.close(); binFile.dateTimeCallback(dateTime); if (!binFile.createContiguous(sd.vwd(), sName, 512 * FILE_BLOCK_COUNT)){ error("createContiguous failed"); } if (!binFile.contiguousRange(&bgnBlock, &endBlock)){ error("contiguousRange failed"); } // Use SdFat's internal buffer ( ???? ) uint8_t* cache = (uint8_t*)sd.vol()->cacheClear(); if (cache == 0) { error("cacheClear failed"); } binFile.dateTimeCallbackCancel(); uint32_t bgnErase = bgnBlock; uint32_t endErase; while (bgnErase < endBlock) { endErase = bgnErase + ERASE_SIZE; if (endErase > endBlock) { endErase = endBlock; } if (!sd.card()->erase(bgnErase, endErase)) { error("erase failed"); } bgnErase = endErase + 1; } // Start a multiple block write. if (!sd.card()->writeStart(bgnBlock, FILE_BLOCK_COUNT)) { error("writeBegin failed"); } }