50 :
File(fs, name, buffer, logger),
51 FatFile(fs, name, buffer, logger),
62 PropWare::ErrorCode
open () {
63 PropWare::ErrorCode err;
64 uint16_t fileEntryOffset = 0;
66 if ((err = this->find(this->
get_name(), &fileEntryOffset))) {
69 check_errors(this->m_fs->extend_current_directory());
71 check_errors(this->create_new_file(fileEntryOffset));
78 check_errors(this->open_existing_file(fileEntryOffset));
87 PropWare::ErrorCode
remove () {
88 PropWare::ErrorCode err;
91 if (0 == this->m_dirTier1Addr) {
92 uint16_t fileEntryOffset = 0;
93 if ((err = this->find(this->m_name, &fileEntryOffset))) {
94 if (FatFS::EOC_END == err)
99 check_errors(this->open_existing_file(fileEntryOffset));
103 check_errors(this->load_directory_sector());
105 this->m_buf->buf[this->fileEntryOffset] = DELETED_FILE_MARK;
106 this->m_buf->meta->mod =
true;
108 check_errors(this->m_fs->clear_chain(this->firstTier2));
110 this->m_fileMetadataModified =
false;
116 PropWare::ErrorCode err;
119 if (this->m_buf->meta == &this->m_contentMeta) {
120 check_errors(this->m_driver->flush(this->m_buf));
124 if (this->m_fileMetadataModified) {
125 this->load_directory_sector();
128 this->m_buf->meta->mod =
true;
129 this->m_driver->write_long(this->fileEntryOffset + FILE_LEN_OFFSET, this->m_buf->buf,
130 (
const uint32_t) this->m_length);
132 check_errors(this->m_driver->flush(this->m_buf));
133 this->m_fileMetadataModified =
false;
140 PropWare::ErrorCode err;
143 if (this->need_to_extend_fat()) {
144 check_errors(this->m_fs->extend_fat(&this->m_contentMeta));
147 check_errors(this->load_sector_under_ptr());
150 const uint16_t bufferOffset = (uint16_t) (this->m_ptr % this->m_driver->get_sector_size());
151 this->m_buf->buf[bufferOffset] = (uint8_t) c;
152 this->m_buf->meta->mod =
true;
155 if (this->m_length == this->m_ptr) {
157 this->m_fileMetadataModified =
true;
169 void print_status (
const bool printBlocks =
false)
const {
170 this->File::print_status(
"FatFileWriter", printBlocks);
171 this->FatFile::print_status(printBlocks,
false);
172 this->FileWriter::print_status(printBlocks,
false);
176 static inline bool not_period_or_end (
const char c) {
177 return '.' != c && c;
180 bool need_to_extend_fat () {
181 const uint8_t sectorsPerCluster = this->m_fs->m_tier1sPerTier2Shift;
183 const uint32_t requiredSector = (uint32_t) this->m_ptr >> this->m_driver->get_sector_size_shift();
184 unsigned int requiredCluster = requiredSector >> sectorsPerCluster;
186 if (this->m_curTier2 < requiredCluster)
187 return this->m_fs->is_eoc(this->m_contentMeta.nextTier2);
194 PropWare::ErrorCode create_new_file (
const uint16_t fileEntryOffset) {
195 PropWare::ErrorCode err;
200 check_errors(this->write_filename(fileEntryOffset));
205 this->m_buf->buf[fileEntryOffset + FILE_ATTRIBUTE_OFFSET] = ARCHIVE;
208 this->get_fat_location(fileEntryOffset);
211 this->m_driver->write_long(fileEntryOffset + FILE_LEN_OFFSET, this->m_buf->buf, 0);
213 this->m_buf->meta->mod =
true;
217 inline PropWare::ErrorCode write_filename (
const uint16_t fileEntryOffset) {
218 PropWare::ErrorCode err;
222 for (i = 0; not_period_or_end(this->m_name[i]); ++i)
223 this->m_buf->buf[fileEntryOffset + i] = (uint8_t) this->m_name[i];
226 if (this->m_name[i]) {
227 check_errors(this->write_filename_extension(fileEntryOffset, i));
229 this->pad_with_spaces(fileEntryOffset, i);
234 inline PropWare::ErrorCode write_filename_extension (
const uint16_t fileEntryOffset, uint8_t &i) {
238 for (j = i; j < FILE_NAME_LEN; ++j)
239 this->m_buf->buf[fileEntryOffset + j] =
' ';
242 if (
'.' == this->m_name[i]) {
247 while (this->m_name[i]) {
248 this->m_buf->buf[fileEntryOffset + j] = (uint8_t) this->m_name[i];
254 while (FILE_NAME_LEN + FILE_EXTENSION_LEN > j) {
255 this->m_buf->buf[fileEntryOffset + j] =
' ';
265 inline void pad_with_spaces (uint16_t
const fileEntryOffset, uint8_t i) {
266 for (; i < (FILE_NAME_LEN + FILE_EXTENSION_LEN); ++i)
267 this->m_buf->buf[fileEntryOffset + i] =
' ';
270 inline void get_fat_location (
const uint16_t fileEntryOffset) {
271 const uint32_t allocUnit = this->m_fs->find_empty_space(0);
272 this->m_driver->write_short(fileEntryOffset + FILE_START_CLSTR_LOW, this->m_buf->buf, (uint16_t) allocUnit);
273 if (FatFS::FAT_32 == this->m_fs->get_fs_type())
274 this->m_driver->write_short(fileEntryOffset + FILE_START_CLSTR_HIGH, this->m_buf->buf,
275 (uint16_t) (allocUnit >> 16));
PropWare::ErrorCode safe_put_char(const char c)
Write a character to the file.
PropWare::ErrorCode open()
Open the file.
Concrete class for writing or modifying a FAT 16/32 file.
Generic definitions and functions for the Parallax Propeller.
FatFileWriter(FatFS &fs, const char name[], BlockStorage::Buffer *buffer=NULL, const Printer &logger=pwOut)
Standard constructor.
A generic interface for all files on the FAT 16/32 filesystem.
const PropWare::Printer pwOut
Most common use of printing in PropWare applications (not thread safe; see PropWare::pwSyncOut for mu...
Container class that has formatting methods for human-readable output. This class can be constructed ...
virtual PropWare::ErrorCode close()
Close a file - a required step in any workflow that includes opening a file.
A write-only file interface.
const char * get_name() const
Determine the name of a file.
Basic file interface for opening and closing files.
PropWare::ErrorCode flush()
Flush any modified data back to the SD card.
virtual ~FatFileWriter()
All content will be saved to the physical device and the file will be safely closed.
In-memory buffer containing a single block of data.