📄 sheetrec.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/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 + -