#80556# Implemented support for Zipfiles contained within zip files. These will appear as folders with the name set to the name of the zipfile.

This commit is contained in:
Martin Gallwey
2000-11-23 13:15:52 +00:00
parent 13e26b0a44
commit 01fefe870a
8 changed files with 222 additions and 42 deletions

View File

@@ -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 <vector>
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 )

View File

@@ -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;}

View File

@@ -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);

View File

@@ -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]);

View File

@@ -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

View File

@@ -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; i<nDataLen;i++,nEnd++)
aBuffer[nEnd] = aData[i];
nCurrent=nEnd;
for (sal_Int64 i=0; i<nDataLen;i++,nCurrent++)
aBuffer[nCurrent] = aData[i];
if (nCurrent>nEnd)
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( )

View File

@@ -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)

View File

@@ -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")