diff options
author | Fong Lin <pflin@novell.com> | 2010-10-08 17:04:46 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@novell.com> | 2010-10-08 17:04:46 +0100 |
commit | cc316b39d9110c536e1758a4f814738ca209bb02 (patch) | |
tree | 0ff290d366ff8fea16ebc7e7781cc14b563f9b37 /lotuswordpro/source/filter/bencont.cxx | |
parent | 949fa63a66adc1ba54a0c353afd66bb863024d27 (diff) |
Port of Lotus Word Pro filter, by Fong Lin and Noel Power
Diffstat (limited to 'lotuswordpro/source/filter/bencont.cxx')
-rw-r--r-- | lotuswordpro/source/filter/bencont.cxx | 716 |
1 files changed, 716 insertions, 0 deletions
diff --git a/lotuswordpro/source/filter/bencont.cxx b/lotuswordpro/source/filter/bencont.cxx new file mode 100644 index 000000000000..246f307937bf --- /dev/null +++ b/lotuswordpro/source/filter/bencont.cxx @@ -0,0 +1,716 @@ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: IBM Corporation + * + * Copyright: 2008 by IBM Corporation + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include "first.hxx" +#include "assert.h" +#include <stdio.h> +#include <sot/storinfo.hxx> +namespace OpenStormBento +{ + +// String definitions +const char gsBenMagicBytes[] = BEN_MAGIC_BYTES; + +/** +* New bento container from file stream +* @param pointer to length of bento file +* @param pointer to pointer of Bento Container object +* @return error code +*/ +ULONG BenOpenContainer(LwpSvStream * pStream, pLtcBenContainer * ppContainer) +{ + BenError Err; + + *ppContainer = NULL; + + if (NULL == pStream) + { + return BenErr_ContainerWithNoObjects; + } + + pLtcBenContainer pContainer = new LtcBenContainer(pStream); + if ((Err = pContainer->Open()) != BenErr_OK) // delete two inputs + { + delete pContainer; + return BenErr_InvalidTOC; + } + + *ppContainer = pContainer; + return BenErr_OK; +} +BenError +LtcBenContainer::Close() +{ + return BenErr_OK; +} + +LtcBenContainer::~LtcBenContainer() +{ + Close(); +} + +BenError +LtcBenContainer::Open() // delete two inputs +{ + BenError Err; + CBenTOCReader TOCReader(this); + if ((Err = TOCReader.ReadLabelAndTOC()) != BenErr_OK) + { + return Err; + } + return BenErr_OK; +} + +void +LtcBenContainer::Release() +{ + delete this; +} + +BenError +LtcBenContainer::RegisterPropertyName(const char * sPropertyName, + pCBenPropertyName * ppPropertyName) +{ + pCBenNamedObjectListElmt pPrevNamedObjectListElmt; + pCBenNamedObject pNamedObject = FindNamedObject(&cNamedObjects, + sPropertyName, &pPrevNamedObjectListElmt); + + if (pNamedObject != NULL) + { + if (! pNamedObject->IsPropertyName()) + return BenErr_NameConflict; + else *ppPropertyName = (pCBenPropertyName) pNamedObject; + } + else + { + pCBenIDListElmt pPrevObject; + if (FindID(&cObjects, cNextAvailObjectID, &pPrevObject) != NULL) + return BenErr_DuplicateObjectID; + + *ppPropertyName = new CBenPropertyName(this, cNextAvailObjectID, + (pCBenObject) pPrevObject, sPropertyName, pPrevNamedObjectListElmt); + ++cNextAvailObjectID; + } + + return BenErr_OK; +} + +BenError +LtcBenContainer::RegisterTypeName(const char * sTypeName, + pCBenTypeName * ppTypeName) +{ + pCBenNamedObjectListElmt pPrevNamedObjectListElmt; + pCBenNamedObject pNamedObject = FindNamedObject(&cNamedObjects, sTypeName, + &pPrevNamedObjectListElmt); + + if (pNamedObject != NULL) + { + if (! pNamedObject->IsTypeName()) + return BenErr_NameConflict; + else *ppTypeName = (pCBenTypeName) pNamedObject; + } + else + { + pCBenIDListElmt pPrevObject; + if (FindID(&cObjects, cNextAvailObjectID, &pPrevObject) != NULL) + return BenErr_DuplicateObjectID; + + *ppTypeName = new CBenTypeName(this, cNextAvailObjectID, + (pCBenObject) pPrevObject, sTypeName, pPrevNamedObjectListElmt); + ++cNextAvailObjectID; + } + + return BenErr_OK; +} + +BenError +LtcBenContainer::NewObject(pCBenObject * ppBenObject) +{ + pCBenIDListElmt pPrev; + if (FindID(&cObjects, cNextAvailObjectID, &pPrev) != NULL) + return BenErr_DuplicateObjectID; + + *ppBenObject = new CBenObject(this, cNextAvailObjectID, pPrev); + + ++cNextAvailObjectID; + return BenErr_OK; +} + +pCBenObject +LtcBenContainer::GetNextObject(pCBenObject pCurrObject) +{ + return (pCBenObject) cObjects.GetNextOrNULL(pCurrObject); +} + +pCBenObject +LtcBenContainer::FindNextObjectWithProperty(pCBenObject pCurrObject, + BenObjectID PropertyID) +{ + while ((pCurrObject = GetNextObject(pCurrObject)) != NULL) + if (pCurrObject->UseProperty(PropertyID) != NULL) + return pCurrObject; + + return NULL; +} + +pCBenObject +LtcBenContainer::FindObject(BenObjectID ObjectID) +{ + return (pCBenObject) FindID(&cObjects, ObjectID, NULL); +} + +/** +* Construction +* @param Bento file stream pointer +* @return +*/ +LtcBenContainer::LtcBenContainer(LwpSvStream * pStream) +{ + cpStream = pStream; + pStream->Seek(STREAM_SEEK_TO_END); + m_ulLength = pStream->Tell(); + pStream->Seek(STREAM_SEEK_TO_BEGIN); +} + +/** +* Read buffer fro bento file with specified buffer +* @date 07/05/2004 +* @param buffer pointer +* @param buffer size +* @param number of bytes read +* @return BenError +*/ +BenError LtcBenContainer::Read(BenDataPtr pBuffer, unsigned long MaxSize, + unsigned long * pAmtRead) +{ + *pAmtRead = cpStream->Read(pBuffer, MaxSize); + return BenErr_OK; +} +/** +* Read buffer from bento file with specified size +* @date 07/05/2004 +* @param buffer pointer +* @param number of bytes to be read +* @return BenError +*/ +BenError LtcBenContainer::ReadKnownSize(BenDataPtr pBuffer, unsigned long Amt) +{ + ULONG ulLength; + ulLength = cpStream->Read(pBuffer, Amt); + if(ulLength == Amt) + { + return BenErr_OK; + } + return BenErr_ReadPastEndOfContainer; +} +/** +* Seek to position from the beginning of the bento file +* @date 07/05/2004 +* @param position in container file from beginning +* @return BenError +*/ +BenError LtcBenContainer::SeekToPosition(BenContainerPos Pos) +{ + cpStream->Seek(Pos); + return BenErr_OK; +} +/** +* Seek to position compare to end of bento file +* @date 07/05/2004 +* @param position in container file from end +* @return BenError +*/ +BenError LtcBenContainer::SeekFromEnd(long Offset) +{ + cpStream->Seek(STREAM_SEEK_TO_END); + cpStream->SeekRel(Offset); + + return BenErr_OK; +} +/** +* Get position in the bento file +* @date 07/05/2004 +* @param pointer of current position in container file from end +* @return BenError +*/ +BenError LtcBenContainer::GetPosition(BenContainerPos * pPosition) +{ + *pPosition = cpStream->Tell(); + return BenErr_OK; +} +/** +* Find the next value stream with property name +* @date 07/05/2004 +* @param string of property name +* @param current value stream pointer with the property name +* @return next value stream pointer with the property names +*/ +LtcUtBenValueStream * LtcBenContainer::FindNextValueStreamWithPropertyName(const char * sPropertyName, LtcUtBenValueStream * pCurrentValueStream) +{ + CBenPropertyName * pPropertyName; + RegisterPropertyName(sPropertyName, &pPropertyName); // Get property name object + + if (NULL == pPropertyName) + return NULL; // Property not exist + + // Get current object + CBenObject * pObj = NULL; + if (pCurrentValueStream != NULL) + { + pObj = pCurrentValueStream->GetValue()->GetProperty()->GetBenObject(); + } + + + pObj =FindNextObjectWithProperty(pObj, pPropertyName->GetID()); // Get next object with same property name + if (NULL == pObj) + return NULL; + + CBenValue * pValue; + LtcUtBenValueStream * pValueStream; + + pValue = pObj->UseValue(pPropertyName->GetID()); + + pValueStream = new LtcUtBenValueStream(pValue); + + return pValueStream; +} + +/** +* Find the unique value stream with property name +* @date 07/05/2004 +* @param string of property name +* @return the only value stream pointer with the property names +*/ +LtcUtBenValueStream * LtcBenContainer::FindValueStreamWithPropertyName(const char * sPropertyName) +{ + return FindNextValueStreamWithPropertyName(sPropertyName, NULL); +} +/** +* Find the unique value stream with property name and Object ID +* @date 10/24/2005 +* @param object ID +* @param string of property name +* @return the only value stream pointer with the property names +*/ +LtcUtBenValueStream * LtcBenContainer::FindObjectValueStreamWithObjectIDAndProperty(BenObjectID ObjectID, const char * sPropertyName) +{ + CBenPropertyName * pPropertyName; + RegisterPropertyName(sPropertyName, &pPropertyName); // Get property name object + if (NULL == pPropertyName) + return NULL; // Property not exist + // Get current object + CBenObject * pObj = NULL; + pObj = FindObject(ObjectID); // Get object with object ID + if (NULL == pObj) + return NULL; + CBenValue * pValue; + LtcUtBenValueStream * pValueStream; + pValue = pObj->UseValue(pPropertyName->GetID()); + pValueStream = new LtcUtBenValueStream(pValue); + return pValueStream; +} +/** +* <description> +* @date 07/05/2004 +* @param pointer to length of bento file +* @return BenError +*/ +BenError LtcBenContainer::GetSize(ULONG * pLength) +{ + *pLength = m_ulLength; + return BenErr_OK; +} + +sal_uInt32 GetSvStreamSize(SvStream * pStream) +{ + sal_uInt32 nCurPos = pStream->Tell(); + pStream->Seek(STREAM_SEEK_TO_END); + sal_uInt32 ulLength = pStream->Tell(); + pStream->Seek(nCurPos); + + return ulLength; +} +/** +* Find hazily according to part of property name +* @date 01/31/2005 +* @param +* @return the value stream pointers vector with the property names +*/ +BenError LtcBenContainer::CreateGraphicStreams(std::vector<SvStream *> * pStreamVector) +{ + /* traverse all named objects to find all the graphic property names */ + CBenObject * pObj= NULL; + char *pName; + std::vector<std::string> aGrPropertyVector ; + while(pObj = GetNextObject(pObj) ) + { + if(pObj->IsNamedObject()) + { + CBenNamedObject * pNamedObj = static_cast<CBenNamedObject *>(pObj); + if(!pNamedObj->IsPropertyName()) + continue; + + // Gr2E,41FDD458-S + // Gr2E,41FDD458-D + pName = const_cast<char *>(pNamedObj->GetName()); + if ( (pName[0] == 'G') + && (pName[1] == 'r') + &&( (pName[14] == 'D') || (pName[14] == 'S') ) ) + { + aGrPropertyVector.push_back(std::string(pName)); + } + } + } + + /* traverse the found properties and construct the stream vectors */ + std::vector<std::string>::iterator itor; + for (itor = aGrPropertyVector.begin(); itor != aGrPropertyVector.end(); itor ++) + { + // get property names with suffix of S&D + char sSName[32], sDName[32]; + strcpy(sSName, itor->c_str()); + strcpy(sDName, itor->c_str()); + sSName[14] = 'S'; + sDName[14] = 'D'; + + // erase strings in vector + std::vector<std::string>::iterator itorSearch; + for (itorSearch = aGrPropertyVector.begin(); itorSearch != aGrPropertyVector.end(); itorSearch ++) + { + if( (*itorSearch == sSName) || (*itorSearch == sDName) ) + { + std::vector<std::string>::iterator itorDel = itorSearch; + aGrPropertyVector.erase(itorDel); + } + } + + // get S&D's stream and merge them together + { + SvStream *pD = NULL, *pS = NULL; + + pS = FindValueStreamWithPropertyName(sSName); + assert(pS != NULL); + pD = FindValueStreamWithPropertyName(sDName); + assert(pD != NULL); + + sal_uInt32 nDLen = GetSvStreamSize(pD); + sal_uInt32 nLen = GetSvStreamSize(pS) + nDLen; + assert(nLen > 0); + char * pBuf = new char[nLen]; + assert(pBuf != NULL); + char * pPointer = pBuf; + pD->Read(pPointer, nDLen); + pPointer += nDLen; + pS->Read(pPointer, nLen - nDLen); + + delete pS; + delete pD; + + SvMemoryStream * pStream = new SvMemoryStream(pBuf, nLen, STREAM_READ); + assert(pStream != NULL); + + pStreamVector->push_back(pStream); + } + } + + aGrPropertyVector.clear(); + return BenErr_OK; +} + +/** +* Find hazily according to object ID +* @date 01/31/2005 +* @param pObjectname - format as "GrXX,XXXXXXXX" wherein XX is high part of object ID, and XXXXXXXX is low part +* @return the value stream pointers with the property names +*/ +BenError LtcBenContainer::CreateGraphicStream(SvStream * &pStream, const char *pObjectName) +{ + if (!pObjectName) + { + pStream = NULL; + return BenErr_NamedObjectError; + } + // construct the string of property name + char sSName[64]=""; + char sDName[64]=""; + + sprintf(sSName, "%s-S", pObjectName); + sprintf(sDName, "%s-D", pObjectName); + + /* traverse the found properties and construct the stream vectors */ + SvMemoryStream * pMemStream = NULL; + // get S&D's stream and merge them together + SvStream *pD = NULL, *pS = NULL; + + pS = FindValueStreamWithPropertyName(sSName); + pD = FindValueStreamWithPropertyName(sDName); + + + sal_uInt32 nDLen = 0; + if(pD) + { + nDLen = GetSvStreamSize(pD); + } + sal_uInt32 nLen = nDLen; + if(pS) + { + nLen += GetSvStreamSize(pS) ; + } + + assert(nLen > 0); + char * pBuf = new char[nLen]; + assert(pBuf != NULL); + char * pPointer = pBuf; + if(pD) + { + pD->Read(pPointer, nDLen); + delete pD; + } + pPointer += nDLen; + if(pS) + { + pS->Read(pPointer, nLen - nDLen); + delete pS; + } + + pMemStream = new SvMemoryStream(pBuf, nLen, STREAM_READ); + assert(pMemStream != NULL); + + pStream = pMemStream; + return BenErr_OK; +} +/** +* Find ole object stream according to object name +* @date 10/24/2005 +* @param +* @return the value ole storage stream pointers +*/ +#include <tools/globname.hxx> +SotStorageStreamRef LtcBenContainer::ConvertAswStorageToOLE2Stream(const char * sObjectName) +{ + SotStorageStreamRef xOleObjStm; + + SvStream* pOleStorageStream = NULL; + //Get Ole Storage stream + AswEntry aEntry; + pOleStorageStream = FindOLEStorageStreamWithObjectName(sObjectName, aEntry); + + if( !pOleStorageStream ) + return xOleObjStm; + //Find it, create Ole stream + //xOleObjStm = new SotStorageStream(String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Ole-Object" ) )); + xOleObjStm = new SotStorageStream(String()); + if( xOleObjStm->GetError() ) + return xOleObjStm; + xOleObjStm->SetBufferSize( 0xff00 ); + + SotStorageRef xOleObjStor = new SotStorage( *xOleObjStm ); + if( xOleObjStor->GetError() ) + return xOleObjStm; + //Set class id + ClsId aClsId = aEntry.GetClassId(); + SvGlobalName aGName( aClsId.n1, aClsId.n2, aClsId.n3, aClsId.n4, + aClsId.n5, aClsId.n6,aClsId.n7,aClsId.n8, + aClsId.n9,aClsId.n10,aClsId.n11); + xOleObjStor->SetClass( aGName, 0, String()); + + xOleObjStor->SetVersion( SOFFICE_FILEFORMAT_60 ); + std::string aOleStreamName("OleStream"); + sal_uInt32 nDLen = 0; + nDLen = GetSvStreamSize(pOleStorageStream); + for(sal_uInt32 nIndex = 0; nIndex < nDLen / ASWENTRY_SIZE; nIndex ++) + { + AswEntry aOleEntry; + ReadAswEntry(pOleStorageStream, aOleEntry); + if(aOleEntry.GetType()== BEN_STGTY_STREAM) + { + SvStream* pOleStream = FindObjectValueStreamWithObjectIDAndProperty(aOleEntry.GetObjectID(), aOleStreamName.c_str()); + if(pOleStream) + { + String strName; + aOleEntry.GetName(strName); + SotStorageStreamRef xStm = xOleObjStor->OpenSotStream( strName ); + if( xStm->GetError() ) + break; + xStm->SetBufferSize( 8192 ); + (*pOleStream) >> (*xStm); + xStm->Commit(); + delete pOleStream; + pOleStream = NULL; + } + } + } + xOleObjStor->Commit(); + xOleObjStm->Commit(); + + return xOleObjStm; +} +/** +* Find ole object storage stream data according to object name +* @date 10/24/2005 +* @param +* @return the value ole storage stream data pointers +*/ +LtcUtBenValueStream* LtcBenContainer::FindOLEStorageStreamWithObjectName(const char * sObjectName, AswEntry& rEntry) +{ + if (!sObjectName) + return NULL; + + //Find OleRootStorage stream + std::string aRootStroageName("OleRootStorage"); + std::string aOleStroageName("OleStorage"); + LtcUtBenValueStream* pRootStream = NULL; + pRootStream = FindValueStreamWithPropertyName(aRootStroageName.c_str()); + if(!pRootStream) + return NULL; + //Read root storage data and find the ole storage object id according to the object name + sal_uInt32 nDLen = 0; + nDLen = GetSvStreamSize(pRootStream); + for(sal_uInt32 nIndex = 0; nIndex < nDLen / ASWENTRY_SIZE; nIndex ++) + { + //Get entry + ReadAswEntry(pRootStream, rEntry); + String sObjName; + rEntry.GetName(sObjName); + if(sObjName.EqualsAscii(sObjectName)) + { + //Find it + delete pRootStream; + return FindObjectValueStreamWithObjectIDAndProperty(rEntry.GetObjectID(), aOleStroageName.c_str()); + } + } + + // Not find + if(pRootStream) + { + delete pRootStream; + } + + return NULL; +} +void LtcBenContainer::ReadAswEntry(SvStream * pStream, AswEntry & rEntry) +{ + char* pBuf = new char[ASWENTRY_SIZE]; + pStream->Read(pBuf, ASWENTRY_SIZE); + rEntry.Load(pBuf); + delete[] pBuf; +} +//////////////////////////////////////////////////////////////////// +//classs AswEntry +AswEntry::AswEntry() +{ + Init(); +} +void AswEntry::Init() +{ + memset( this, 0, sizeof (AswEntry)); +} +void AswEntry::SetName( const String& rName ) +{ + int i; + for( i = 0; i < rName.Len() && i < 68; i++ ) + nName[ i ] = rName.GetChar( i ); + while( i < 68 ) + nName[ i++ ] = 0; +} +void AswEntry::GetName(String & rName) const +{ + rName = nName; +} +void AswEntry::Store( void* pTo ) +{ + SvMemoryStream r( (sal_Char *)pTo, ASWENTRY_SIZE, STREAM_WRITE ); + for( short i = 0; i < 68; i++ ) + r << nName[ i ]; // 00 name as WCHAR + r<< nMtime[ 0 ] // 42 entry type + << nMtime[ 1 ] // 43 0 or 1 (tree balance?) + << nCtime[ 0 ] // 44 left node entry + << nCtime[ 1 ] // 48 right node entry + << nAtime[ 0 ] // 44 left node entry + << nAtime[ 1 ]; // 48 right node entry + r.Write(&aClsId ,16); // 50 class ID (optional) + r<< nStatebits // 60 state flags(?) + << nType + << nObjectIDRef // 64 modification time + << nMversion // 6C creation and access time + << nLversion // 6C creation and access time + << nReserved[ 0 ] // 74 starting block (either direct or translated) + << nReserved[ 1 ]; // 78 file size +} +void AswEntry::Load( const void* pFrom ) +{ + SvMemoryStream r( (sal_Char *)pFrom, ASWENTRY_SIZE, STREAM_WRITE ); + for( short i = 0; i < 68; i++ ) + r >> nName[ i ]; // 00 name as WCHAR + r>> nMtime[ 0 ] // 42 entry type + >> nMtime[ 1 ] // 43 0 or 1 (tree balance?) + >> nCtime[ 0 ] // 44 left node entry + >> nCtime[ 1 ] // 48 right node entry + >> nAtime[ 0 ] // 44 left node entry + >> nAtime[ 1 ]; // 48 right node entry + r.Read(&aClsId,16); // 50 class ID (optional) + r>> nStatebits // 60 state flags(?) + >> nType + >> nObjectIDRef // 64 modification time + >> nMversion // 6C creation and access time + >> nLversion // 6C creation and access time + >> nReserved[ 0 ] // 74 starting block (either direct or translated) + >> nReserved[ 1 ]; // 78 file size +} +void AswEntry::SetClassId( const ClsId& r ) +{ + memcpy( &aClsId, &r, sizeof( ClsId ) ); +} +/////////////////////////////////////////////////////////////////// +}// end namespace OpenStormBento |