⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oledoc.cpp

📁 xls文件格式分析基础库
💻 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 + -