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

📄 sheetrec.cpp

📁 xls文件格式分析基础库
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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/sheetrec.cpp,v $ * $Revision: 1.2 $ * $Author: darioglz $ * $Date: 2004/09/01 00:47:04 $ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * File description: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */#include "sheetrec.h"using namespace std;using namespace xlslib_core;/* * LOCAL MODULE MACROS */#if STORAGE_CELL==LIST_CONTAINER#define MARK_CELLS_UNSORTED() {                 \   m_CellsSorted = false;                       \   m_SizesCalculated = false;                   \   m_RBSizes.clear();                           \}#elif STORAGE_CELL==SET_CONTAINER#define MARK_CELLS_UNSORTED() {                 \   m_CellsSorted = false;                       \   m_SizesCalculated = false;                   \   m_RBSizes.clear();                           \}#endif#define MAX_ROWBLOCK_SIZE (32)#define RB_DBCELL_MINSIZE          (unsigned8_t(8))#define RB_DBCELL_CELLSIZEOFFSET   (unsigned8_t(2))using namespace std;/***********************************************************************worksheet class implementation***********************************************************************/worksheet::worksheet(CGlobalRecords* pglobalrec)   : m_DumpState(SHEET_INIT), m_pCurrentData(NULL),     m_Size(0),     m_CellsSorted(false),     m_SizesCalculated(false),     m_DumpRBState(RB_INIT),     m_DBCellOffset(0),     m_CurrentRowBlock(0){   m_pGlobalRecords = pglobalrec;}worksheet::~worksheet(){   if(!m_RBSizes.empty())      for(RBSize_List_Itor_t rbs = m_RBSizes.begin(); rbs != m_RBSizes.end(); rbs++)	 delete *rbs;   // Delete the dinamically created cell objects (pointers)      if(!m_Cells.empty())   {//      cout<<"worksheet::~worksheet(), this = "<<this<<endl;      for(Cell_List_Itor_t cell = m_Cells.begin(); cell != m_Cells.end(); cell++)         delete *cell;      m_Cells.clear();   }   // Delete dinamically allocated ranges of merged cells.   if(!m_MergedRanges.empty())   {      do      {         delete m_MergedRanges.front();         m_MergedRanges.pop_front();      }while(!m_MergedRanges.empty());   }   // Delete dinamically allocated Cellinfo record definitions   if(!m_Colinfos.empty())   {      for(Colinfo_List_Itor_t ci = m_Colinfos.begin(); ci != m_Colinfos.end(); ci++)         delete *ci;      m_Colinfos.clear();   }/*  if(!m_Colinfos.empty())  {  do  {  delete m_Colinfos.front();  m_Colinfos.pop_front();  }while(!m_Colinfos.empty());  }*/   // Delete dinamically allocated Cellinfo record definitions   if(!m_RowHeights.empty())   {      for(RowHeight_List_Itor_t rh = m_RowHeights.begin(); rh != m_RowHeights.end(); rh++)         delete *rh;      m_RowHeights.clear();   }/*  if(!m_RowHeights.empty())  {  do  {  delete m_RowHeights.front();  m_RowHeights.pop_front();  }while(!m_RowHeights.empty());  }*/   // Delete dinamically allocated range definitions   if(!m_Ranges.empty())   {      do      {         delete m_Ranges.front();         m_Ranges.pop_front();      }while(!m_Ranges.empty());   }}/************************************************************************/void worksheet::SortCells(){//// // Set containers don't need sorting// // // }/************************************************************************/#define RB_INDEX_MINSIZE ((unsigned8_t)16)CUnit* worksheet::DumpData(unsigned32_t offset){   bool repeat = false;      XTRACE("worksheet::DumpData");   do   {      switch(m_DumpState)      {         case SHEET_INIT:            m_DumpState = SHEET_BOF;            m_Current_Colinfo = m_Colinfos.begin();            repeat  = true;            break;         case SHEET_BOF:            XTRACE("\tBOF");            repeat = false;            //Delete_Pointer(m_pCurrentData);            m_pCurrentData = (CUnit*)(new CBof(BOF_TYPE_WORKSHEET));            m_DumpState = SHEET_INDEX;            break;         case SHEET_INDEX:         {            XTRACE("\tINDEX");            // Get first/last row from the list of row blocks            unsigned32_t first_row, last_row;            GetFirstLastRows(&first_row, &last_row);                   m_pCurrentData = (CUnit*)(new CIndex(first_row, last_row));            unsigned32_t numrb = GetNumRowBlocks();            unsigned32_t rb_size_acc = 0;            unsigned32_t index_size = RB_INDEX_MINSIZE + 4*numrb;            for(unsigned32_t rb = 0; rb < numrb; rb++)            {               // Get sizes of next RowBlock               unsigned32_t rowandcell_size, dbcell_size;               GetRowBlockSizes( &rowandcell_size, &dbcell_size);               // Update the offset accumulator and cerate the next DBCELL's offset               rb_size_acc += rowandcell_size;               unsigned32_t dbcelloffset = offset + BOF_RECORD_SIZE + index_size + rb_size_acc;               ((CIndex*)m_pCurrentData)->AddDBCellOffset(dbcelloffset);               // Update the offset for the next DBCELL's offset               rb_size_acc += dbcell_size;            }            m_DumpState = SHEET_ROWBLOCKS; // Change to the next state            break;         }         case SHEET_ROWBLOCKS:            XTRACE("\tROWBLOCKS");            if(GetNumRowBlocks())            {// First check if the list of RBs is not empty...                      m_pCurrentData = RowBlocksDump();               if(m_pCurrentData == NULL)               {                  repeat = true;                  m_DumpState = SHEET_MERGED;               }              }            else            {// if the list is empty, change the dump state.               repeat = true;               m_DumpState = SHEET_MERGED;            }                      break;         case SHEET_MERGED:            repeat = false;            XTRACE("\tMERGED");            if(!m_MergedRanges.empty())            {               m_pCurrentData = (CUnit*)(new CMergedCells());               ((CMergedCells*)m_pCurrentData)->SetNumRanges(m_MergedRanges.size());               for(Range_List_Itor_t mr = m_MergedRanges.begin(); mr != m_MergedRanges.end(); mr++)               {                  ((CMergedCells*)m_pCurrentData)->AddRange(*mr);               }                      }            else            {               repeat = true;            }            m_DumpState = SHEET_COLINFO;            break;         case SHEET_COLINFO:            repeat = false;            XTRACE("\tCOLINFO");            if(!m_Colinfos.empty())            {// First check if the list of fonts is not empty...               //Delete_Pointer(m_pCurrentData);               m_pCurrentData = (CUnit*)(new CColInfo(*m_Current_Colinfo));               if(m_Current_Colinfo != (--m_Colinfos.end()))               {// if it was'nt the last font from the list, increment to get the next one                  m_Current_Colinfo++;               }               else               {// if it was the last from the list, change the DumpState                  m_DumpState = SHEET_WINDOW2;                  m_Current_Colinfo = m_Colinfos.begin();               }            }            else            {// if the list is empty, change the dump state.               m_DumpState = SHEET_WINDOW2;               //font = m_Fonts.begin();               repeat = true;            }            break;         case SHEET_WINDOW2:            XTRACE("\tWINDOW2");            repeat = false;            //Delete_Pointer(m_pCurrentData);            m_pCurrentData = (CUnit*)(new CWindow2());            m_DumpState = SHEET_EOF;            break;         case SHEET_EOF:            XTRACE("\tEOF");            //Delete_Pointer(m_pCurrentData);            m_pCurrentData = (CUnit*)(new CEof());            m_DumpState = SHEET_FINISH;            break;         case SHEET_FINISH:            XTRACE("\tFINISH");            //Delete_Pointer(m_pCurrentData);            m_pCurrentData = NULL;            m_DumpState = SHEET_INIT;            break;      }   }while(repeat);   return m_pCurrentData;}CUnit* worksheet::RowBlocksDump(){   bool repeat = false;   CUnit* rb_record = NULL;   do   {      switch(m_DumpRBState)      {         case RB_INIT:            m_DumpRBState = RB_ROWS;            m_CurrentRowBlock = 0;            m_RowCounter = 0;            m_CurrentCell = m_Cells.begin();            // Initialize the row widths            m_Current_RowHeight = m_RowHeights.begin();            m_DumpRBState = RB_FIRST_ROW;            repeat = true;            break;         case RB_FIRST_ROW:            repeat = true;                   if( m_Cells.empty() || m_CurrentCell != m_Cells.end())             {               m_Starting_RBCell = m_CurrentCell;                     m_CellCounter = 0;               m_DBCellOffset = 0;               m_CellOffsets.clear();               m_DumpRBState = RB_ROWS;            }            else            {               m_DumpRBState = RB_FINISH;            }            break;         case RB_ROWS:         {            repeat = false;            // Initialize first/last cols to impossible values            // that are appropriate for the following detection algorithm            unsigned16_t first_col = (unsigned16_t)(-1);            unsigned16_t last_col  = 0;            unsigned16_t row_num = 0;            // Get the row number for the current row            row_num = (*m_CurrentCell)->GetRow();            Cell_List_Itor_t this_cell, next_cell;            do            {                         // Determine the first/last column of the current row               if((*m_CurrentCell)->GetCol() > last_col)                  last_col = (*m_CurrentCell)->GetCol();               if((*m_CurrentCell)->GetCol() < first_col)                  first_col = (*m_CurrentCell)->GetCol();               // To avoid dereference an empty iterator check if this is the only one cell               // in m_Cells list.               if(m_Cells.size() > 1)               {                  m_CellCounter++;                  this_cell = m_CurrentCell;                  next_cell = ++m_CurrentCell;                          // Break the while if there are no more cells                  if(next_cell == m_Cells.end())                     break;               }               else               {                  // Break the loop if this was the only cell.                              if(!m_Cells.empty())                  {                     m_CellCounter++;                     ++m_CurrentCell;                  }                  break;               }                        // The order in the following and-statement is important            }while( m_CurrentCell != (m_Cells.end()) && *(*this_cell) == *(*next_cell ));            // Check if the current row is in the list of height-set            // rows.            if(m_Current_RowHeight != m_RowHeights.end())            {               if((*m_Current_RowHeight)->GetRowNum() == row_num)               {                  rb_record = (CUnit*) (new CRow(row_num, first_col,                                                  last_col,                                                  (*m_Current_RowHeight)->GetRowHeight()) );                  m_Current_RowHeight++;                         }               else               {                  rb_record = (CUnit*) (new CRow(row_num, first_col, last_col) );               }            }            else            {               rb_record = (CUnit*) (new CRow(row_num, first_col, last_col) );            }            m_DBCellOffset += ROW_RECORD_SIZE;            // If the current row-block is full OR there are no more cells            if(++m_RowCounter >= MAX_ROWBLOCK_SIZE ||  m_CurrentCell == m_Cells.end())            {               if (m_CurrentCell == (--m_Cells.end()))                  m_CellCounter++;               m_RowCounter = 0;               m_DumpRBState = RB_FIRSTCELL;                    }                   break;         }         case RB_FIRSTCELL:            rb_record = (*m_Starting_RBCell)->GetData();                   // Update the offset to be used in the DBCell Record            m_DBCellOffset += rb_record->GetDataSize();            // The first cell of the rowblock has an offset that includes (among others)            // the rows size (without counting the first row)            m_CellOffsets.push_back(m_DBCellOffset -ROW_RECORD_SIZE);            // Update the pointer (iterator) to the next cell            if(--m_CellCounter == 0)            {// The RowBlock's cells are done               m_DumpRBState = RB_DBCELL;            }            else            {               m_Starting_RBCell++;               m_DumpRBState = RB_CELLS;            }            break;         case RB_CELLS:            repeat = false;            if(m_CellCounter == 0)            {// The RowBlock's cells are done               m_DumpRBState = RB_DBCELL;               repeat = true;            }            else            {               rb_record = (*m_Starting_RBCell)->GetData();               m_DBCellOffset += rb_record->GetDataSize();

⌨️ 快捷键说明

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