merge the formfield patch from ooo-build
[ooovba.git] / lotuswordpro / source / filter / bencont.cxx
blobc7bc0b4d1b1fd12d382a259c96d1085a09564085
1 /*************************************************************************
3 * The Contents of this file are made available subject to the terms of
4 * either of the following licenses
6 * - GNU Lesser General Public License Version 2.1
7 * - Sun Industry Standards Source License Version 1.1
9 * Sun Microsystems Inc., October, 2000
11 * GNU Lesser General Public License Version 2.1
12 * =============================================
13 * Copyright 2000 by Sun Microsystems, Inc.
14 * 901 San Antonio Road, Palo Alto, CA 94303, USA
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License version 2.1, as published by the Free Software Foundation.
20 * This library is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * Lesser General Public License for more details.
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * MA 02111-1307 USA
31 * Sun Industry Standards Source License Version 1.1
32 * =================================================
33 * The contents of this file are subject to the Sun Industry Standards
34 * Source License Version 1.1 (the "License"); You may not use this file
35 * except in compliance with the License. You may obtain a copy of the
36 * License at http://www.openoffice.org/license.html.
38 * Software provided under this License is provided on an "AS IS" basis,
39 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
40 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
41 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
42 * See the License for the specific provisions governing your rights and
43 * obligations concerning the Software.
45 * The Initial Developer of the Original Code is: IBM Corporation
47 * Copyright: 2008 by IBM Corporation
49 * All Rights Reserved.
51 * Contributor(s): _______________________________________
54 ************************************************************************/
55 #include "first.hxx"
56 #include "assert.h"
57 #include <stdio.h>
58 #include <sot/storinfo.hxx>
59 namespace OpenStormBento
62 // String definitions
63 const char gsBenMagicBytes[] = BEN_MAGIC_BYTES;
65 /**
66 * New bento container from file stream
67 * @param pointer to length of bento file
68 * @param pointer to pointer of Bento Container object
69 * @return error code
71 ULONG BenOpenContainer(LwpSvStream * pStream, pLtcBenContainer * ppContainer)
73 BenError Err;
75 *ppContainer = NULL;
77 if (NULL == pStream)
79 return BenErr_ContainerWithNoObjects;
82 pLtcBenContainer pContainer = new LtcBenContainer(pStream);
83 if ((Err = pContainer->Open()) != BenErr_OK) // delete two inputs
85 delete pContainer;
86 return BenErr_InvalidTOC;
89 *ppContainer = pContainer;
90 return BenErr_OK;
92 BenError
93 LtcBenContainer::Close()
95 return BenErr_OK;
98 LtcBenContainer::~LtcBenContainer()
100 Close();
103 BenError
104 LtcBenContainer::Open() // delete two inputs
106 BenError Err;
107 CBenTOCReader TOCReader(this);
108 if ((Err = TOCReader.ReadLabelAndTOC()) != BenErr_OK)
110 return Err;
112 return BenErr_OK;
115 void
116 LtcBenContainer::Release()
118 delete this;
121 BenError
122 LtcBenContainer::RegisterPropertyName(const char * sPropertyName,
123 pCBenPropertyName * ppPropertyName)
125 pCBenNamedObjectListElmt pPrevNamedObjectListElmt;
126 pCBenNamedObject pNamedObject = FindNamedObject(&cNamedObjects,
127 sPropertyName, &pPrevNamedObjectListElmt);
129 if (pNamedObject != NULL)
131 if (! pNamedObject->IsPropertyName())
132 return BenErr_NameConflict;
133 else *ppPropertyName = (pCBenPropertyName) pNamedObject;
135 else
137 pCBenIDListElmt pPrevObject;
138 if (FindID(&cObjects, cNextAvailObjectID, &pPrevObject) != NULL)
139 return BenErr_DuplicateObjectID;
141 *ppPropertyName = new CBenPropertyName(this, cNextAvailObjectID,
142 (pCBenObject) pPrevObject, sPropertyName, pPrevNamedObjectListElmt);
143 ++cNextAvailObjectID;
146 return BenErr_OK;
149 BenError
150 LtcBenContainer::RegisterTypeName(const char * sTypeName,
151 pCBenTypeName * ppTypeName)
153 pCBenNamedObjectListElmt pPrevNamedObjectListElmt;
154 pCBenNamedObject pNamedObject = FindNamedObject(&cNamedObjects, sTypeName,
155 &pPrevNamedObjectListElmt);
157 if (pNamedObject != NULL)
159 if (! pNamedObject->IsTypeName())
160 return BenErr_NameConflict;
161 else *ppTypeName = (pCBenTypeName) pNamedObject;
163 else
165 pCBenIDListElmt pPrevObject;
166 if (FindID(&cObjects, cNextAvailObjectID, &pPrevObject) != NULL)
167 return BenErr_DuplicateObjectID;
169 *ppTypeName = new CBenTypeName(this, cNextAvailObjectID,
170 (pCBenObject) pPrevObject, sTypeName, pPrevNamedObjectListElmt);
171 ++cNextAvailObjectID;
174 return BenErr_OK;
177 BenError
178 LtcBenContainer::NewObject(pCBenObject * ppBenObject)
180 pCBenIDListElmt pPrev;
181 if (FindID(&cObjects, cNextAvailObjectID, &pPrev) != NULL)
182 return BenErr_DuplicateObjectID;
184 *ppBenObject = new CBenObject(this, cNextAvailObjectID, pPrev);
186 ++cNextAvailObjectID;
187 return BenErr_OK;
190 pCBenObject
191 LtcBenContainer::GetNextObject(pCBenObject pCurrObject)
193 return (pCBenObject) cObjects.GetNextOrNULL(pCurrObject);
196 pCBenObject
197 LtcBenContainer::FindNextObjectWithProperty(pCBenObject pCurrObject,
198 BenObjectID PropertyID)
200 while ((pCurrObject = GetNextObject(pCurrObject)) != NULL)
201 if (pCurrObject->UseProperty(PropertyID) != NULL)
202 return pCurrObject;
204 return NULL;
207 pCBenObject
208 LtcBenContainer::FindObject(BenObjectID ObjectID)
210 return (pCBenObject) FindID(&cObjects, ObjectID, NULL);
214 * Construction
215 * @param Bento file stream pointer
216 * @return
218 LtcBenContainer::LtcBenContainer(LwpSvStream * pStream)
220 cpStream = pStream;
221 pStream->Seek(STREAM_SEEK_TO_END);
222 m_ulLength = pStream->Tell();
223 pStream->Seek(STREAM_SEEK_TO_BEGIN);
227 * Read buffer fro bento file with specified buffer
228 * @date 07/05/2004
229 * @param buffer pointer
230 * @param buffer size
231 * @param number of bytes read
232 * @return BenError
234 BenError LtcBenContainer::Read(BenDataPtr pBuffer, unsigned long MaxSize,
235 unsigned long * pAmtRead)
237 *pAmtRead = cpStream->Read(pBuffer, MaxSize);
238 return BenErr_OK;
241 * Read buffer from bento file with specified size
242 * @date 07/05/2004
243 * @param buffer pointer
244 * @param number of bytes to be read
245 * @return BenError
247 BenError LtcBenContainer::ReadKnownSize(BenDataPtr pBuffer, unsigned long Amt)
249 ULONG ulLength;
250 ulLength = cpStream->Read(pBuffer, Amt);
251 if(ulLength == Amt)
253 return BenErr_OK;
255 return BenErr_ReadPastEndOfContainer;
258 * Seek to position from the beginning of the bento file
259 * @date 07/05/2004
260 * @param position in container file from beginning
261 * @return BenError
263 BenError LtcBenContainer::SeekToPosition(BenContainerPos Pos)
265 cpStream->Seek(Pos);
266 return BenErr_OK;
269 * Seek to position compare to end of bento file
270 * @date 07/05/2004
271 * @param position in container file from end
272 * @return BenError
274 BenError LtcBenContainer::SeekFromEnd(long Offset)
276 cpStream->Seek(STREAM_SEEK_TO_END);
277 cpStream->SeekRel(Offset);
279 return BenErr_OK;
282 * Get position in the bento file
283 * @date 07/05/2004
284 * @param pointer of current position in container file from end
285 * @return BenError
287 BenError LtcBenContainer::GetPosition(BenContainerPos * pPosition)
289 *pPosition = cpStream->Tell();
290 return BenErr_OK;
293 * Find the next value stream with property name
294 * @date 07/05/2004
295 * @param string of property name
296 * @param current value stream pointer with the property name
297 * @return next value stream pointer with the property names
299 LtcUtBenValueStream * LtcBenContainer::FindNextValueStreamWithPropertyName(const char * sPropertyName, LtcUtBenValueStream * pCurrentValueStream)
301 CBenPropertyName * pPropertyName;
302 RegisterPropertyName(sPropertyName, &pPropertyName); // Get property name object
304 if (NULL == pPropertyName)
305 return NULL; // Property not exist
307 // Get current object
308 CBenObject * pObj = NULL;
309 if (pCurrentValueStream != NULL)
311 pObj = pCurrentValueStream->GetValue()->GetProperty()->GetBenObject();
315 pObj =FindNextObjectWithProperty(pObj, pPropertyName->GetID()); // Get next object with same property name
316 if (NULL == pObj)
317 return NULL;
319 CBenValue * pValue;
320 LtcUtBenValueStream * pValueStream;
322 pValue = pObj->UseValue(pPropertyName->GetID());
324 pValueStream = new LtcUtBenValueStream(pValue);
326 return pValueStream;
330 * Find the unique value stream with property name
331 * @date 07/05/2004
332 * @param string of property name
333 * @return the only value stream pointer with the property names
335 LtcUtBenValueStream * LtcBenContainer::FindValueStreamWithPropertyName(const char * sPropertyName)
337 return FindNextValueStreamWithPropertyName(sPropertyName, NULL);
340 * Find the unique value stream with property name and Object ID
341 * @date 10/24/2005
342 * @param object ID
343 * @param string of property name
344 * @return the only value stream pointer with the property names
346 LtcUtBenValueStream * LtcBenContainer::FindObjectValueStreamWithObjectIDAndProperty(BenObjectID ObjectID, const char * sPropertyName)
348 CBenPropertyName * pPropertyName;
349 RegisterPropertyName(sPropertyName, &pPropertyName); // Get property name object
350 if (NULL == pPropertyName)
351 return NULL; // Property not exist
352 // Get current object
353 CBenObject * pObj = NULL;
354 pObj = FindObject(ObjectID); // Get object with object ID
355 if (NULL == pObj)
356 return NULL;
357 CBenValue * pValue;
358 LtcUtBenValueStream * pValueStream;
359 pValue = pObj->UseValue(pPropertyName->GetID());
360 pValueStream = new LtcUtBenValueStream(pValue);
361 return pValueStream;
364 * <description>
365 * @date 07/05/2004
366 * @param pointer to length of bento file
367 * @return BenError
369 BenError LtcBenContainer::GetSize(ULONG * pLength)
371 *pLength = m_ulLength;
372 return BenErr_OK;
375 sal_uInt32 GetSvStreamSize(SvStream * pStream)
377 sal_uInt32 nCurPos = pStream->Tell();
378 pStream->Seek(STREAM_SEEK_TO_END);
379 sal_uInt32 ulLength = pStream->Tell();
380 pStream->Seek(nCurPos);
382 return ulLength;
385 * Find hazily according to part of property name
386 * @date 01/31/2005
387 * @param
388 * @return the value stream pointers vector with the property names
390 BenError LtcBenContainer::CreateGraphicStreams(std::vector<SvStream *> * pStreamVector)
392 /* traverse all named objects to find all the graphic property names */
393 CBenObject * pObj= NULL;
394 char *pName;
395 std::vector<std::string> aGrPropertyVector ;
396 while(pObj = GetNextObject(pObj) )
398 if(pObj->IsNamedObject())
400 CBenNamedObject * pNamedObj = static_cast<CBenNamedObject *>(pObj);
401 if(!pNamedObj->IsPropertyName())
402 continue;
404 // Gr2E,41FDD458-S
405 // Gr2E,41FDD458-D
406 pName = const_cast<char *>(pNamedObj->GetName());
407 if ( (pName[0] == 'G')
408 && (pName[1] == 'r')
409 &&( (pName[14] == 'D') || (pName[14] == 'S') ) )
411 aGrPropertyVector.push_back(std::string(pName));
416 /* traverse the found properties and construct the stream vectors */
417 std::vector<std::string>::iterator itor;
418 for (itor = aGrPropertyVector.begin(); itor != aGrPropertyVector.end(); itor ++)
420 // get property names with suffix of S&D
421 char sSName[32], sDName[32];
422 strcpy(sSName, itor->c_str());
423 strcpy(sDName, itor->c_str());
424 sSName[14] = 'S';
425 sDName[14] = 'D';
427 // erase strings in vector
428 std::vector<std::string>::iterator itorSearch;
429 for (itorSearch = aGrPropertyVector.begin(); itorSearch != aGrPropertyVector.end(); itorSearch ++)
431 if( (*itorSearch == sSName) || (*itorSearch == sDName) )
433 std::vector<std::string>::iterator itorDel = itorSearch;
434 aGrPropertyVector.erase(itorDel);
438 // get S&D's stream and merge them together
440 SvStream *pD = NULL, *pS = NULL;
442 pS = FindValueStreamWithPropertyName(sSName);
443 assert(pS != NULL);
444 pD = FindValueStreamWithPropertyName(sDName);
445 assert(pD != NULL);
447 sal_uInt32 nDLen = GetSvStreamSize(pD);
448 sal_uInt32 nLen = GetSvStreamSize(pS) + nDLen;
449 assert(nLen > 0);
450 char * pBuf = new char[nLen];
451 assert(pBuf != NULL);
452 char * pPointer = pBuf;
453 pD->Read(pPointer, nDLen);
454 pPointer += nDLen;
455 pS->Read(pPointer, nLen - nDLen);
457 delete pS;
458 delete pD;
460 SvMemoryStream * pStream = new SvMemoryStream(pBuf, nLen, STREAM_READ);
461 assert(pStream != NULL);
463 pStreamVector->push_back(pStream);
467 aGrPropertyVector.clear();
468 return BenErr_OK;
472 * Find hazily according to object ID
473 * @date 01/31/2005
474 * @param pObjectname - format as "GrXX,XXXXXXXX" wherein XX is high part of object ID, and XXXXXXXX is low part
475 * @return the value stream pointers with the property names
477 BenError LtcBenContainer::CreateGraphicStream(SvStream * &pStream, const char *pObjectName)
479 if (!pObjectName)
481 pStream = NULL;
482 return BenErr_NamedObjectError;
484 // construct the string of property name
485 char sSName[64]="";
486 char sDName[64]="";
488 sprintf(sSName, "%s-S", pObjectName);
489 sprintf(sDName, "%s-D", pObjectName);
491 /* traverse the found properties and construct the stream vectors */
492 SvMemoryStream * pMemStream = NULL;
493 // get S&D's stream and merge them together
494 SvStream *pD = NULL, *pS = NULL;
496 pS = FindValueStreamWithPropertyName(sSName);
497 pD = FindValueStreamWithPropertyName(sDName);
500 sal_uInt32 nDLen = 0;
501 if(pD)
503 nDLen = GetSvStreamSize(pD);
505 sal_uInt32 nLen = nDLen;
506 if(pS)
508 nLen += GetSvStreamSize(pS) ;
511 assert(nLen > 0);
512 char * pBuf = new char[nLen];
513 assert(pBuf != NULL);
514 char * pPointer = pBuf;
515 if(pD)
517 pD->Read(pPointer, nDLen);
518 delete pD;
520 pPointer += nDLen;
521 if(pS)
523 pS->Read(pPointer, nLen - nDLen);
524 delete pS;
527 pMemStream = new SvMemoryStream(pBuf, nLen, STREAM_READ);
528 assert(pMemStream != NULL);
530 pStream = pMemStream;
531 return BenErr_OK;
534 * Find ole object stream according to object name
535 * @date 10/24/2005
536 * @param
537 * @return the value ole storage stream pointers
539 #include <tools/globname.hxx>
540 SotStorageStreamRef LtcBenContainer::ConvertAswStorageToOLE2Stream(const char * sObjectName)
542 SotStorageStreamRef xOleObjStm;
544 SvStream* pOleStorageStream = NULL;
545 //Get Ole Storage stream
546 AswEntry aEntry;
547 pOleStorageStream = FindOLEStorageStreamWithObjectName(sObjectName, aEntry);
549 if( !pOleStorageStream )
550 return xOleObjStm;
551 //Find it, create Ole stream
552 //xOleObjStm = new SotStorageStream(String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Ole-Object" ) ));
553 xOleObjStm = new SotStorageStream(String());
554 if( xOleObjStm->GetError() )
555 return xOleObjStm;
556 xOleObjStm->SetBufferSize( 0xff00 );
558 SotStorageRef xOleObjStor = new SotStorage( *xOleObjStm );
559 if( xOleObjStor->GetError() )
560 return xOleObjStm;
561 //Set class id
562 ClsId aClsId = aEntry.GetClassId();
563 SvGlobalName aGName( aClsId.n1, aClsId.n2, aClsId.n3, aClsId.n4,
564 aClsId.n5, aClsId.n6,aClsId.n7,aClsId.n8,
565 aClsId.n9,aClsId.n10,aClsId.n11);
566 xOleObjStor->SetClass( aGName, 0, String());
568 xOleObjStor->SetVersion( SOFFICE_FILEFORMAT_60 );
569 std::string aOleStreamName("OleStream");
570 sal_uInt32 nDLen = 0;
571 nDLen = GetSvStreamSize(pOleStorageStream);
572 for(sal_uInt32 nIndex = 0; nIndex < nDLen / ASWENTRY_SIZE; nIndex ++)
574 AswEntry aOleEntry;
575 ReadAswEntry(pOleStorageStream, aOleEntry);
576 if(aOleEntry.GetType()== BEN_STGTY_STREAM)
578 SvStream* pOleStream = FindObjectValueStreamWithObjectIDAndProperty(aOleEntry.GetObjectID(), aOleStreamName.c_str());
579 if(pOleStream)
581 String strName;
582 aOleEntry.GetName(strName);
583 SotStorageStreamRef xStm = xOleObjStor->OpenSotStream( strName );
584 if( xStm->GetError() )
585 break;
586 xStm->SetBufferSize( 8192 );
587 (*pOleStream) >> (*xStm);
588 xStm->Commit();
589 delete pOleStream;
590 pOleStream = NULL;
594 xOleObjStor->Commit();
595 xOleObjStm->Commit();
597 return xOleObjStm;
600 * Find ole object storage stream data according to object name
601 * @date 10/24/2005
602 * @param
603 * @return the value ole storage stream data pointers
605 LtcUtBenValueStream* LtcBenContainer::FindOLEStorageStreamWithObjectName(const char * sObjectName, AswEntry& rEntry)
607 if (!sObjectName)
608 return NULL;
610 //Find OleRootStorage stream
611 std::string aRootStroageName("OleRootStorage");
612 std::string aOleStroageName("OleStorage");
613 LtcUtBenValueStream* pRootStream = NULL;
614 pRootStream = FindValueStreamWithPropertyName(aRootStroageName.c_str());
615 if(!pRootStream)
616 return NULL;
617 //Read root storage data and find the ole storage object id according to the object name
618 sal_uInt32 nDLen = 0;
619 nDLen = GetSvStreamSize(pRootStream);
620 for(sal_uInt32 nIndex = 0; nIndex < nDLen / ASWENTRY_SIZE; nIndex ++)
622 //Get entry
623 ReadAswEntry(pRootStream, rEntry);
624 String sObjName;
625 rEntry.GetName(sObjName);
626 if(sObjName.EqualsAscii(sObjectName))
628 //Find it
629 delete pRootStream;
630 return FindObjectValueStreamWithObjectIDAndProperty(rEntry.GetObjectID(), aOleStroageName.c_str());
634 // Not find
635 if(pRootStream)
637 delete pRootStream;
640 return NULL;
642 void LtcBenContainer::ReadAswEntry(SvStream * pStream, AswEntry & rEntry)
644 char* pBuf = new char[ASWENTRY_SIZE];
645 pStream->Read(pBuf, ASWENTRY_SIZE);
646 rEntry.Load(pBuf);
647 delete[] pBuf;
649 ////////////////////////////////////////////////////////////////////
650 //classs AswEntry
651 AswEntry::AswEntry()
653 Init();
655 void AswEntry::Init()
657 memset( this, 0, sizeof (AswEntry));
659 void AswEntry::SetName( const String& rName )
661 int i;
662 for( i = 0; i < rName.Len() && i < 68; i++ )
663 nName[ i ] = rName.GetChar( i );
664 while( i < 68 )
665 nName[ i++ ] = 0;
667 void AswEntry::GetName(String & rName) const
669 rName = nName;
671 void AswEntry::Store( void* pTo )
673 SvMemoryStream r( (sal_Char *)pTo, ASWENTRY_SIZE, STREAM_WRITE );
674 for( short i = 0; i < 68; i++ )
675 r << nName[ i ]; // 00 name as WCHAR
676 r<< nMtime[ 0 ] // 42 entry type
677 << nMtime[ 1 ] // 43 0 or 1 (tree balance?)
678 << nCtime[ 0 ] // 44 left node entry
679 << nCtime[ 1 ] // 48 right node entry
680 << nAtime[ 0 ] // 44 left node entry
681 << nAtime[ 1 ]; // 48 right node entry
682 r.Write(&aClsId ,16); // 50 class ID (optional)
683 r<< nStatebits // 60 state flags(?)
684 << nType
685 << nObjectIDRef // 64 modification time
686 << nMversion // 6C creation and access time
687 << nLversion // 6C creation and access time
688 << nReserved[ 0 ] // 74 starting block (either direct or translated)
689 << nReserved[ 1 ]; // 78 file size
691 void AswEntry::Load( const void* pFrom )
693 SvMemoryStream r( (sal_Char *)pFrom, ASWENTRY_SIZE, STREAM_WRITE );
694 for( short i = 0; i < 68; i++ )
695 r >> nName[ i ]; // 00 name as WCHAR
696 r>> nMtime[ 0 ] // 42 entry type
697 >> nMtime[ 1 ] // 43 0 or 1 (tree balance?)
698 >> nCtime[ 0 ] // 44 left node entry
699 >> nCtime[ 1 ] // 48 right node entry
700 >> nAtime[ 0 ] // 44 left node entry
701 >> nAtime[ 1 ]; // 48 right node entry
702 r.Read(&aClsId,16); // 50 class ID (optional)
703 r>> nStatebits // 60 state flags(?)
704 >> nType
705 >> nObjectIDRef // 64 modification time
706 >> nMversion // 6C creation and access time
707 >> nLversion // 6C creation and access time
708 >> nReserved[ 0 ] // 74 starting block (either direct or translated)
709 >> nReserved[ 1 ]; // 78 file size
711 void AswEntry::SetClassId( const ClsId& r )
713 memcpy( &aClsId, &r, sizeof( ClsId ) );
715 ///////////////////////////////////////////////////////////////////
716 }// end namespace OpenStormBento