diff --git a/package/inc/ZipPackage.hxx b/package/inc/ZipPackage.hxx index e4b7709b8b23..ace21a8bfb45 100644 --- a/package/inc/ZipPackage.hxx +++ b/package/inc/ZipPackage.hxx @@ -2,9 +2,9 @@ * * $RCSfile: ZipPackage.hxx,v $ * - * $Revision: 1.5 $ + * $Revision: 1.6 $ * - * last change: $Author: mtg $ $Date: 2000-11-21 17:57:06 $ + * last change: $Author: mtg $ $Date: 2000-11-23 14:15:49 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -113,6 +113,12 @@ #include "ZipPackageBuffer.hxx" #endif +#ifdef _DEBUG_RECURSION_ +#include "testzip.hxx" +#endif + +#include + class ZipPackage : public cppu::WeakImplHelper4< com::sun::star::lang::XInitialization, com::sun::star::container::XHierarchicalNameAccess, @@ -126,14 +132,26 @@ private: ZipOutputStream *pZipOut; ZipPackageBuffer *pZipBuffer; ::ucb::Content *pContent; + ::std::vector < com::sun::star::uno::Reference < com::sun::star::lang::XSingleServiceFactory > > aContainedZips; ::com::sun::star::uno::Reference < com::sun::star::package::XZipFile > xZipFile; ::com::sun::star::uno::Reference < com::sun::star::package::XZipOutputStream > xZipOut; ::com::sun::star::uno::Reference < com::sun::star::io::XOutputStream > xBuffer; ::com::sun::star::uno::Reference < com::sun::star::container::XNameContainer > xFolder; ::com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xStream; + sal_Bool isZipFile(com::sun::star::package::ZipEntry &rEntry); public: - ZipPackage (com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xInput); + ZipPackage (com::sun::star::uno::Reference < com::sun::star::io::XInputStream > xInput, + ZipPackageBuffer *pNewBuffer, + ZipOutputStream *pNewZipOut); ZipPackage (void); + ZipPackageFolder * getRootFolder() + { + return pRootFolder; + } + ZipPackageBuffer * getZipBuffer() + { + return pZipBuffer; + } virtual ~ZipPackage( void ); // XInitialization virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) diff --git a/package/inc/ZipPackageFolder.hxx b/package/inc/ZipPackageFolder.hxx index 34c8bfdd2cc9..32edbafb4695 100644 --- a/package/inc/ZipPackageFolder.hxx +++ b/package/inc/ZipPackageFolder.hxx @@ -2,9 +2,9 @@ * * $RCSfile: ZipPackageFolder.hxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: mtg $ $Date: 2000-11-21 12:07:58 $ + * last change: $Author: mtg $ $Date: 2000-11-23 14:15:49 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -135,6 +135,10 @@ struct hashFunc #include "ZipOutputStream.hxx" #endif +#ifdef _DEBUG_RECURSION_ +#include "testzip.hxx" +#endif + typedef std::hash_map < rtl::OUString, com::sun::star::uno::Reference < com::sun::star::lang::XUnoTunnel > , hashFunc, eqFunc > TunnelHash; class ZipPackageFolder : public ZipPackageEntry, @@ -152,7 +156,11 @@ private: com::sun::star::uno::Reference < com::sun::star::uno::XInterface > xParent; public: ZipPackageFolder (ZipOutputStream &rStream );//ZipPackage &rInPackage); +#ifdef _DEBUG_RECURSION_ + void saveContents(rtl::OUString &rPath, TestZip &rFoo); +#else void saveContents(rtl::OUString &rPath); +#endif inline sal_Bool isFolder( void ) {return sal_True;} inline sal_Bool isStream( void ) {return sal_False;} diff --git a/package/source/zipapi/ZipFile.cxx b/package/source/zipapi/ZipFile.cxx index 0dc0c60e01eb..15156aeb9d86 100644 --- a/package/source/zipapi/ZipFile.cxx +++ b/package/source/zipapi/ZipFile.cxx @@ -2,9 +2,9 @@ * * $RCSfile: ZipFile.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: mtg $ $Date: 2000-11-21 17:57:07 $ + * last change: $Author: mtg $ $Date: 2000-11-23 14:15:51 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -440,10 +440,10 @@ sal_Int32 ZipFile::readCEN() pEntry->nOffset = nOffset + nLocPos; pEntry->nOffset *= -1; - + /* if (nHow == STORED) pEntry->nCompressedSize = 0; - + */ uno::Sequence < sal_Int8> aSequence (nNameLen); aGrabber.readBytes(aSequence, nNameLen); pEntry->sName = OUString((sal_Char*)aSequence.getConstArray(), nNameLen, RTL_TEXTENCODING_ASCII_US); diff --git a/package/source/zipapi/ZipOutputStream.cxx b/package/source/zipapi/ZipOutputStream.cxx index 56c8995cd2dd..8054931beec8 100644 --- a/package/source/zipapi/ZipOutputStream.cxx +++ b/package/source/zipapi/ZipOutputStream.cxx @@ -2,9 +2,9 @@ * * $RCSfile: ZipOutputStream.cxx,v $ * - * $Revision: 1.5 $ + * $Revision: 1.6 $ * - * last change: $Author: mtg $ $Date: 2000-11-22 16:55:27 $ + * last change: $Author: mtg $ $Date: 2000-11-23 14:15:51 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -127,7 +127,7 @@ void SAL_CALL ZipOutputStream::putNextEntry( const package::ZipEntry& rEntry ) case STORED: if (pNonConstEntry->nSize == -1) pNonConstEntry->nSize = pNonConstEntry->nCompressedSize; - else if (pNonConstEntry->nCompressedSize == -1) + else if (pNonConstEntry->nCompressedSize == -1 || pNonConstEntry->nCompressedSize == 0) pNonConstEntry->nCompressedSize = pNonConstEntry->nSize; pNonConstEntry->nVersion = 10; pNonConstEntry->nFlag = 0; @@ -209,7 +209,7 @@ void SAL_CALL ZipOutputStream::write( const uno::Sequence< sal_Int8 >& rBuffer, if (!aDeflater.finished()) { aDeflater.setInputSegment(rBuffer, nNewOffset, nNewLength); - while (!aDeflater.needsInput()) + while (!aDeflater.needsInput()) doDeflate(); } break; @@ -243,9 +243,11 @@ void SAL_CALL ZipOutputStream::finish( ) } void ZipOutputStream::doDeflate() { + //sal_Int32 nOldOut = aDeflater.getTotalOut(); sal_Int32 nLength = aDeflater.doDeflateSegment(aBuffer, 0, aBuffer.getLength()); sal_Int32 nOldLength = aBuffer.getLength(); - if (nLength > 0 ) + //sal_Int32 nNewOut = aDeflater.getTotalOut() - nOldOut; + if (nLength> 0 ) { aBuffer.realloc(nLength); aChucker.writeBytes(aBuffer); @@ -276,7 +278,7 @@ void ZipOutputStream::writeEND(sal_uInt32 nOffset, sal_uInt32 nLength) void ZipOutputStream::writeCEN( const package::ZipEntry &rEntry ) { sal_Int16 nNameLength = rEntry.sName.getLength(), - nCommentLength = rEntry.sName.getLength(), + nCommentLength = rEntry.sComment.getLength(), nExtraLength = rEntry.extra.getLength(), i = 0; aChucker << CENSIG; @@ -310,7 +312,7 @@ void ZipOutputStream::writeCEN( const package::ZipEntry &rEntry ) if (nCommentLength) { aSequence.realloc (nCommentLength); - for (i=0, pChar = rEntry.sName.getStr(); i < nCommentLength; i++) + for (i=0, pChar = rEntry.sComment.getStr(); i < nCommentLength; i++) { VOS_ENSURE (pChar[i] <127, "Non US ASCII character in zipentry comment!"); aSequence[i] = static_cast < const sal_Int8 > (pChar[i]); diff --git a/package/source/zippackage/ZipPackage.cxx b/package/source/zippackage/ZipPackage.cxx index 2e279ece180b..c90751907cbe 100644 --- a/package/source/zippackage/ZipPackage.cxx +++ b/package/source/zippackage/ZipPackage.cxx @@ -2,9 +2,9 @@ * * $RCSfile: ZipPackage.cxx,v $ * - * $Revision: 1.6 $ + * $Revision: 1.7 $ * - * last change: $Author: mtg $ $Date: 2000-11-21 17:57:07 $ + * last change: $Author: mtg $ $Date: 2000-11-23 14:15:52 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -72,18 +72,103 @@ using namespace com::sun::star::package; using namespace com::sun::star::lang; using namespace com::sun::star::package::ZipConstants; -ZipPackage::ZipPackage (Reference < XInputStream > xInput) +ZipPackage::ZipPackage (Reference < XInputStream > xNewInput, + ZipPackageBuffer *pNewBuffer, + ZipOutputStream *pNewZipOut) : pContent(NULL) , pZipFile(NULL) -, pZipOut(NULL) -, pZipBuffer(NULL) +, pZipOut(pNewZipOut) +, pZipBuffer(pNewBuffer) , pRootFolder(NULL) -, xStream (NULL) +, xStream (xNewInput) , xFolder (NULL) , xZipFile (NULL) , xBuffer (NULL) , xZipOut(NULL) { + pZipFile = new ZipFile(xStream); + + xZipFile = Reference < XZipFile > (pZipFile); + xBuffer = Reference < XOutputStream > (pZipBuffer); + + pRootFolder = new ZipPackageFolder(*pZipOut); + + xZipOut = Reference < XZipOutputStream > (pZipOut); + xFolder = Reference < XNameContainer > (pRootFolder ); + + Reference< XEnumeration > xEnum = pZipFile->entries(); + Reference< XNameContainer > xCurrent = xFolder; + ZipPackageStream *pPkgStream; + ZipPackageFolder *pPkgFolder; + ZipEntry aEntry; + pZipOut->setMethod(DEFLATED); + pZipOut->setLevel(DEFAULT_COMPRESSION); + + while (xEnum->hasMoreElements()) + { + xCurrent = Reference < XNameContainer > (pRootFolder); + sal_Int32 nOldIndex =0,nIndex = 0; + Any aAny = xEnum->nextElement(); + aAny >>= aEntry; + OUString &rName = aEntry.sName; + + if (rName.lastIndexOf('/') == rName.getLength()-1) + { + while ((nIndex = rName.indexOf('/', nOldIndex)) != -1) + { + OUString sTemp = rName.copy (nOldIndex, nIndex - nOldIndex); + if (nIndex == nOldIndex) //sTemp.getLength() == 1) + break; + if (!xCurrent->hasByName(sTemp)) + { + pPkgFolder = new ZipPackageFolder(*pZipOut);//*this); + pPkgFolder->setName(sTemp); + pPkgFolder->setParent( Reference < XInterface >(xCurrent, UNO_QUERY)); + aAny <<= Reference < XUnoTunnel > (pPkgFolder); + xCurrent->insertByName(sTemp, aAny); + xCurrent = Reference < XNameContainer > (pPkgFolder); + } + else + { + aAny = xCurrent->getByName(sTemp); + Reference < XUnoTunnel> xRef; + aAny >>= xRef; + xCurrent = Reference < XNameContainer > (xRef, UNO_QUERY); + } + + nOldIndex = nIndex+1; + } + } + else + { + while ((nIndex = rName.indexOf('/', nOldIndex)) != -1) + { + OUString sTemp = rName.copy (nOldIndex, nIndex - nOldIndex); + if (nIndex == nOldIndex) //sTemp.getLength() == 1) + break; + if (xCurrent->hasByName(sTemp)) + { + Reference < XUnoTunnel > xChildRef; + aAny = xCurrent->getByName(sTemp); + aAny >>= xChildRef; + xCurrent = Reference < XNameContainer > (xChildRef, UNO_QUERY); + } + nOldIndex = nIndex+1; + } + OUString sStreamName = rName.copy( nOldIndex, rName.getLength() - nOldIndex); + if (isZipFile(aEntry)) + { + // do stuff + } + pPkgStream = new ZipPackageStream( *pZipFile ); + pPkgStream->bPackageMember = sal_True; + pPkgStream->setParent( Reference < XInterface > (xCurrent, UNO_QUERY)); + pPkgStream->setZipEntry( aEntry ); + pPkgStream->setName( sStreamName ); + aAny <<= Reference < XUnoTunnel > (pPkgStream); + xCurrent->insertByName(sStreamName, aAny); + } + } } ZipPackage::ZipPackage( void ) @@ -198,16 +283,29 @@ void SAL_CALL ZipPackage::initialize( const Sequence< Any >& aArguments ) nOldIndex = nIndex+1; } OUString sStreamName = rName.copy( nOldIndex, rName.getLength() - nOldIndex); - pPkgStream = new ZipPackageStream( *pZipFile ); - pPkgStream->bPackageMember = sal_True; - pPkgStream->setParent( Reference < XInterface > (xCurrent, UNO_QUERY)); - pPkgStream->setZipEntry( aEntry ); - pPkgStream->setName( sStreamName ); - aAny <<= Reference < XUnoTunnel > (pPkgStream); - xCurrent->insertByName(sStreamName, aAny); + if (isZipFile(aEntry)) + { + Reference < XInputStream > xStream = pZipFile->getInputStream(aEntry); + ZipPackage *pInZip = new ZipPackage (xStream, pZipBuffer, pZipOut); + aContainedZips.push_back (Reference < XSingleServiceFactory > (pInZip)); + pPkgFolder = pInZip->getRootFolder(); + pPkgFolder->setName(sStreamName); + pPkgFolder->setParent( Reference < XInterface >(xCurrent, UNO_QUERY)); + aAny <<= Reference < XUnoTunnel > (pPkgFolder); + xCurrent->insertByName(sStreamName, aAny); + } + else + { + pPkgStream = new ZipPackageStream( *pZipFile ); + pPkgStream->bPackageMember = sal_True; + pPkgStream->setParent( Reference < XInterface > (xCurrent, UNO_QUERY)); + pPkgStream->setZipEntry( aEntry ); + pPkgStream->setName( sStreamName ); + aAny <<= Reference < XUnoTunnel > (pPkgStream); + xCurrent->insertByName(sStreamName, aAny); + } } } - } // XHierarchicalNameAccess Any SAL_CALL ZipPackage::getByHierarchicalName( const OUString& aName ) @@ -326,7 +424,14 @@ Reference< XInterface > SAL_CALL ZipPackage::createInstanceWithArguments( const void SAL_CALL ZipPackage::commitChanges( ) throw(WrappedTargetException, RuntimeException) { +#ifdef _DEBUG_RECURSION_ + TestZip *pFoo = new TestZip(L"e:/clean/foo.txt", sal_False); + pRootFolder->saveContents(OUString::createFromAscii(""), *pFoo); + pFoo->closeInput(); +#else pRootFolder->saveContents(OUString::createFromAscii("")); +#endif + pZipOut->finish(); } sal_Bool SAL_CALL ZipPackage::hasPendingChanges( ) @@ -340,6 +445,22 @@ Sequence< ElementChange > SAL_CALL ZipPackage::getPendingChanges( ) return Sequence < ElementChange > ( NULL, 0 ); } +sal_Bool ZipPackage::isZipFile(com::sun::star::package::ZipEntry &rEntry) +{ + Reference < XInputStream > xStream = pZipFile->getInputStream(rEntry); + Sequence < sal_Int8 > aSequence (4); + xStream->readBytes(aSequence, 4); + sal_uInt32 nTestSig = static_cast < sal_uInt32 > + (static_cast < sal_uInt8> (aSequence[0]& 0xFF) + | static_cast < sal_uInt8> (aSequence[1]& 0xFF) << 8 + | static_cast < sal_uInt8> (aSequence[2]& 0xFF) << 16 + | static_cast < sal_uInt8> (aSequence[3]& 0xFF) << 24); + if (nTestSig == LOCSIG) + return sal_True; + else + return sal_False; +} + /** * Function to create a new component instance; is needed by factory helper implementation. * @param xMgr service manager to if the components needs other component instances diff --git a/package/source/zippackage/ZipPackageBuffer.cxx b/package/source/zippackage/ZipPackageBuffer.cxx index 5eecb876e77f..31dda37d11b7 100644 --- a/package/source/zippackage/ZipPackageBuffer.cxx +++ b/package/source/zippackage/ZipPackageBuffer.cxx @@ -2,9 +2,9 @@ * * $RCSfile: ZipPackageBuffer.cxx,v $ * - * $Revision: 1.2 $ + * $Revision: 1.3 $ * - * last change: $Author: mtg $ $Date: 2000-11-21 17:57:07 $ + * last change: $Author: mtg $ $Date: 2000-11-23 14:15:52 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -145,10 +145,10 @@ void SAL_CALL ZipPackageBuffer::writeBytes( const Sequence< sal_Int8 >& aData ) nBufferSize *=2; aBuffer.realloc(nBufferSize); } - for (sal_Int64 i=0; inEnd) + nEnd = nCurrent; } void SAL_CALL ZipPackageBuffer::flush( ) throw(NotConnectedException, BufferSizeExceededException, IOException, RuntimeException) @@ -166,6 +166,9 @@ void SAL_CALL ZipPackageBuffer::seek( sal_Int64 location ) sal_Int64 SAL_CALL ZipPackageBuffer::getPosition( ) throw(IOException, RuntimeException) { + sal_Int8 nP = aBuffer[nCurrent]; + sal_Int8 nR = aBuffer[nEnd]; + int i =0; return nCurrent; } sal_Int64 SAL_CALL ZipPackageBuffer::getLength( ) diff --git a/package/source/zippackage/ZipPackageFolder.cxx b/package/source/zippackage/ZipPackageFolder.cxx index 1fdd146c1741..cce6c113c899 100644 --- a/package/source/zippackage/ZipPackageFolder.cxx +++ b/package/source/zippackage/ZipPackageFolder.cxx @@ -2,9 +2,9 @@ * * $RCSfile: ZipPackageFolder.cxx,v $ * - * $Revision: 1.5 $ + * $Revision: 1.6 $ * - * last change: $Author: mtg $ $Date: 2000-11-21 12:08:47 $ + * last change: $Author: mtg $ $Date: 2000-11-23 14:15:52 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -236,7 +236,11 @@ void SAL_CALL ZipPackageFolder::removeVetoableChangeListener( const ::rtl::OUStr throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) { } +#ifdef _DEBUG_RECURSION_ +void ZipPackageFolder::saveContents(rtl::OUString &rPath, TestZip &rFoo) +#else void ZipPackageFolder::saveContents(rtl::OUString &rPath) +#endif { uno::Reference < lang::XUnoTunnel > xTunnel; package::ZipEntry *aEntry = NULL; @@ -265,14 +269,38 @@ void ZipPackageFolder::saveContents(rtl::OUString &rPath) { time_t nTime = 0; pFolder->aEntry.sName = rPath + pFolder->getName() + L"/"; +#ifdef _DEBUG_RECURSION_ + /*pFolder->aEntry.nMethod = STORED;*/ + ByteString sByte(String(pFolder->aEntry.sName),RTL_TEXTENCODING_ASCII_US); + uno::Sequence < sal_Int8 > aSeq ((sal_Int8*) sByte.GetBuffer(), sByte.Len()); + rFoo.writeBytes(aSeq); + sal_Int8 me[] = {(sal_Int8) '\n'}; + uno::Sequence < sal_Int8 > bSeq (me, 1); + rFoo.writeBytes(bSeq); +#endif + pFolder->aEntry.nTime = ZipOutputStream::tmDateToDosDate ( *localtime(&nTime)); rZipOut.putNextEntry(pFolder->aEntry); rZipOut.closeEntry(); +#ifdef _DEBUG_RECURSION_ + pFolder->saveContents(pFolder->aEntry.sName, rFoo); +#else pFolder->saveContents(pFolder->aEntry.sName); +#endif } else { pStream->aEntry.sName = rPath + pStream->getName(); + +#ifdef _DEBUG_RECURSION_ + /*pStream->aEntry.nMethod = STORED;*/ + ByteString sByte(String(pStream->aEntry.sName),RTL_TEXTENCODING_ASCII_US); + uno::Sequence < sal_Int8 > aSeq ((sal_Int8*) sByte.GetBuffer(), sByte.Len()); + rFoo.writeBytes(aSeq); + sal_Int8 me[] = {(sal_Int8) '\n'}; + uno::Sequence < sal_Int8 > bSeq (me, 1); + rFoo.writeBytes(bSeq); +#endif uno::Reference < io::XInputStream > xStream = pStream->getInputStream(); rZipOut.putNextEntry(pStream->aEntry); while (1) diff --git a/package/source/zippackage/ZipPackageStream.cxx b/package/source/zippackage/ZipPackageStream.cxx index 94385e0862df..d9f8e9b26893 100644 --- a/package/source/zippackage/ZipPackageStream.cxx +++ b/package/source/zippackage/ZipPackageStream.cxx @@ -2,9 +2,9 @@ * * $RCSfile: ZipPackageStream.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: mtg $ $Date: 2000-11-21 10:43:06 $ + * last change: $Author: mtg $ $Date: 2000-11-23 14:15:52 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -156,7 +156,7 @@ void SAL_CALL ZipPackageStream::setPropertyValue( const ::rtl::OUString& aProper throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) { if (aPropertyName == L"MediaType") - aValue >>= sMediaType; + aValue >>= aEntry.sComment; else if (aPropertyName == L"Size") aValue >>= aEntry.nSize; else @@ -168,7 +168,7 @@ uno::Any SAL_CALL ZipPackageStream::getPropertyValue( const ::rtl::OUString& Pro if (PropertyName == L"MediaType") { uno::Any aAny; - aAny <<= sMediaType; + aAny <<= aEntry.sComment; return aAny; } else if (PropertyName == L"Size")