📄 olefs.cpp
字号:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) Yeico S. A. de C. V. * xlsLib -- A multiplatform, C++ library for dynamic generation of Excel (TM) * files. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * $Source: /cvsroot/xlslib/xlslib/src/oledoc/olefs.cpp,v $ * $Revision: 1.2 $ * $Author: darioglz $ * $Date: 2004/09/01 00:47:04 $ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * File description: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */#include "olefs.h"#include <string>#include "stringtok.h"using namespace std;using namespace xlslib_core; /* ***********************************COleFileSystem class Implementation************************************/COleFileSystem::COleFileSystem() :m_RootEntry((signed32_t)0,string("Root Entry")), m_nProperty_Count(0){ m_RootEntry.SetType(PTYPE_ROOT); m_RootEntry.SetSize(0); m_RootEntry.SetPreviousIndex( PLINK_EMPTY); m_RootEntry.SetNextIndex( PLINK_EMPTY); m_RootEntry.SetChildIndex( PLINK_EMPTY); m_RootEntry.SetStartBlock( PBLOCK_END); m_RootEntry.SetColor(PROPERTY_COLOR_NODE_BLACK); m_RootEntry.SetDataPointer(NULL); m_RootEntry.SetCreatedSecs(PPT_DFLT_SECS1); m_RootEntry.SetCreatedDays(PPT_DFLT_DAYS1); m_RootEntry.SetModifiedSecs(PPT_DFLT_SECS2); m_RootEntry.SetModifiedDays(PPT_DFLT_DAYS2);}COleFileSystem::~COleFileSystem(){}/* ***********************************************************************/int COleFileSystem::GetNode(string const &path, Tree_Level_Itor_t& node){ StringList_t path_list; stringtok(path_list, path, "/"); int retval = SearchNode(&m_RootEntry, path_list, node); // Delete dinamically created strings of path_list // anyway the list is deleted iside SearchNode... for (StringListItor_t pl = path_list.begin(); pl != path_list.end(); pl++) delete *pl; return retval;}/* ***********************************************************************/int COleFileSystem::SearchNode(COleProp* base_node, StringList_t& path_list, Tree_Level_Itor_t& node_level){ int errcode = FS_INVALID_PATH; if(!((base_node->m_Child_List).empty())) { for (StringListItor_t node_name = path_list.begin(); node_name != path_list.end(); ++node_name) for(node_level = (base_node->m_Child_List).begin(); node_level != (base_node->m_Child_List).end(); node_level++) { if (**node_name == (*node_level)->GetName()) { delete path_list.front(); path_list.pop_front(); // Remove the found element from path if(path_list.empty()) // If it was the last element return it { return FS_NO_ERRORS; } else { // Recursively continue the search return SearchNode(*node_level, path_list, node_level); } } } } return errcode;}/* ***********************************************************************/int COleFileSystem::AddDirectory(string const &dir_path){ int errcode = NO_ERRORS; StringList_t path_list; stringtok(path_list, dir_path, "/"); errcode = AddNode(&m_RootEntry, path_list); // Delete dinamically created strings of path_list for (StringListItor_t pl = path_list.begin(); pl != path_list.end(); pl++) delete *pl; if(errcode == FS_NO_ERRORS) { Tree_Level_Itor_t newnode; GetNode(dir_path, newnode); (*newnode)->SetChildIndex(PLINK_EMPTY); (*newnode)->SetType(PTYPE_DIRECTORY); (*newnode)->SetSize(0); (*newnode)->SetColor(PROPERTY_COLOR_NODE_BLACK); (*newnode)->SetDataPointer(NULL); (*newnode)->SetCreatedSecs(PPT_DFLT_SECS1); (*newnode)->SetCreatedDays(PPT_DFLT_DAYS1); (*newnode)->SetModifiedSecs(PPT_DFLT_SECS2); (*newnode)->SetModifiedDays(PPT_DFLT_DAYS2); } return errcode;}/* ***********************************************************************/#define MIN_DATA_SIZE (0x1000)// TODO: Change the DataStorage pass-argumentint COleFileSystem::AddFile(string const &dir_path, CDataStorage* pdata){ int errcode = NO_ERRORS; StringList_t path_list; // NOTE: Token analysis can be done inside of AddNode: stringtok(path_list, dir_path, "/"); errcode = AddNode(&m_RootEntry, path_list); // Delete dinamically created strings of path_list for (StringListItor_t pl = path_list.begin(); pl != path_list.end(); pl++) delete *pl; if(errcode == FS_NO_ERRORS) { Tree_Level_Itor_t newnode; GetNode(dir_path, newnode); (*newnode)->SetType(PTYPE_FILE); (*newnode)->SetChildIndex(PLINK_EMPTY); // Calculate the trail data size needed to complete a BIG_BLOCK unsigned32_t trail_size = (pdata->GetDataSize() % BIG_BLOCK_SIZE)? (BIG_BLOCK_SIZE - (pdata->GetDataSize() % BIG_BLOCK_SIZE)):0; // This library won't use Small Blocks, so all data elements shall be >0x1000 if ((trail_size + pdata->GetDataSize()) < MIN_DATA_SIZE) { trail_size = MIN_DATA_SIZE - pdata->GetDataSize(); (*newnode)->SetSize(MIN_DATA_SIZE); } else { // The size stored in the node is the actual size of the data (not the filled-to-bigblock one) (*newnode)->SetSize(pdata->GetDataSize() + trail_size); } // create the trail data unit. CUnit* ptraildata = new CUnit; ptraildata->AddFixedDataArray(0x00, trail_size); (*pdata) += ptraildata; (*newnode)->SetDataPointer(pdata); (*newnode)->SetColor(PROPERTY_COLOR_NODE_BLACK); (*newnode)->SetCreatedSecs(PPT_DFLT_SECS1); (*newnode)->SetCreatedDays(PPT_DFLT_DAYS1); (*newnode)->SetModifiedSecs(PPT_DFLT_SECS2); (*newnode)->SetModifiedDays(PPT_DFLT_DAYS2); } return errcode;}/* ***********************************************************************//*Some special adding-node cases:- The path to reach the node doesn't exist- The the node already exists*/int COleFileSystem::AddNode(COleProp* base_node, StringList_t& path_list){ int errcode; if(!(base_node->m_Child_List).empty()) { for(Tree_Level_Itor_t node_child = (base_node->m_Child_List).begin(); node_child != (base_node->m_Child_List).end(); node_child++) { if((*node_child)->GetName() == **path_list.begin()) { delete path_list.front(); path_list.pop_front(); // Remove the found element from path return AddNode(*node_child, path_list); } } } //if the path element wasn't found, the program gets here //... and we have two possible reasons: // 1. The path isn't correct, so no node is created and an error msg have to be returned // (one of the intermediate nodes is empty or doesn't exist: there are more than one path elements left) // 2. The node is the new one we want to create. // if the size of the path is 0, the node already existed if(path_list.size() != 1) { if (path_list.size() == 0) errcode = FS_NODE_ALREADY_EXISTS; else errcode = FS_INVALID_PATH; } else { unsigned8_t base_node_type = base_node->GetType(); if(base_node_type == PTYPE_DIRECTORY || base_node_type == PTYPE_ROOT) {#if 0 COleProp newnode(++m_nProperty_Count, *path_list.begin()); bool was_firstborn = false; if((base_node->m_Child_List).empty()) //if this is the first child of the node... { base_node->SetChildIndex(m_nProperty_Count); // the new one is the child newnode.SetPreviousIndex(PLINK_EMPTY); // there is no previous was_firstborn = true;// mark for later } // The next-index of the new node shall to point to nowhere newnode.SetNextIndex(PLINK_EMPTY); (base_node->m_Child_List).push_back(newnode); // Get the just added node Tree_Level_Itor_t nodeadded = (base_node->m_Child_List).end(); nodeadded--; // Get the previous to the just added node Tree_Level_Itor_t prev_to_nodeadded = (base_node->m_Child_List).end(); prev_to_nodeadded--;prev_to_nodeadded--; if(!was_firstborn) nodeadded->SetPreviousIndex(prev_to_nodeadded->GetIndex()); // Set the next-index of the previous node to point to the newone prev_to_nodeadded->SetNextIndex(nodeadded->GetIndex());#else//////////// COleProp* newnode = new COleProp(++m_nProperty_Count, **path_list.begin()); int childnum = (base_node->m_Child_List).size(); if(!(base_node->m_Child_List).empty()) //if this is the first child of the node... { Tree_Level_Itor_t lastnode = (base_node->m_Child_List).end(); lastnode--; if(1 == childnum) { base_node->SetChildIndex(newnode->GetIndex()); // The 2nd child is the entry always newnode->SetPreviousIndex((*lastnode)->GetIndex()); // The previous is the only element of the list } else { (*lastnode)->SetNextIndex(newnode->GetIndex()); newnode->SetPreviousIndex(PLINK_EMPTY); // there is no previous } newnode->SetNextIndex(PLINK_EMPTY); // there is no next newnode->SetChildIndex(PLINK_EMPTY); // there is no child } else { base_node->SetChildIndex(m_nProperty_Count); // the new one is the child newnode->SetPreviousIndex(PLINK_EMPTY); // there is no previous newnode->SetNextIndex(PLINK_EMPTY); // there is no next newnode->SetChildIndex(PLINK_EMPTY); // there is no child } (base_node->m_Child_List).push_back(newnode);#endif errcode = FS_NO_ERRORS; } else { errcode = FS_NODE_NOT_A_DIRECTORY; } } return errcode;}/* ***********************************************************************/void COleFileSystem::GetAllNodes(NodeList_t& node_list){ GetAllNodesList(node_list, &m_RootEntry); SortList(node_list);}/* ***********************************************************************/void COleFileSystem::GetAllNodesList(NodeList_t& node_list, COleProp* base_node){ if(!(base_node->m_Child_List).empty()) { for(Tree_Level_Itor_t child_node = (base_node->m_Child_List).begin(); child_node != (base_node->m_Child_List).end(); child_node++ ) { GetAllNodesList(node_list, (*child_node)); node_list.push_back((*child_node)); } } else { return; }} /* ***********************************An horribly inefficient sorting routine....... until I find the way of using the list<T>::sort() function soI can specify the sorting criteria (for this case, a member variableof the elements of the list.************************************/void COleFileSystem::SortList(NodeList_t& node_list){ NodeList_t node_list_shadow = node_list; node_list.erase(node_list.begin(), node_list.end()); NodeList_Itor_t i; int index = 1; do{ for(i = node_list_shadow.begin(); i != node_list_shadow.end(); i++) { if((*i)->GetIndex() == index) { node_list.push_back(*i); node_list_shadow.erase(i); index++; break; } } }while(!node_list_shadow.empty());}/* ***********************************************************************/unsigned32_t COleFileSystem::GetTotalDataSize(){ NodeList_t node_list; GetAllNodes(node_list); unsigned32_t total_size = 0; for(NodeList_Itor_t i = node_list.begin(); i != node_list.end(); i++) { if((*i)->GetType() == PTYPE_FILE) total_size += (*i)->GetDataPointer()->GetDataSize(); } return total_size;}/* ***********************************************************************/unsigned32_t COleFileSystem::GetNumDataFiles(){ NodeList_t node_list; GetAllNodes(node_list); unsigned32_t total_files = 0; for(NodeList_Itor_t i = node_list.begin(); i != node_list.end(); i++) { if((*i)->GetType() == PTYPE_FILE) total_files ++; } return total_files;}/* ***********************************************************************/COleProp& COleFileSystem::GetRootEntry(){ return m_RootEntry;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * $Log: olefs.cpp,v $ * Revision 1.2 2004/09/01 00:47:04 darioglz * + Modified to gain independence of target * * Revision 1.1.1.1 2004/08/27 16:31:43 darioglz * Initial Import. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -