pic32/libraries/SD/utility/SdFile.cpp
//------------------------------------------------------------------------------
/**
 * Open a file or directory by name.
 *
 * \param[in] dirFile An open SdFat instance for the directory containing the
 * file to be opened.
 *
 * \param[in] fileName A valid 8.3 DOS name for a file to be opened.
 *
 * \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
 * OR of flags from the following list
 *
 * O_READ - Open for reading.
 *
 * O_RDONLY - Same as O_READ.
 *
 * O_WRITE - Open for writing.
 *
 * O_WRONLY - Same as O_WRITE.
 *
 * O_RDWR - Open for reading and writing.
 *
 * O_APPEND - If set, the file offset shall be set to the end of the
 * file prior to each write.
 *
 * O_CREAT - If the file exists, this flag has no effect except as noted
 * under O_EXCL below. Otherwise, the file shall be created
 *
 * O_EXCL - If O_CREAT and O_EXCL are set, open() shall fail if the file exists.
 *
 * O_SYNC - Call sync() after each write.  This flag should not be used with
 * write(uint8_t), write_P(PGM_P), writeln_P(PGM_P), or the Arduino Print class.
 * These functions do character at a time writes so sync() will be called
 * after each byte.
 *
 * O_TRUNC - If the file exists and is a regular file, and the file is
 * successfully opened and is not read only, its length shall be truncated to 0.
 *
 * \note Directory files must be opened read only.  Write and truncation is
 * not allowed for directory files.
 *
 * \return The value one, true, is returned for success and
 * the value zero, false, is returned for failure.
 * Reasons for failure include this SdFile is already open, \a difFile is not
 * a directory, \a fileName is invalid, the file does not exist
 * or can't be opened in the access mode specified by oflag.
 */
Open a file or directory by name.
\param[in] dirFile An open SdFat instance for the directory containing the
file to be opened.

\param[in] fileName A valid 8.3 DOS name for a file to be opened.

\param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
OR of flags from the following list

Open for reading.



Open for writing.



Open for reading and writing.

If set, the file offset shall be set to the end of the
file prior to each write.

If the file exists, this flag has no effect except as noted
under O_EXCL below. Otherwise, the file shall be created

If O_CREAT and O_EXCL are set, open() shall fail if the file exists.

Call sync() after each write.

If the file exists and is a regular file, and the file is
successfully opened and is not read only, its length shall be truncated to 0.

\note Directory files must be opened read only.  Write and truncation is
not allowed for directory files.

