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

📄 workbook.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/xlslib/workbook.cpp,v $ * $Revision: 1.2 $ * $Author: darioglz $ * $Date: 2004/09/01 00:47:21 $ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * File description: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */#include "workbook.h"using namespace std;using namespace xlslib_core;#define CHANGE_DUMPSTATE(state) {               \   m_PreviousDumpState = m_DumpState;           \   m_DumpState = state;                         \}/***********************************************************************workbook class implementation***********************************************************************/workbook::workbook()   : m_DumpState(WB_INIT),     m_PreviousDumpState(WB_FINISH),     m_pCurrentData(NULL),     m_pContinueRecord(NULL),     dump_not_started(true),     globalrec_size(0),     current_sheet(0),     offset(0){   write_fptr = NULL;   m_Disposition = STK_ATTACHMENT;}workbook::workbook(write_fptr_t w_fptr)   : m_DumpState(WB_INIT),     m_PreviousDumpState(WB_FINISH),     m_pCurrentData(NULL),     m_pContinueRecord(NULL),     dump_not_started(true),     globalrec_size(0),     current_sheet(0),     offset(0){   write_fptr = w_fptr;   m_Disposition = STK_ATTACHMENT;}workbook::~workbook(){   if(!m_Sheets.empty())   {      for(unsigned32_t i = 0; i<m_Sheets.size(); i++)      {	 delete m_Sheets[i];      }   }}/************************************************************************/worksheet* workbook::sheet(string sheetname){   worksheet* pnewsheet = new worksheet(&m_GlobalRecords);   m_Sheets.push_back(pnewsheet);   // NOTE: Streampos defaults to 0   // It has to be set somewhere else   m_GlobalRecords.AddBoundingSheet(0, BSHEET_ATTR_WORKSHEET, sheetname);   // Return a pointer to the just added sheet   return (m_Sheets.back());}/************************************************************************/worksheet* workbook::GetSheet(unsigned16_t sheetnum){   if(sheetnum < m_Sheets.size())   {      return m_Sheets[sheetnum];   }   else   {      return NULL;   }}/************************************************************************/font_t* workbook::font(string  name){   font_t* newfont = new font_t;   newfont->SetName(name);   return(m_GlobalRecords.AddFont(newfont));}/************************************************************************/format_t* workbook::format(string  formatstr){   format_t* newformat = new  format_t(0x0000, formatstr);   return(m_GlobalRecords.AddFormat(newformat));}xf_t* workbook::xformat(void){   xf_t* newxf = new xf_t;   newxf->MarkUsed();   return(m_GlobalRecords.AddXFormat(newxf));}xf_t* workbook::xformat(font_t* font){   xf_t* newxf = new xf_t;   newxf->MarkUsed();   newxf->SetFont(font);   return(m_GlobalRecords.AddXFormat(newxf));}/************************************************************************/#define SETWORKBOOK()                                              \   CDataStorage biffdata;					   \   CUnit* precorddata;						   \   bool keep = true;						   \   do { 							   \      precorddata = DumpData();					   \								   \      if(precorddata != NULL)					   \         biffdata += precorddata;				   \      else							   \         keep = false;						   \   }while(keep);						   \                                                                   \   AddFile("/Book",&biffdata);					   \   string name;							   \   name = (char)0x05;						   \   name += "SummaryInformation";				   \   AddFile(name, &m_SummaryInfo);				   \   name = (char)0x05;						   \   name += "DocumentSummaryInformation";			   \   AddFile(name, &m_DocSummaryInfo);				   \/****************************** * This function has to be called before any output to the php-string * (this includes any non-php-script text in the source file or  * zend_printf call) because it makes use of headers() php-function, * which has to be called before any of those kind of output. * If this restraint isn't followed, the html-header won't be modified * and the binary data will be displayed in the browser (in the best of * cases). * This can also be avoided using buffering in the PHP environment * See chapter LXXVIII. "Output Control Functions" of the PHP manual. ******************************/void workbook::Stroke(string filename){      SetStroke();      SETWORKBOOK();      DumpOleFile();}void workbook::Disposition(Stroke_Disposition_t disp){   m_Disposition = disp;}void workbook::Dump(string filename){   UnSetStroke();   Open(filename);   SETWORKBOOK()   DumpOleFile();}/************************************************************************/CUnit* workbook::DumpData(void){   bool repeat = false;   XTRACE("workbook::DumpData");   do   {      switch(m_DumpState)      {         case WB_INIT:            dump_not_started = true;            globalrec_size = 0;            current_sheet = 0;            offset = 0;            CHANGE_DUMPSTATE(WB_GLOBALRECORDS);            repeat = true;            break;         case WB_GLOBALRECORDS:            XTRACE("\tGLOBALRECORDS");            repeat = false;            if(dump_not_started)            {// the following code is executed only if this is the first pas to the first dump-state               // Basically, streampositions of BoundingSheet records are initialized.               dump_not_started = false;               globalrec_size = m_GlobalRecords.GetSize();               offset =  globalrec_size;               unsigned32_t offset_from_globalrecs = 0;               if(!m_Sheets.empty())               {                  Boundsheet_List_Itor_t bs = m_GlobalRecords.GetFirstBoundSheet();                  for(unsigned16_t i = 0; i < m_Sheets.size(); i++)                  {                     (*bs) -> streampos = globalrec_size + offset_from_globalrecs;                     m_GlobalRecords.GetBoundingSheets(bs);                     offset_from_globalrecs += m_Sheets[i]->GetSize();                  }               }               else               {                  //Nothing else to do.               }               //TODO: Add other EOF/BOF blocks here            }            m_pCurrentData = m_GlobalRecords.DumpData();            if(m_pCurrentData == NULL)            {               if(!m_Sheets.empty())               {                  // get in advance the first record of the first sheet                  //m_pCurrentData = m_Sheets[0].DumpData(globalrec_size);                  repeat = true;                  CHANGE_DUMPSTATE(WB_SHEETS);               }               else               {                  // Nothing else to do. Branch to the FINISH state                  m_pCurrentData = NULL;                  CHANGE_DUMPSTATE(WB_FINISH);               }            }            else            {               // Do nothing. Continue in this state.            }            break;         case WB_SHEETS:         {            XTRACE("\tSHEETS");            repeat = false;            // If I got here, there's at least one sheet which has already            // sent the first record block of data.            //m_GlobalRecords.GetSize();            m_pCurrentData = m_Sheets[current_sheet]->DumpData(offset);            if(m_pCurrentData == NULL)            {               if((unsigned16_t)(current_sheet+1) < m_Sheets.size())               {                  // Update the offset for the next sheet                  offset += m_Sheets[current_sheet]->GetSize();                  current_sheet++;                  // ... and get the first record of the next sheet.                  // m_pCurrentData = m_Sheets[current_sheet].DumpData(offset);                  repeat = true;               }               else               {                  // I'm done with all the sheets                  // Nothing else to do. Branch to the FINISH state                  CHANGE_DUMPSTATE(WB_FINISH);                  repeat = true;               }            }            break;         }         case WB_FINISH:            XTRACE("\tFINISH");            repeat = false;            m_pCurrentData  = NULL;            CHANGE_DUMPSTATE(WB_INIT);            break;         case WB_CONTINUE_REC:            repeat = false;            if(m_ContinueIndex == 0)            {               //Create a new data unit containing the max data size               m_pContinueRecord = (CUnit*)(new CRecord());               // The real size of the record is the size of the buffer minus the               // size of the header record               ((CUnit*)(m_pContinueRecord))->AddDataArray(((CRecord*)m_pCurrentData)->GetRecordDataBuffer(),MAX_RECORD_SIZE_BIFF57);               ((CRecord*)(m_pContinueRecord))->SetRecordType(((CRecord*)m_pCurrentData)->GetRecordType());               ((CRecord*)(m_pContinueRecord))->SetRecordLength(MAX_RECORD_SIZE_BIFF57);//        m_pContinueRecord->SetValueAt(MAX_RECORD_SIZE_BIFF57-4,2);               m_ContinueIndex++;               return m_pContinueRecord;            }            else            {               //Delete_Pointer(m_pContinueRecord);               // Get a pointer to the next chunk of data               unsigned8_t* pdata = (((CRecord*)m_pCurrentData)->GetRecordDataBuffer()) + m_ContinueIndex*MAX_RECORD_SIZE_BIFF57;               // Get the size of the chunk of data (that is the MAX_REC_SIZE except by the last one)               unsigned32_t csize = 0;               if(( ((CRecord*)m_pCurrentData)->GetRecordDataSize()/MAX_RECORD_SIZE_BIFF57) > (m_ContinueIndex))               {                  csize = MAX_RECORD_SIZE_BIFF57;                  m_ContinueIndex++;                  m_pContinueRecord =(CUnit*) ( new CContinue(pdata, csize));                  return m_pContinueRecord;               }               else               {                  unsigned32_t data_size = ((CRecord*)m_pCurrentData)->GetRecordDataSize();                  csize = (data_size - (m_ContinueIndex) * MAX_RECORD_SIZE_BIFF57);                  // Restore the previous state (*Don't use the macro*)                  m_DumpState = m_PreviousDumpState;                  m_PreviousDumpState = WB_CONTINUE_REC;                  m_ContinueIndex = 0;                  if(csize)                  {                     m_pContinueRecord = (CUnit*) new CContinue(pdata, csize);                     Delete_Pointer(m_pCurrentData);                     return m_pContinueRecord;                  }                  else                  {                     Delete_Pointer(m_pCurrentData);                     repeat = true;                  }               }            }            break;         default:            XTRACE("\tDEFAULT");            break;      }      if(m_pCurrentData != NULL)         if(((CRecord*)m_pCurrentData)->GetRecordDataSize() >= MAX_RECORD_SIZE_BIFF57 &&            m_DumpState != WB_CONTINUE_REC)         {            // Save the current dump satate and change to the CONTINUE Record state            CHANGE_DUMPSTATE(WB_CONTINUE_REC);            m_ContinueIndex = 0;            repeat = true;         }   }while(repeat);   return m_pCurrentData;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * $Log: workbook.cpp,v $ * Revision 1.2  2004/09/01 00:47:21  darioglz * + Modified to gain independence of target * * Revision 1.1.1.1  2004/08/27 16:31:49  darioglz * Initial Import. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -