int File::findChildren(FileFinder& finder, vector<File*>& results, bool recursive, bool archiveEntries) const { int matchCount = 0; FileIterator* it = getIterator(); File* child; while ((child = it->next()) != NULL) { bool matches = finder.matches(*child); if (matches) { results.push_back(child); matchCount++; } if (finder.isInterrupted()) { if (!matches) { delete child; } return matchCount; } if (recursive && (child->isDirectory() || (archiveEntries && child->isArchiveFile()))) { matchCount += child->findChildren(finder, results, true, archiveEntries); } if (!matches) { delete child; } } delete it; return matchCount; }
File* File::findChild(FileFinder& finder, bool recursive, bool archiveEntries) const { FileIterator* it = getIterator(); File* child; while ((child = it->next()) != NULL) { if (finder.matches(*child)) { delete it; return child; } if (finder.isInterrupted()) { delete child; return NULL; } if (recursive && (child->isDirectory() || (archiveEntries && child->isArchiveFile()))) { File* match = child->findChild(finder, true, archiveEntries); if (match) { delete child; delete it; return match; } } delete child; } delete it; return NULL; }
int File::indexOf(const File& other) const { if (!isDirectory() && !isArchiveFile()) { char* errmsg = new char[path->toString().length() + 128]; sprintf(errmsg, "Called indexOf(const File&) with an invalid file type: '%s'", path->toString().get()); FileException ex(errmsg, __FILE__, __LINE__); delete[] errmsg; throw ex; } FileIterator* it = getIterator(); int i = 0; File* child; while ((child = it->next()) != NULL) { if (child->getPath()->toString() == other.getPath()->toString()) { delete child; delete it; return i; } i++; delete child; } delete it; return -1; }
int File::getChildCount(bool recursive, bool archiveEntries) const { if (isRegularFile()) { FileContentType type = guessContentType(); if (type != CONTENT_TYPE_DIR && type != CONTENT_TYPE_IMG) { return 0; } else { if (!recursive || archiveEntries) { //IMGArchive img(*this); //return img.getEntryCount(); return getIMGArchive()->getEntryCount(); } else { return 0; } } } else if (!isDirectory()) { return 0; } FileIterator* it = getIterator(); int i = 0; File* child; while ((child = it->next()) != NULL) { if (recursive) { i += child->getChildCount(true, archiveEntries); } delete child; i++; } delete it; return i; }
File* File::getChild(int childIdx) const { if (physicallyExists()) { if (isRegularFile()) { FileContentType type = guessContentType(); if (type == CONTENT_TYPE_DIR || type == CONTENT_TYPE_IMG) { try { boost::shared_ptr<IMGArchive> archive = getIMGArchive(); if (childIdx >= archive->getEntryCount()) { return NULL; } IMGArchive::EntryIterator it = archive->getEntryBegin(); for (int i = 0 ; it != archive->getEntryEnd() && i < childIdx ; it++, i++); return new File(*this, (*it)->name); } catch (Exception& ex) { char* errMsg = new char[path->toString().length() + 64]; sprintf(errMsg, "Exception thrown during child count of IMG archive %s.", path->toString().get()); FileException fex(errMsg, __FILE__, __LINE__, &ex); delete[] errMsg; throw fex; } } else { char* errmsg = new char[path->toString().length() + 128]; sprintf(errmsg, "Called getChild(int) with a regular non-archive file: '%s'", path->toString().get()); FileException ex(errmsg, __FILE__, __LINE__); delete[] errmsg; throw ex; } } else if (isDirectory()) { FileIterator* it = getIterator(); File* nextFile = NULL; for (int i = 0 ; i <= childIdx ; i++) { if (nextFile != NULL) { delete nextFile; } nextFile = it->next(); if (nextFile == NULL) { break; } } delete it; return nextFile; } else { char* errmsg = new char[path->toString().length() + 128]; sprintf(errmsg, "Called getChild(int) with file of invalid type: '%s'", path->toString().get()); FileException ex(errmsg, __FILE__, __LINE__); delete[] errmsg; throw ex; } } else { char* errmsg = new char[path->toString().length() + 128]; sprintf(errmsg, "Called getChild(int) with a non-existant file: '%s'", path->toString().get()); FileException ex(errmsg, __FILE__, __LINE__); delete[] errmsg; throw ex; } }
int CompactBlock::real_compact(LogicBlock* src, LogicBlock* dest) { assert(NULL != src && NULL != dest); BlockInfo dest_blk; BlockInfo* src_blk = src->get_block_info(); dest_blk.block_id_ = src_blk->block_id_; dest_blk.seq_no_ = src_blk->seq_no_; dest_blk.version_ = src_blk->version_; dest_blk.file_count_ = 0; dest_blk.size_ = 0; dest_blk.del_file_count_ = 0; dest_blk.del_size_ = 0; dest->set_last_update(time(NULL)); TBSYS_LOG(DEBUG, "compact block set last update. blockid: %u\n", dest->get_logic_block_id()); char* dest_buf = new char[MAX_COMPACT_READ_SIZE]; int32_t write_offset = 0, data_len = 0; int32_t w_file_offset = 0; RawMetaVec dest_metas; FileIterator* fit = new FileIterator(src); int ret = TFS_SUCCESS; while (fit->has_next()) { ret = fit->next(); if (TFS_SUCCESS != ret) { tbsys::gDeleteA(dest_buf); tbsys::gDelete(fit); return ret; } const FileInfo* pfinfo = fit->current_file_info(); if (pfinfo->flag_ & (FI_DELETED | FI_INVALID)) { continue; } FileInfo dfinfo = *pfinfo; dfinfo.offset_ = w_file_offset; // the size returned by FileIterator.current_file_info->size is // the size of file content!!! dfinfo.size_ = pfinfo->size_ + sizeof(FileInfo); dfinfo.usize_ = pfinfo->size_ + sizeof(FileInfo); w_file_offset += dfinfo.size_; dest_blk.file_count_++; dest_blk.size_ += dfinfo.size_; RawMeta tmp_meta; tmp_meta.set_file_id(dfinfo.id_); tmp_meta.set_size(dfinfo.size_); tmp_meta.set_offset(dfinfo.offset_); dest_metas.push_back(tmp_meta); // need flush write buffer if ((0 != data_len) && (fit->is_big_file() || data_len + dfinfo.size_ > MAX_COMPACT_READ_SIZE)) { TBSYS_LOG(DEBUG, "write one, blockid: %u, write offset: %d\n", dest->get_logic_block_id(), write_offset); ret = dest->write_raw_data(dest_buf, data_len, write_offset); if (TFS_SUCCESS != ret) { TBSYS_LOG(ERROR, "write raw data fail, blockid: %u, offset %d, readinglen: %d, ret :%d", dest->get_logic_block_id(), write_offset, data_len, ret); tbsys::gDeleteA(dest_buf); tbsys::gDelete(fit); return ret; } write_offset += data_len; data_len = 0; } if (fit->is_big_file()) { ret = write_big_file(src, dest, *pfinfo, dfinfo, write_offset); write_offset += dfinfo.size_; } else { memcpy(dest_buf + data_len, &dfinfo, sizeof(FileInfo)); int left_len = MAX_COMPACT_READ_SIZE - data_len; ret = fit->read_buffer(dest_buf + data_len + sizeof(FileInfo), left_len); data_len += dfinfo.size_; } if (TFS_SUCCESS != ret) { tbsys::gDeleteA(dest_buf); tbsys::gDelete(fit); return ret; } } // end of iterate if (0 != data_len) // flush the last buffer { TBSYS_LOG(DEBUG, "write one, blockid: %u, write offset: %d\n", dest->get_logic_block_id(), write_offset); ret = dest->write_raw_data(dest_buf, data_len, write_offset); if (TFS_SUCCESS != ret) { TBSYS_LOG(ERROR, "write raw data fail, blockid: %u, offset %d, readinglen: %d, ret :%d", dest->get_logic_block_id(), write_offset, data_len, ret); tbsys::gDeleteA(dest_buf); tbsys::gDelete(fit); return ret; } } tbsys::gDeleteA(dest_buf); tbsys::gDelete(fit); TBSYS_LOG(DEBUG, "compact write complete. blockid: %u\n", dest->get_logic_block_id()); ret = dest->batch_write_meta(&dest_blk, &dest_metas); if (TFS_SUCCESS != ret) { TBSYS_LOG(ERROR, "compact write segment meta failed. blockid: %u, meta size %zd\n", dest->get_logic_block_id(), dest_metas.size()); return ret; } TBSYS_LOG(DEBUG, "compact set dirty flag. blockid: %u\n", dest->get_logic_block_id()); ret = dest->set_block_dirty_type(C_DATA_CLEAN); if (TFS_SUCCESS != ret) { TBSYS_LOG(ERROR, "compact blockid: %u set dirty flag fail. ret: %d\n", dest->get_logic_block_id(), ret); return ret; } return TFS_SUCCESS; }