\return The value one, true, is returned for success and
the value zero, false, is returned for failure.
Reasons for failure include this SdFile is already open, \a difFile is not
a directory, \a fileName is invalid, the file does not exist
or can't be opened in the access mode specified by oflag.
Open a file or directory by name . \ param [ in ] dirFile An open SdFat instance for the directory containing the file to be opened . \ param [ in ] fileName A valid 8 . 3 DOS name for a file to be opened . \ param [ in ] oflag Values for \ a oflag are constructed by a bitwise - inclusive OR of flags from the following list Open for reading . Open for writing . Open for reading and writing . If set the file offset shall be set to the end of the file prior to each write . If the file exists this flag has no effect except as noted under O_EXCL below . Otherwise the file shall be created If O_CREAT and O_EXCL are set open () shall fail if the file exists . Call sync () after each write . If the file exists and is a regular file and the file is successfully opened and is not read only its length shall be truncated to 0 . \ note Directory files must be opened read only . Write and truncation is not allowed for directory files . \ return The value one true is returned for success and the value zero false is returned for failure . Reasons for failure include this SdFile is already open \ a difFile is not a directory \ a fileName is invalid the file does not exist or can ' t be opened in the access mode specified by oflag .
uint8_t SdFile::open(SdFile* dirFile, const char* fileName, uint8_t oflag) {
  uint8_t dname[11];
  dir_t* p;
  if (isOpen())return false;
  if (!make83Name(fileName, dname)) return false;
  vol_ = dirFile->vol_;
  dirFile->rewind();
  uint8_t emptyFound = false;
  while (dirFile->curPosition_ < dirFile->fileSize_) {
    uint8_t index = 0XF & (dirFile->curPosition_ >> 5);
    p = dirFile->readDirCache();
    if (p == NULL) return false;
    if (p->name[0] == DIR_NAME_FREE || p->name[0] == DIR_NAME_DELETED) {
      if (!emptyFound) {
        emptyFound = true;
        dirIndex_ = index;
        dirBlock_ = SdVolume::cacheBlockNumber_;
      }
      if (p->name[0] == DIR_NAME_FREE) break;
    } else if (!memcmp(dname, p->name, 11)) {
      if ((oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) return false;
      return openCachedEntry(0XF & index, oflag);
    }
  }
  if ((oflag & (O_CREAT | O_WRITE)) != (O_CREAT | O_WRITE)) return false;
  if (emptyFound) {
    p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
    if (!p) return false;
  } else {
    if (dirFile->type_ == FAT_FILE_TYPE_ROOT16) return false;
    if (!dirFile->addDirCluster()) return false;
    dirIndex_ = 0;
    p = SdVolume::cacheBuffer_.dir;
  }
  memset(p, 0, sizeof(dir_t));
  memcpy(p->name, dname, 11);
  if (dateTime_) {
    dateTime_(&p->creationDate, &p->creationTime);
  } else {
    p->creationDate = FAT_DEFAULT_DATE;
    p->creationTime = FAT_DEFAULT_TIME;
  }
  p->lastAccessDate = p->creationDate;
  p->lastWriteDate = p->creationDate;
  p->lastWriteTime = p->creationTime;
  if (!SdVolume::cacheFlush()) return false;
  return openCachedEntry(dirIndex_, oflag);
}
uint8_t SdFile :: open ( SdFile * dirFile , const char * fileName , uint8_t oflag ) { uint8_t dname [ 11 ] ; dir_t * p ; if ( isOpen ( ) ) return false ; if ( ! make83Name ( fileName , dname ) ) return false ; vol_ = dirFile -> vol_ ; dirFile -> rewind ( ) ; uint8_t emptyFound = false ; while ( dirFile -> curPosition_ < dirFile -> fileSize_ ) { uint8_t index = 0 XF & ( dirFile -> curPosition_ >> 5 ) ; p = dirFile -> readDirCache ( ) ; if ( p == NULL ) return false ; if ( p -> name [ 0 ] == DIR_NAME_FREE || p -> name [ 0 ] == DIR_NAME_DELETED ) { if ( ! emptyFound ) { emptyFound = true ; dirIndex_ = index ; dirBlock_ = SdVolume :: cacheBlockNumber_ ; } if ( p -> name [ 0 ] == DIR_NAME_FREE ) break ; } else if ( ! memcmp ( dname , p -> name , 11 ) ) { if ( ( oflag & ( O_CREAT | O_EXCL ) ) == ( O_CREAT | O_EXCL ) ) return false ; return openCachedEntry ( 0 XF & index , oflag ) ; } } if ( ( oflag & ( O_CREAT | O_WRITE ) ) != ( O_CREAT | O_WRITE ) ) return false ; if ( emptyFound ) { p = cacheDirEntry ( SdVolume :: CACHE_FOR_WRITE ) ; if ( ! p ) return false ; } else { if ( dirFile -> type_ == FAT_FILE_TYPE_ROOT16 ) return false ; if ( ! dirFile -> addDirCluster ( ) ) return false ; dirIndex_ = 0 ; p = SdVolume :: cacheBuffer_ . dir ; } memset ( p , 0 , sizeof ( dir_t ) ) ; memcpy ( p -> name , dname , 11 ) ; if ( dateTime_ ) { dateTime_ ( & p -> creationDate , & p -> creationTime ) ; } else { p -> creationDate = FAT_DEFAULT_DATE ; p -> creationTime = FAT_DEFAULT_TIME ; } p -> lastAccessDate = p -> creationDate ; p -> lastWriteDate = p -> creationDate ; p -> lastWriteTime = p -> creationTime ; if ( ! SdVolume :: cacheFlush ( ) ) return false ; return openCachedEntry ( dirIndex_ , oflag ) ; }
Open a file or directory by name.
Open a file or directory by name .
// error if already open // bool for empty entry found // search for file // remember first empty slot // done if no entries follow // don't open existing file if O_CREAT and O_EXCL // open found file // only create file if O_CREAT and O_WRITE // cache found slot or add cluster if end of file // add and zero cluster for dirFile - first cluster is in cache for write // use first entry in cluster // initialize as empty file // set timestamps // call user function // use default date/time // force write of entry to SD // open entry in cache