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,
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 ************************************************************************/
58 #include <sot/storinfo.hxx>
59 namespace OpenStormBento
63 const char gsBenMagicBytes
[] = BEN_MAGIC_BYTES
;
66 * New bento container from file stream
67 * @param pointer to length of bento file
68 * @param pointer to pointer of Bento Container object
71 ULONG
BenOpenContainer(LwpSvStream
* pStream
, pLtcBenContainer
* ppContainer
)
79 return BenErr_ContainerWithNoObjects
;
82 pLtcBenContainer pContainer
= new LtcBenContainer(pStream
);
83 if ((Err
= pContainer
->Open()) != BenErr_OK
) // delete two inputs
86 return BenErr_InvalidTOC
;
89 *ppContainer
= pContainer
;
93 LtcBenContainer::Close()
98 LtcBenContainer::~LtcBenContainer()
104 LtcBenContainer::Open() // delete two inputs
107 CBenTOCReader
TOCReader(this);
108 if ((Err
= TOCReader
.ReadLabelAndTOC()) != BenErr_OK
)
116 LtcBenContainer::Release()
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
;
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
;
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
;
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
;
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
;
191 LtcBenContainer::GetNextObject(pCBenObject pCurrObject
)
193 return (pCBenObject
) cObjects
.GetNextOrNULL(pCurrObject
);
197 LtcBenContainer::FindNextObjectWithProperty(pCBenObject pCurrObject
,
198 BenObjectID PropertyID
)
200 while ((pCurrObject
= GetNextObject(pCurrObject
)) != NULL
)
201 if (pCurrObject
->UseProperty(PropertyID
) != NULL
)
208 LtcBenContainer::FindObject(BenObjectID ObjectID
)
210 return (pCBenObject
) FindID(&cObjects
, ObjectID
, NULL
);
215 * @param Bento file stream pointer
218 LtcBenContainer::LtcBenContainer(LwpSvStream
* 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
229 * @param buffer pointer
231 * @param number of bytes read
234 BenError
LtcBenContainer::Read(BenDataPtr pBuffer
, unsigned long MaxSize
,
235 unsigned long * pAmtRead
)
237 *pAmtRead
= cpStream
->Read(pBuffer
, MaxSize
);
241 * Read buffer from bento file with specified size
243 * @param buffer pointer
244 * @param number of bytes to be read
247 BenError
LtcBenContainer::ReadKnownSize(BenDataPtr pBuffer
, unsigned long Amt
)
250 ulLength
= cpStream
->Read(pBuffer
, Amt
);
255 return BenErr_ReadPastEndOfContainer
;
258 * Seek to position from the beginning of the bento file
260 * @param position in container file from beginning
263 BenError
LtcBenContainer::SeekToPosition(BenContainerPos Pos
)
269 * Seek to position compare to end of bento file
271 * @param position in container file from end
274 BenError
LtcBenContainer::SeekFromEnd(long Offset
)
276 cpStream
->Seek(STREAM_SEEK_TO_END
);
277 cpStream
->SeekRel(Offset
);
282 * Get position in the bento file
284 * @param pointer of current position in container file from end
287 BenError
LtcBenContainer::GetPosition(BenContainerPos
* pPosition
)
289 *pPosition
= cpStream
->Tell();
293 * Find the next value stream with property name
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
320 LtcUtBenValueStream
* pValueStream
;
322 pValue
= pObj
->UseValue(pPropertyName
->GetID());
324 pValueStream
= new LtcUtBenValueStream(pValue
);
330 * Find the unique value stream with property name
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
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
358 LtcUtBenValueStream
* pValueStream
;
359 pValue
= pObj
->UseValue(pPropertyName
->GetID());
360 pValueStream
= new LtcUtBenValueStream(pValue
);
366 * @param pointer to length of bento file
369 BenError
LtcBenContainer::GetSize(ULONG
* pLength
)
371 *pLength
= m_ulLength
;
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
);
385 * Find hazily according to part of property name
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
;
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())
406 pName
= const_cast<char *>(pNamedObj
->GetName());
407 if ( (pName
[0] == 'G')
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());
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
);
444 pD
= FindValueStreamWithPropertyName(sDName
);
447 sal_uInt32 nDLen
= GetSvStreamSize(pD
);
448 sal_uInt32 nLen
= GetSvStreamSize(pS
) + nDLen
;
450 char * pBuf
= new char[nLen
];
451 assert(pBuf
!= NULL
);
452 char * pPointer
= pBuf
;
453 pD
->Read(pPointer
, nDLen
);
455 pS
->Read(pPointer
, nLen
- nDLen
);
460 SvMemoryStream
* pStream
= new SvMemoryStream(pBuf
, nLen
, STREAM_READ
);
461 assert(pStream
!= NULL
);
463 pStreamVector
->push_back(pStream
);
467 aGrPropertyVector
.clear();
472 * Find hazily according to object ID
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
)
482 return BenErr_NamedObjectError
;
484 // construct the string of property name
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;
503 nDLen
= GetSvStreamSize(pD
);
505 sal_uInt32 nLen
= nDLen
;
508 nLen
+= GetSvStreamSize(pS
) ;
512 char * pBuf
= new char[nLen
];
513 assert(pBuf
!= NULL
);
514 char * pPointer
= pBuf
;
517 pD
->Read(pPointer
, nDLen
);
523 pS
->Read(pPointer
, nLen
- nDLen
);
527 pMemStream
= new SvMemoryStream(pBuf
, nLen
, STREAM_READ
);
528 assert(pMemStream
!= NULL
);
530 pStream
= pMemStream
;
534 * Find ole object stream according to object name
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
547 pOleStorageStream
= FindOLEStorageStreamWithObjectName(sObjectName
, aEntry
);
549 if( !pOleStorageStream
)
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() )
556 xOleObjStm
->SetBufferSize( 0xff00 );
558 SotStorageRef xOleObjStor
= new SotStorage( *xOleObjStm
);
559 if( xOleObjStor
->GetError() )
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
++)
575 ReadAswEntry(pOleStorageStream
, aOleEntry
);
576 if(aOleEntry
.GetType()== BEN_STGTY_STREAM
)
578 SvStream
* pOleStream
= FindObjectValueStreamWithObjectIDAndProperty(aOleEntry
.GetObjectID(), aOleStreamName
.c_str());
582 aOleEntry
.GetName(strName
);
583 SotStorageStreamRef xStm
= xOleObjStor
->OpenSotStream( strName
);
584 if( xStm
->GetError() )
586 xStm
->SetBufferSize( 8192 );
587 (*pOleStream
) >> (*xStm
);
594 xOleObjStor
->Commit();
595 xOleObjStm
->Commit();
600 * Find ole object storage stream data according to object name
603 * @return the value ole storage stream data pointers
605 LtcUtBenValueStream
* LtcBenContainer::FindOLEStorageStreamWithObjectName(const char * sObjectName
, AswEntry
& rEntry
)
610 //Find OleRootStorage stream
611 std::string
aRootStroageName("OleRootStorage");
612 std::string
aOleStroageName("OleStorage");
613 LtcUtBenValueStream
* pRootStream
= NULL
;
614 pRootStream
= FindValueStreamWithPropertyName(aRootStroageName
.c_str());
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
++)
623 ReadAswEntry(pRootStream
, rEntry
);
625 rEntry
.GetName(sObjName
);
626 if(sObjName
.EqualsAscii(sObjectName
))
630 return FindObjectValueStreamWithObjectIDAndProperty(rEntry
.GetObjectID(), aOleStroageName
.c_str());
642 void LtcBenContainer::ReadAswEntry(SvStream
* pStream
, AswEntry
& rEntry
)
644 char* pBuf
= new char[ASWENTRY_SIZE
];
645 pStream
->Read(pBuf
, ASWENTRY_SIZE
);
649 ////////////////////////////////////////////////////////////////////
655 void AswEntry::Init()
657 memset( this, 0, sizeof (AswEntry
));
659 void AswEntry::SetName( const String
& rName
)
662 for( i
= 0; i
< rName
.Len() && i
< 68; i
++ )
663 nName
[ i
] = rName
.GetChar( i
);
667 void AswEntry::GetName(String
& rName
) const
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(?)
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(?)
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