33 extern BlockStorage::Buffer SHARED_BUFFER;
53 :
File(fs, name, buffer, logger),
54 FatFile(fs, name, buffer, logger),
65 PropWare::ErrorCode
open () {
66 PropWare::ErrorCode err;
67 uint16_t fileEntryOffset = 0;
69 if ((err = this->find(this->
get_name(), &fileEntryOffset))) {
72 check_errors(this->m_fs->extend_current_directory());
74 check_errors(this->create_new_file(fileEntryOffset));
81 check_errors(this->open_existing_file(fileEntryOffset));
91 PropWare::ErrorCode err;
94 if (0 == this->m_dirTier1Addr) {
95 uint16_t fileEntryOffset = 0;
96 if ((err = this->find(this->m_name, &fileEntryOffset))) {
97 if (FatFS::EOC_END == err)
102 check_errors(this->open_existing_file(fileEntryOffset));
106 check_errors(this->load_directory_sector());
108 this->m_buf->buf[this->fileEntryOffset] = DELETED_FILE_MARK;
109 this->m_buf->meta->mod =
true;
111 check_errors(this->m_fs->clear_chain(this->firstTier2));
113 this->m_fileMetadataModified =
false;
119 PropWare::ErrorCode err;
122 if (this->m_buf->meta == &this->m_contentMeta) {
123 check_errors(this->m_driver->flush(this->m_buf));
127 if (this->m_fileMetadataModified) {
128 this->load_directory_sector();
131 this->m_buf->meta->mod =
true;
132 this->m_driver->write_long(this->fileEntryOffset + FILE_LEN_OFFSET, this->m_buf->buf,
133 (
const uint32_t) this->m_length);
135 check_errors(this->m_driver->flush(this->m_buf));
136 this->m_fileMetadataModified =
false;
143 PropWare::ErrorCode err;
146 if (this->need_to_extend_fat()) {
147 check_errors(this->m_fs->extend_fat(&this->m_contentMeta));
150 check_errors(this->load_sector_under_ptr());
153 const uint16_t bufferOffset = (uint16_t) (this->m_ptr % this->m_driver->get_sector_size());
154 this->m_buf->buf[bufferOffset] = (uint8_t) c;
155 this->m_buf->meta->mod =
true;
158 if (this->m_length == this->m_ptr) {
160 this->m_fileMetadataModified =
true;
172 void print_status (
const bool printBlocks =
false)
const {
173 this->File::print_status(
"FatFileWriter", printBlocks);
174 this->FatFile::print_status(printBlocks,
false);
175 this->FileWriter::print_status(printBlocks,
false);
179 static inline bool not_period_or_end (
const char c) {
180 return '.' != c && c;
183 bool need_to_extend_fat () {
184 const uint8_t sectorsPerCluster = this->m_fs->m_tier1sPerTier2Shift;
186 const uint32_t requiredSector = (uint32_t) this->m_ptr >> this->m_driver->get_sector_size_shift();
187 unsigned int requiredCluster = requiredSector >> sectorsPerCluster;
189 if (this->m_curTier2 < requiredCluster)
190 return this->m_fs->is_eoc(this->m_contentMeta.nextTier2);
197 PropWare::ErrorCode create_new_file (
const uint16_t fileEntryOffset) {
198 PropWare::ErrorCode err;
203 check_errors(this->write_filename(fileEntryOffset));
208 this->m_buf->buf[fileEntryOffset + FILE_ATTRIBUTE_OFFSET] = ARCHIVE;
211 this->get_fat_location(fileEntryOffset);
214 this->m_driver->write_long(fileEntryOffset + FILE_LEN_OFFSET, this->m_buf->buf, 0);
216 this->m_buf->meta->mod =
true;
220 inline PropWare::ErrorCode write_filename (
const uint16_t fileEntryOffset) {
221 PropWare::ErrorCode err;
225 for (i = 0; not_period_or_end(this->m_name[i]); ++i)
226 this->m_buf->buf[fileEntryOffset + i] = (uint8_t) this->m_name[i];
229 if (this->m_name[i]) {
230 check_errors(this->write_filename_extension(fileEntryOffset, i));
232 this->pad_with_spaces(fileEntryOffset, i);
237 inline PropWare::ErrorCode write_filename_extension (
const uint16_t fileEntryOffset, uint8_t &i) {
241 for (j = i; j < FILE_NAME_LEN; ++j)
242 this->m_buf->buf[fileEntryOffset + j] =
' ';
245 if (
'.' == this->m_name[i]) {
250 while (this->m_name[i]) {
251 this->m_buf->buf[fileEntryOffset + j] = (uint8_t) this->m_name[i];
257 while (FILE_NAME_LEN + FILE_EXTENSION_LEN > j) {
258 this->m_buf->buf[fileEntryOffset + j] =
' ';
268 inline void pad_with_spaces (uint16_t
const fileEntryOffset, uint8_t i) {
269 for (; i < (FILE_NAME_LEN + FILE_EXTENSION_LEN); ++i)
270 this->m_buf->buf[fileEntryOffset + i] =
' ';
273 inline void get_fat_location (
const uint16_t fileEntryOffset) {
274 const uint32_t allocUnit = this->m_fs->find_empty_space(0);
275 this->m_driver->write_short(fileEntryOffset + FILE_START_CLSTR_LOW, this->m_buf->buf, (uint16_t) allocUnit);
276 if (FatFS::FAT_32 == this->m_fs->get_fs_type())
277 this->m_driver->write_short(fileEntryOffset + FILE_START_CLSTR_HIGH, this->m_buf->buf,
278 (uint16_t) (allocUnit >> 16));