📄 oledoc.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/oledoc.cpp,v $ * $Revision: 1.2 $ * $Author: darioglz $ * $Date: 2004/09/01 00:47:04 $ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * File description: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */#include "oledoc.h"using namespace std;using namespace xlslib_core;/* ***********************************COleDoc class implementation************************************/const unsigned8_t COleDoc::OLE_FILETYPE[] ={ 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1}; COleDoc::COleDoc(){}/* COleDoc::COleDoc(const string& file_name) { Open(file_name); }*/COleDoc::~COleDoc(){}/* ***********************************************************************/int COleDoc::DumpHeader(signed32_t bat_count, unsigned32_t total_data_size){ int errcode = NO_ERRORS; int i; // [00]FILETYPE WriteByteArray(COleDoc::OLE_FILETYPE, /*(unsigned32_t)*/sizeof(COleDoc::OLE_FILETYPE)); // [08]UK1 WriteSigned32(HEADVAL_DFLT_UK1); // [0c]UK2 WriteSigned32(HEADVAL_DFLT_UK2); // [10]UK2b WriteSigned32(HEADVAL_DFLT_UK2b); // [14]UK3 WriteSigned32(HEADVAL_DFLT_UK3); // [18]UK4 WriteSigned16(HEADVAL_DFLT_UK4); // [1a]UK5 WriteSigned16(HEADVAL_DFLT_UK5); // [1c]UK6 WriteSigned16(HEADVAL_DFLT_UK6); // [1e]LOG_2_BIG_BLOCK WriteSigned16(HEADVAL_DFLT_LOG2_BIGBLOCK); // [20]LOG_2_SMALL_BLOCK WriteSigned32(HEADVAL_DFLT_LOG2_SMALLBLOCK); // [24]UK7 WriteSigned32(HEADVAL_DFLT_UK7); // [28]UK8 WriteSigned32(HEADVAL_DFLT_UK8); // [2c] BAT_COUNT (BBDEPOT NUM BLOCKS) WriteSigned32(bat_count); //[30] PROPERTIES_START_BLOCK // Since the big block depot will go immediately after the data, I need // to know the size of the data and the size of the BAT in blocks (prev) WriteSigned32(bat_count+total_data_size/(BIG_BLOCK_SIZE)); // [34] UK9 WriteSigned32(HEADVAL_DFLT_UK9); // [38] UK10 WriteSigned32(HEADVAL_DFLT_UK10); // [3c] SBAT_START // No small blocks will be used, so this is set to the default empty value WriteSigned32(HEADVAL_DFLT_SBAT_START); // [40] SBAT_BLOCKCOUNT_NUMBER // Use the default value WriteSigned32(HEADVAL_DFLT_SBAT_COUNT); // [44] XBAT_START // No extended BAT neither WriteSigned32(HEADVAL_DFLT_XBAT_START); // [48] XBAT_COUNT WriteSigned32(HEADVAL_DFLT_XBAT_COUNT); // [4C] BAT_ARRAY // The BAT_ARRAY shall be calculated from the number of BAT blocks and their position for(i=0; i<bat_count; i++) WriteSigned32(total_data_size/(BIG_BLOCK_SIZE) +i); // Finally, fill remaining addresses of the header with -1. // from (BAT_ARRY+BAT_COUNT) to (BIGBLOCKSIZE) for(i = (HEADPOS_BAT_ARRAY + bat_count*4); i<HEAD_SIZE; i++) WriteByte(HEAD_UNUSED_BYTE); return errcode;}/* ***********************************************************************/int COleDoc::DumpData(void){ int errcode = NO_ERRORS; NodeList_t node_list; GetAllNodes(node_list); for(NodeList_Itor_t i = node_list.begin(); i != node_list.end(); i++) { if((*i)->GetType() == PTYPE_FILE) { for(DataList_Itor_t j = (*i)->GetDataPointer()->begin(); j != (*i)->GetDataPointer()->end(); j++) { WriteByteArray((*j)->GetBuffer(), (*j)->GetDataSize()); } } } return errcode;}/* ***********************************************************************/int COleDoc::DumpDepots(unsigned32_t bat_blocks_count){ int errcode = NO_ERRORS; NodeList_t node_list; GetAllNodes(node_list); unsigned32_t bat_index = 0; for(NodeList_Itor_t node = node_list.begin(); node != node_list.end(); node++) { // The start block is set in the node. (*node)->SetStartBlock(bat_index); // Write the chain for this node element for(unsigned32_t i = 0; i < ((*node)->GetDataPointer()->GetDataSize()/BIG_BLOCK_SIZE - 1); i++) { WriteSigned32(++bat_index); } // Set the terminator number ++bat_index; WriteSigned32(BAT_END_CHAIN); } // Write the -3 number for every index in the BAT that references to some BAT block (uh!?) for(unsigned16_t i=0; i<bat_blocks_count;i++) { ++bat_index; WriteSigned32(BAT_SELF_PLACE); } // The terminator for the self-chain ++bat_index; WriteSigned32(BAT_END_CHAIN); //Fill the rest of the _LAST_ BAT block. unsigned32_t to_fill_size = BIG_BLOCK_SIZE - ((4*bat_index) % BIG_BLOCK_SIZE);#if 0 unsigned8_t * to_fill_data = new unsigned8_t[to_fill_size]; memset(to_fill_data, BAT_NOT_USED_BYTE, to_fill_size*sizeof(unsigned8_t)); WriteByteArray(to_fill_data, to_fill_size); delete[] to_fill_data;#else SerializeFixedArray(BAT_NOT_USED_BYTE, to_fill_size);#endif return errcode;}/* ***********************************************************************/int COleDoc::DumpFileSystem(void){ int errcode = NO_ERRORS; NodeList_t node_list; GetAllNodes(node_list); DumpNode(GetRootEntry()); for(NodeList_Itor_t node = node_list.begin(); node != node_list.end(); node++) DumpNode(*(*node)); return errcode;}/* ***********************************************************************/int COleDoc::DumpOleFile(void){ int errcode = NO_ERRORS; signed32_t bat_count = GetBATCount(); unsigned32_t total_data_size = GetTotalDataSize(); errcode = DumpHeader(bat_count, total_data_size); errcode = DumpData(); errcode = DumpDepots(bat_count); errcode = DumpFileSystem(); return errcode;}/*************************************************************** Need to know the size of all the data (rounded to bigblocks) so I can create the BBDepot and see the size in bigblocks Para obtener el tama駉 de la BAT, se asume que por cada prop se tendr韆 una lista enlazada de size/0x200+1 elementos. Adem醩, se coloca un -3 en la posici髇 correspondiente a cada BAT: BAT_SIZE = (4*SizeP0/0x200 + 4*SizeP1/0x200 + ... + 4*SizePn/0x200) + n BAT_SIZE = (SizeP0 + SizeP1 + ... + SizePn)/0x50 + n BAT_SIZE = (SizeTot/0x50 + n) EXTRA_VALUES = BAT_SIZE/BIGBLOCKSIZE if (BAT_SIZE%BIGBLOCKSIZE) EXTRA_VALUES++ EXTRA_VALUES++ BAT_SIZE += EXTRA_VALUES // This operation may be recursive, since Extra_Values is dependant on Bat_Size BAT_COUNT = BAT_SIZE/0x200*****************************************************************/signed32_t COleDoc::GetBATCount(){ signed32_t bat_size; signed32_t extra_values = 0, temp=0; // Get the size in bytes of the BAT bat_size = (GetTotalDataSize()/(BIG_BLOCK_SIZE/4) + GetNumDataFiles()) ; // The following is a semirecursive loop (the same code is executed twice: // the second one using the result of the first one) do { signed32_t previous_extra_values = extra_values; extra_values = (bat_size)/BIG_BLOCK_SIZE; // for each BAT-block there's an extra byte in the BAT if(bat_size%BIG_BLOCK_SIZE) extra_values++; // Round up extra_values++; bat_size += (extra_values - previous_extra_values); temp = bat_size/BIG_BLOCK_SIZE; // See if the previous result affected the overall extra values if(bat_size%BIG_BLOCK_SIZE) temp++; temp++; } while(extra_values != temp ); // Get the unrounded num of blocks needed. signed32_t bat_num_blocks = bat_size/BIG_BLOCK_SIZE; if(bat_size%BIG_BLOCK_SIZE) bat_num_blocks++; return bat_num_blocks;}/* ***********************************************************************/// NOTE: name_unicode has to be deleted after this function finishes.// Ideally, this function should be implemented as part of a std::string // derived class, so the array would be deleted automaticallysigned16_t COleDoc::GetUnicodeName(const char* name, char** ppname_unicode){ unsigned16_t name_size = strlen(name); if(name_size > PROPERTY_MAX_NAME_LENGTH) name_size = PROPERTY_MAX_NAME_LENGTH; unsigned8_t size_unicode = (name_size+1)*2; if(*ppname_unicode != NULL) delete[] *ppname_unicode; *ppname_unicode = (char*)new unsigned8_t[size_unicode]; memset(*ppname_unicode, 0x00, size_unicode); for(int i=0; i<(size_unicode/2-1); i++) (*ppname_unicode)[2*i] = name[i]; return size_unicode;}/* ***********************************************************************/int COleDoc::DumpNode(COleProp& node){ int errcode = NO_ERRORS; char* name_unicode = NULL; // Get the unicode name and its size signed16_t size_name = GetUnicodeName(node.GetName().c_str(), &name_unicode); // [00] PROPERTY_NAME WriteByteArray((const unsigned8_t*)name_unicode, size_name); // Fill the rest of the name field with 0x00 SerializeFixedArray(PROPERTY_DFLT_NOTUSED, PPTPOS_NAMELENGTH - size_name); // [40] NAME_SIZE WriteSigned16(size_name); // [42] PROPERTY_TYPE WriteByte(node.GetType()); // [43] NODE_COLOR WriteByte(node.GetColor()); // [44] PREVIOUS_PROP WriteSigned32(node.GetPreviousIndex()); // [48] NEXT_PROP WriteSigned32(node.GetNextIndex()); // [4c] CHILD_PROP WriteSigned32(node.GetChildIndex()); // Fill empty block SerializeFixedArray(PROPERTY_DFLT_NOTUSED, (PPTPOS_SECS1 - PPTPOS_UNUSED_EMPTY0)); //[64]...[70] // SECONDS_1, DAYS_2, SECONDS_2, DAYS_2 WriteSigned32(node.GetCreatedSecs()); WriteSigned32(node.GetCreatedDays()); WriteSigned32(node.GetModifiedDays()); WriteSigned32(node.GetModifiedSecs()); // [74] START_BLOCK WriteSigned32(node.GetStartBlock()); // [74] SIZE if(node.GetType() == PTYPE_FILE) WriteSigned32(node.GetSize()); else WriteSigned32(0); // A unused space: WriteSigned32(PROPERTY_DFLT_NOTUSED); delete[] name_unicode; name_unicode = NULL; return errcode;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * $Log: oledoc.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 + -