📄 binimp.c
字号:
/*------------------------------------------------------------------------------*
* File Name: BinImp.c *
* Creation: LY 11/4/2002 *
* Purpose: OriginC Source C file *
* Copyright (c) Originlab Corp. 2002 *
* All Rights Reserved *
* *
* Modification Log: *
* JCG 05/29/03 v7.0594 FIX_BUG_29_ORIGIN_SUSPENDS *
* EJP 06-23-2003 IMPROVE_IMPORT_SPEED *
* EJP 07-23-2003 v7.0631 QA70-4575 ADD_SKIPROWS_TO_BINIMP *
* EJP 08-07-2003 v7.0649 FIX_BINIMP_DATA_TYPE_MACROS *
* EJP 09-12-2003 v7.5693 QA70-5073 ADD_READROWS_TO_BINIMP *
*------------------------------------------------------------------------------*/
////////////////////////////////////////////////////////////////////////////////////
#include <origin.h> // main Origin C header, has precompiled file
#include "Wks_Utils.h" // wuRenameToFileName function
#include "BinImp.h" // Function prototypes and non-localized constants
////////////////////////////////////////////////////////////////////////////////////
#define IMPROVE_IMPORT_SPEED
////////////////////////////////////////////////////////////////////////////////////
//utility function prototype used by binary import
////////////////////////////////////////////////////////////////////////////////////
#define GET_NUMOFCOLS_FROM_FILE(_pbi) ( pbi->iPartial ? (pbi->iPartialC2 - pbi->iPartialC1+1)\
: pbi->iNumColumns )
/// EJP 08-07-2003 v7.0649 FIX_BINIMP_DATA_TYPE_MACROS
///#define IS_TYPE_REAL(_type) ((_type & BIP_FLAG_REAL) && (_type & BIP_FLAG_SIGNED))
///#define IS_TYPE_INT(_type) (_type & BIP_TYPE_INT)
///#define IS_TYPE_UINT(_type) (_type & BIP_TYPE_UINT)
///#define IS_TYPE_STRING(_type) (_type & BIP_TYPE_STRING)
#define IS_TYPE_REAL(_type) (_type == BIP_TYPE_REAL)
#define IS_TYPE_INT(_type) (_type == BIP_TYPE_INT)
#define IS_TYPE_UINT(_type) (_type == BIP_TYPE_UINT)
#define IS_TYPE_STRING(_type) (_type == BIP_TYPE_STRING)
/// end FIX_BINIMP_DATA_TYPE_MACROS
/// EJP 06-23-2003 IMPROVE_IMPORT_SPEED
#ifndef IMPROVE_IMPORT_SPEED
/// end IMPROVE_IMPORT_SPEED
//data type used in file import
typedef struct tagPOSITION_IDX {
int nRow;
int nCol;
} POSITION_IDX;
//global variables
static POSITION_IDX s_Pos;
static LONG s_nFullRowSize = 0;
static LONG s_nBeforeRange = 0;
static LONG s_nAfterRange = 0;
/// EJP 06-23-2003 IMPROVE_IMPORT_SPEED
#else // IMPROVE_IMPORT_SPEED
/// end IMPROVE_IMPORT_SPEED
static LONG s_nStartCol = 0;
static LONG s_nStartRow = 0;
/// EJP 06-23-2003 IMPROVE_IMPORT_SPEED
static LONG s_lRowSizeInBytes;
static BYTE *s_pbyRowBuffer;
static LONG s_lBytesBeforePartial;
static int s_iFirstParamVecElement;
static int s_iFirstParamCount;
static int s_iLastParamVecElement;
static int s_iLastParamCount;
#endif // IMPROVE_IMPORT_SPEED
/// end IMPROVE_IMPORT_SPEED
////////////////////////////////////////////////////////////////////////////////////
// functions
/**
Import binary data file into a worksheet based on the description struct filled in by user.
Example:
Parameters:
wks = The worksheet object
lpcszFile = Binary data file name
pbi = Struct defined in OC_types.h file to descript binary data format
Return:
Returns 0 to indicate import successful. Non-zero value means error
*/
int wuImportBinary(Worksheet &wks, LPCSTR lpcszFile, BINIMP *pbi)
{
if( pbi->vParamType.GetSize() == 0 )
return BIN_INVALID_ARGUMENT;
if( !wks.IsValid() || lpcszFile == NULL || pbi == NULL )
{
printf("Invalid object in arguments\n");
return BIN_INVALID_ARGUMENT;
}
/// EJP 06-23-2003 IMPROVE_IMPORT_SPEED
#ifndef IMPROVE_IMPORT_SPEED
/// end IMPROVE_IMPORT_SPEED
file fDataFile;
int iRet = 0;
//open the binary file
if( !fDataFile.Open(lpcszFile, file::modeRead | file::typeBinary) )
{
printf("Error to open file %s\n", lpcszFile);
return BIN_OPEN_FILE_FAILURE;
}
/// EJP 06-23-2003 IMPROVE_IMPORT_SPEED
#endif // IMPROVE_IMPORT_SPEED
/// end IMPROVE_IMPORT_SPEED
/// EJP the worksheet is setup before import is called
/// //intialize the worksheet
/// if( !initWorksheet(wks, pbi) )
/// {
/// fDataFile.Close();
/// return BIN_FAIL_INIT_WKS;
/// }
//rename the worksheet
/// EJP 06-23-2003 IMPROVE_IMPORT_SPEED
/*
if( pbi->iRenameWks && !wuRenameToFileName(wks, lpcszFile) )
{
fDataFile.Close();
return BIN_FAIL_RENAME_WKS;
}
*/
/// EJP 06-27-2003 CENTRALIZE_RENAME_WKS_ON_IMPORT, Moved to fileimport.c
///if( pbi->iRenameWks )
/// wuRenameToFileName(wks, lpcszFile);
/// end CENTRALIZE_RENAME_WKS_ON_IMPORT
/// end IMPROVE_IMPORT_SPEED
/// EJP 06-23-2003 IMPROVE_IMPORT_SPEED
#ifndef IMPROVE_IMPORT_SPEED
/// end IMPROVE_IMPORT_SPEED
return importData(wks, fDataFile, pbi);
/// EJP 06-23-2003 IMPROVE_IMPORT_SPEED
#else // IMPROVE_IMPORT_SPEED
return import_binary_file(wks, lpcszFile, *pbi);
#endif // IMPROVE_IMPORT_SPEED
/// end IMPROVE_IMPORT_SPEED
}
////////////////////////////////////////////////////////////////////////////////////
//Implement utility functions to support binary import
////////////////////////////////////////////////////////////////////////////////////
#ifdef JUNK
/**
initialize the worksheet: append columns, set type or rename worksheet if required
*/
static BOOL initWorksheet(Worksheet& wks, BINIMP *pbi)
{
int iColsFromFile = GET_NUMOFCOLS_FROM_FILE(pbi);
int iAddNumColumns = 0;
int iNumCols = wks.GetNumCols();
switch( pbi->iMode )
{
case ASCIMP_MODE_APPEND_COLS:
s_nStartRow = 0; // Start from first row
int iUpper = 0, iLower = 0, iCol = 0;
foreach(Column cc in wks.Columns)
{
cc.GetRange(iLower, iUpper);
if( iLower == 0 && iUpper == -1 )
break;
iCol++;
}
s_nStartCol = iCol;
if( s_nStartCol + iColsFromFile > iNumCols )
iAddNumColumns = s_nStartCol + iColsFromFile - iNumCols;
break;
case ASCIMP_MODE_APPEND_ROWS:
s_nStartCol = 0; // Start from first column
Dataset dd(wks, 0);
if( dd.IsValid() )
s_nStartRow = dd.GetSize();
else
s_nStartRow = 0;
if( iColsFromFile > iNumCols )
iAddNumColumns = iColsFromFile - iNumCols;
break;
case ASCIMP_MODE_REPLACE_DATA:
default:
//delete all columns from worksheet
while( wks.DeleteCol(0) )
;
iAddNumColumns = iColsFromFile;
s_nStartCol = 0; // Start from first column
s_nStartRow = 0; // Start from first row
break;
}
for( int ii = 0; ii < iAddNumColumns; ii++)
{
wks.AddCol();
//if pbi->iAutoColType evaluates true
//set the new column to the colsest data
//type of the element data type
if( pbi->iAutoColTypes )
{
int nIndexBase = pbi->iPartial ? pbi->iPartialC1 : 0;
byte byDataType = 0;
UINT nElementSize = getRowElementInfo(pbi, iNumCols + ii + nIndexBase, byDataType);
Column colObj(wks, iNumCols + ii);
if( IS_TYPE_REAL(byDataType) ) //real number
{
colObj.SetFormat(OKCOLTYPE_NUMERIC);
if( nElementSize <= sizeof(float) )
colObj.SetInternalData(FSI_REAL);
else
colObj.SetInternalData(FSI_DOUBLE);
}
else if( IS_TYPE_INT(byDataType) || IS_TYPE_UINT(byDataType) ) //int or UINT
{
colObj.SetFormat(OKCOLTYPE_NUMERIC);
colObj.SetInternalData(FSI_LONG );
}
else if( IS_TYPE_STRING(byDataType) ) //string
{
colObj.SetFormat(OKCOLTYPE_TEXT);
}
} //end auto type setting
}
return TRUE;
}
#endif JUNK
/// EJP 06-23-2003 IMPROVE_IMPORT_SPEED
#ifndef IMPROVE_IMPORT_SPEED
/// end IMPROVE_IMPORT_SPEED
/**
initialize the global varaiables
*/
static void initGlobalVar()
{
//reset global variable
s_Pos.nRow = 0;
s_Pos.nCol = 0;
s_nFullRowSize = 0;
s_nBeforeRange = 0;
s_nAfterRange = 0;
}
/**
import binary data. It will do that by setting each cell in the worksheet
*/
static int importData(Worksheet& wks, file& fDataFile, BINIMP *pbi)
{
if( !fDataFile.IsOpen() || !wks.IsValid() )
return BIN_INVALID_ARGUMENT;
// init global variables
initGlobalVar();
// get file size
///LONG nSize = getFileLength(fDataFile);
LONG nSize = fDataFile.GetLength();
// skip the header section
fDataFile.Seek(pbi->iHeaderBytes, file::begin);
int nRetCode = BIN_SUCCEED;
POSITION_IDX wksPos;
int nRowIndex = s_nStartRow;
int nUpperBound = wks.GetNumRows();
int iColsFromFile = GET_NUMOFCOLS_FROM_FILE(pbi);
while( fDataFile.GetPosition() < nSize )
{
// increase worksheet row number, the step is 50
if( nRowIndex == nUpperBound )
{
wks.AppendRows(50);
nUpperBound = wks.GetNumRows();
}
// read data from file, fill in one row in worksheet
for( int ii = s_nStartCol; ii < s_nStartCol + iColsFromFile; ii++ )
{
// position for the cell in the worksheet
wksPos.nRow = nRowIndex;
wksPos.nCol = ii;
nRetCode = setWksCellData(wks, wksPos, fDataFile, pbi);
if( BIN_SUCCEED != nRetCode )
{
fDataFile.Close();
return nRetCode;
}
}
// check if partial import range is done
if( isPartialImportDone(nRowIndex, pbi) )
break;
nRowIndex++;
}
fDataFile.Close();
return BIN_SUCCEED;
}
/**
get number of bytes in a row upto the column index
the nColIndex is the column index in the binary data file
*/
static LONG GetByteOffsetOfDataColumn(BINIMP &binimp, int nColIndex)
{
LONG nBytes = 0;
//vParamType, vParamSize and vParamCount vectors have the same size
int nSize = binimp.vParamType.GetSize();
int nColIndexInFile = 0;
for( int ii=0; ii<nSize; ii++ )
{
int nTemp = binimp.vParamCount[ii];
if( nColIndex < nColIndexInFile + nTemp )
nTemp = nColIndex - nColIndexInFile;
nColIndexInFile += nTemp;
nBytes += nTemp * binimp.vParamSize[ii];
if( nColIndexInFile == nColIndex )
break;
}
return nBytes;
}
/**
get an element data type and data type size
the nIndex is the column index in the binary data file
*/
static UINT getRowElementInfo(BINIMP *pbi, int nIndex, byte& byType)
{
UINT nBytes = 0;
//vParamType, vParamSize and vParamCount vectors have the same size
int nSize = pbi->vParamType.GetSize();
int nColIndexInFile = 0;
for( int ii=0; ii<nSize; ii++ )
{
int nTemp = pbi->vParamCount[ii];
if( nIndex < nColIndexInFile + nTemp )
nTemp = nIndex - nColIndexInFile;
else
{
nColIndexInFile += nTemp;
continue;
}
nColIndexInFile += nTemp;
if( nColIndexInFile == nIndex )
{
nBytes = pbi->vParamSize[ii];
byType = pbi->vParamType[ii];
break;
}
}
return nBytes;
}
/**
check if partial import has done import for all range
*/
static bool isPartialImportDone(int nRowIndex, BINIMP *pbi)
{
if( pbi->iPartial && pbi->iPartialR2 >= 0 )
if( nRowIndex == (pbi->iPartialR2 - pbi->iPartialR1) )
return true;
return false;
}
/**
set each worksheet cell
*/
static int setWksCellData(Worksheet& wks, POSITION_IDX& wksPos, file& fDataFile, BINIMP *pbi)
{
if( !fDataFile.IsOpen() || !wks.IsValid() )
return BIN_INVALID_ARGUMENT;
int nRowInFile = 0, nColInFile = 0;
int nStartPartialImport = 0;
int iRowInWks = wksPos.nRow - s_nStartRow;
int iColInWks = wksPos.nCol - s_nStartCol;
POSITION_IDX filePos;
filePos.nRow = iRowInWks;
filePos.nCol = iColInWks;
if( pbi->iPartial ) //compute partial import parameters
{
//initial three globale variables to indicate the block size in partial import
//s_nFullRowSize denotes bytes of a whole row
//s_nBeforeRange denotes bytes before the import col index in a row
//s_nAfterRange denotes bytes after the import col index in a row
if( 0 == s_nFullRowSize )
s_nFullRowSize = GetByteOffsetOfDataColumn(*pbi, pbi->iNumColumns);
if( 0 == s_nBeforeRange )
s_nBeforeRange = GetByteOffsetOfDataColumn(*pbi, pbi->iPartialC1);
if( 0 == s_nAfterRange )
s_nAfterRange = s_nFullRowSize - GetByteOffsetOfDataColumn(*pbi, pbi->iPartialC2 + 1);
//calculate row and col indexes in the partial impoer range
filePos.nRow = iRowInWks + pbi->iPartialR1;
filePos.nCol = iColInWks + pbi->iPartialC1;
//seek to the element before right the first element in the import range
//the import range indexes are 0 based
if( iRowInWks == 0 && iColInWks == 0 && nStartPartialImport == 0)
{
fDataFile.Seek(s_nFullRowSize*pbi->iPartialR1 + s_nBeforeRange, file::current);
nStartPartialImport = 1;
}
//seek to the beginning position of next row
else if( filePos.nRow == s_Pos.nRow + 1 && filePos.nCol == pbi->iPartialC1 )
{
fDataFile.Seek(s_nAfterRange + s_nBeforeRange, file::current);
}
}
return setCellFromFile(wks, wksPos, fDataFile, filePos, pbi);
}
/**
get the file size
*/
static LONG getFileLength(file& fDataFile)
{
if( !fDataFile.IsOpen() )
return 0;
LONG nCurPos = fDataFile.GetPosition();
LONG nSize = fDataFile.SeekToEnd();
//restore previous position
fDataFile.Seek(nCurPos, file::begin);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -