pic32/libraries/SD/utility/SdFile.cpp
//------------------------------------------------------------------------------
/**
 * Write data to an open file.
 *
 * \note Data is moved to the cache but may not be written to the
 * storage device until sync() is called.
 *
 * \param[in] buf Pointer to the location of the data to be written.
 *
 * \param[in] nbyte Number of bytes to write.
 *
 * \return For success write() returns the number of bytes written, always
 * \a nbyte.  If an error occurs, write() returns -1.  Possible errors
 * include write() is called before a file has been opened, write is called
 * for a read-only file, device is full, a corrupt file system or an I/O error.
 *
 */
Write data to an open file.
\note Data is moved to the cache but may not be written to the
storage device until sync() is called.

\param[in] buf Pointer to the location of the data to be written.

\param[in] nbyte Number of bytes to write.

\return For success write() returns the number of bytes written, always
\a nbyte.  If an error occurs, write() returns -1.  Possible errors
include write() is called before a file has been opened, write is called
for a read-only file, device is full, a corrupt file system or an I/O error.
Write data to an open file . \ note Data is moved to the cache but may not be written to the storage device until sync () is called . \ param [ in ] buf Pointer to the location of the data to be written . \ param [ in ] nbyte Number of bytes to write . \ return For success write () returns the number of bytes written always \ a nbyte . If an error occurs write () returns - 1 . Possible errors include write () is called before a file has been opened write is called for a read - only file device is full a corrupt file system or an I / O error .
size_t SdFile::write(const void* buf, uint16_t nbyte) {
  const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
  uint16_t nToWrite = nbyte;
  if (!isFile() || !(flags_ & O_WRITE)) goto writeErrorReturn;
  if ((flags_ & O_APPEND) && curPosition_ != fileSize_) {
    if (!seekEnd()) goto writeErrorReturn;
  }
  while (nToWrite > 0) {
    uint8_t blockOfCluster = vol_->blockOfCluster(curPosition_);
    uint16_t blockOffset = curPosition_ & 0X1FF;
    if (blockOfCluster == 0 && blockOffset == 0) {
      if (curCluster_ == 0) {
        if (firstCluster_ == 0) {
          if (!addCluster()) goto writeErrorReturn;
        } else {
          curCluster_ = firstCluster_;
        }
      } else {
        uint32_t next;
        if (!vol_->fatGet(curCluster_, &next)) return false;
        if (vol_->isEOC(next)) {
          if (!addCluster()) goto writeErrorReturn;
        } else {
          curCluster_ = next;
        }
      }
    }
    uint16_t n = 512 - blockOffset;
    if (n > nToWrite) n = nToWrite;
    uint32_t block = vol_->clusterStartBlock(curCluster_) + blockOfCluster;
    if (n == 512) {
      if (SdVolume::cacheBlockNumber_ == block) {
        SdVolume::cacheBlockNumber_ = 0XFFFFFFFF;
      }
      if (!vol_->writeBlock(block, src)) goto writeErrorReturn;
      src += 512;
    } else {
      if (blockOffset == 0 && curPosition_ >= fileSize_) {
        if (!SdVolume::cacheFlush()) goto writeErrorReturn;
        SdVolume::cacheBlockNumber_ = block;
        SdVolume::cacheSetDirty();
      } else {
        if (!SdVolume::cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) {
          goto writeErrorReturn;
        }
      }
      uint8_t* dst = SdVolume::cacheBuffer_.data + blockOffset;
      uint8_t* end = dst + n;
      while (dst != end) *dst++ = *src++;
    }
    nToWrite -= n;
    curPosition_ += n;
  }
  if (curPosition_ > fileSize_) {
    fileSize_ = curPosition_;
    flags_ |= F_FILE_DIR_DIRTY;
  } else if (dateTime_ && nbyte) {
    flags_ |= F_FILE_DIR_DIRTY;
  }
  if (flags_ & O_SYNC) {
    if (!sync()) goto writeErrorReturn;
  }
  return nbyte;
 writeErrorReturn:
  return 0;
}
size_t SdFile :: write ( const void * buf , uint16_t nbyte ) { const uint8_t * src = reinterpret_cast < const uint8_t * > ( buf ) ; uint16_t nToWrite = nbyte ; if ( ! isFile ( ) || ! ( flags_ & O_WRITE ) ) goto writeErrorReturn ; if ( ( flags_ & O_APPEND ) && curPosition_ != fileSize_ ) { if ( ! seekEnd ( ) ) goto writeErrorReturn ; } while ( nToWrite > 0 ) { uint8_t blockOfCluster = vol_ -> blockOfCluster ( curPosition_ ) ; uint16_t blockOffset = curPosition_ & 0 X1FF ; if ( blockOfCluster == 0 && blockOffset == 0 ) { if ( curCluster_ == 0 ) { if ( firstCluster_ == 0 ) { if ( ! addCluster ( ) ) goto writeErrorReturn ; } else { curCluster_ = firstCluster_ ; } } else { uint32_t next ; if ( ! vol_ -> fatGet ( curCluster_ , & next ) ) return false ; if ( vol_ -> isEOC ( next ) ) { if ( ! addCluster ( ) ) goto writeErrorReturn ; } else { curCluster_ = next ; } } } uint16_t n = 512 - blockOffset ; if ( n > nToWrite ) n = nToWrite ; uint32_t block = vol_ -> clusterStartBlock ( curCluster_ ) + blockOfCluster ; if ( n == 512 ) { if ( SdVolume :: cacheBlockNumber_ == block ) { SdVolume :: cacheBlockNumber_ = 0 XFFFFFFFF ; } if ( ! vol_ -> writeBlock ( block , src ) ) goto writeErrorReturn ; src += 512 ; } else { if ( blockOffset == 0 && curPosition_ >= fileSize_ ) { if ( ! SdVolume :: cacheFlush ( ) ) goto writeErrorReturn ; SdVolume :: cacheBlockNumber_ = block ; SdVolume :: cacheSetDirty ( ) ; } else { if ( ! SdVolume :: cacheRawBlock ( block , SdVolume :: CACHE_FOR_WRITE ) ) { goto writeErrorReturn ; } } uint8_t * dst = SdVolume :: cacheBuffer_ . data + blockOffset ; uint8_t * end = dst + n ; while ( dst != end ) * dst ++ = * src ++ ; } nToWrite -= n ; curPosition_ += n ; } if ( curPosition_ > fileSize_ ) { fileSize_ = curPosition_ ; flags_ |= F_FILE_DIR_DIRTY ; } else if ( dateTime_ && nbyte ) { flags_ |= F_FILE_DIR_DIRTY ; } if ( flags_ & O_SYNC ) { if ( ! sync ( ) ) goto writeErrorReturn ; } return nbyte ; writeErrorReturn : return 0 ; }
Write data to an open file.
Write data to an open file .
// convert void* to uint8_t*  -  must be before goto statements // number of bytes left to write  -  must be before goto statements // error if not a normal file or is read-only // seek to end of file if append flag // start of new cluster // allocate first cluster of file // add cluster if at end of chain // max space in block // lesser of space and amount to write // block for data write // full block - don't need to use cache // invalidate cache if block is in cache // start of new block don't need to read into cache // rewrite part of block // update fileSize and insure sync will update dir entry // insure sync will update modified date and time // return for write error //writeError = true; //setWriteError();