added ZIP classes by M.J.Wetherell (patch 1030239)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30436 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2004-11-10 23:58:38 +00:00
parent eabd333355
commit 00375592f9
16 changed files with 6531 additions and 167 deletions

View File

@@ -473,7 +473,6 @@ $(TAB)copy "$(DOLLAR)(InputPath)" $(SETUPHDIR)\wx\setup.h
<precomp-headers>on</precomp-headers>
<precomp-headers-file>wxprec_$(id)</precomp-headers-file>
<precomp-headers-exclude>
src/common/unzip.c
src/common/extended.c
src/msw/gsocket.cpp
src/msw/gsockmsw.cpp

View File

@@ -214,7 +214,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/common/textfile.cpp
src/common/tokenzr.cpp
src/common/txtstrm.cpp
src/common/unzip.c
src/common/archive.cpp
src/common/uri.cpp
src/common/variant.cpp
src/common/wfstream.cpp

View File

@@ -217,6 +217,7 @@ OTHER CHANGES
All:
- new classes for reading and writing ZIP files (M.J.Wetherell)
- Norwegian (Bokm<6B>l) translation added (Hans F. Nordhaug)
- wxDynamicLibrary::HasSymbol() added
- added wxTextInputStream::operator>>(wchar_t) for compilers which support this

433
docs/latex/wx/arc.tex Normal file
View File

@@ -0,0 +1,433 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Name: arc.tex
%% Purpose: Overview of the archive classes
%% Author: M.J.Wetherell
%% RCS-ID: $Id$
%% Copyright: 2004 M.J.Wetherell
%% License: wxWidgets license
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Archive formats such as zip}\label{wxarc}
The archive classes handle archive formats such as zip, tar, rar and cab.
Currently only the wxZip classes are included.
For each archive type, there are the following classes (using zip here
as an example):
\begin{twocollist}\twocolwidtha{4cm}
\twocolitem{\helpref{wxZipInputStream}{wxzipinputstream}}{Input stream}
\twocolitem{\helpref{wxZipOutputStream}{wxzipoutputstream}}{Output stream}
\twocolitem{\helpref{wxZipEntry}{wxzipentry}}{Holds the meta-data for an
entry (e.g. filename, timestamp, etc.)}
\end{twocollist}
There are also abstract wxArchive classes that can be used to write code
that can handle any of the archive types,
see '\helpref{Generic archive programming}{wxarcgeneric}'.
Also see \helpref{wxFileSystem}{fs} for a higher level interface that
can handle archive files in a generic way.
The classes are designed to handle archives on both seekable streams such
as disk files, or non-seekable streams such as pipes and sockets
(see '\helpref{Archives on non-seekable streams}{wxarcnoseek}').
\wxheading{See also}
\helpref{wxFileSystem}{fs}
\subsection{Creating an archive}\label{wxarccreate}
\helpref{Archive formats such as zip}{wxarc}
Call \helpref{PutNextEntry()}{wxarchiveoutputstreamputnextentry} to
create each new entry in the archive, then write the entry's data.
Another call to PutNextEntry() closes the current entry and begins the next.
For example:
\begin{verbatim}
wxFFileOutputStream out(_T("test.zip"));
wxZipOutputStream zip(out);
wxTextOutputStream txt(zip);
zip.PutNextEntry(_T("entry1.txt"));
txt << _T("Some text for entry1\n");
zip.PutNextEntry(_T("entry2.txt"));
txt << _T("Some text for entry2\n");
\end{verbatim}
\subsection{Extracting an archive}\label{wxarcextract}
\helpref{Archive formats such as zip}{wxarc}
\helpref{GetNextEntry()}{wxarchiveinputstreamgetnextentry} returns an
entry object containing the meta-data for the next entry in the archive
(and gives away ownership). Reading from the input stream then returns
the entry's data. Eof() becomes true after an attempt has been made to
read past the end of the entry's data.
When there are no more entries, GetNextEntry() returns NULL and sets Eof().
\begin{verbatim}
wxDEFINE_SCOPED_PTR_TYPE(wxZipEntry);
wxZipEntryPtr entry;
wxFFileInputStream in(_T("test.zip"));
wxZipInputStream zip(in);
wxTextInputStream txt(zip);
wxString data;
while (entry.reset(zip.GetNextEntry()), entry.get() != NULL)
{
wxString name = entry->GetName(); // access meta-data
txt >> data; // access data
}
\end{verbatim}
\subsection{Modifying an archive}\label{wxarcmodify}
\helpref{Archive formats such as zip}{wxarc}
To modify an existing archive, write a new copy of the archive to a new file,
making any necessary changes along the way and transferring any unchanged
entries using \helpref{CopyEntry()}{wxarchiveoutputstreamcopyentry}.
For archive types which compress entry data, CopyEntry() is likely to be
much more efficient than transferring the data using Read() and Write()
since it will copy them without decompressing and recompressing them.
In general modifications are not possible without rewriting the archive,
though it may be possible in some limited cases. Even then, rewriting
the archive is usually a better choice since a failure can be handled
without losing the whole archive.
For example to delete all entries matching the pattern "*.txt":
\begin{verbatim}
wxFFileInputStream in(_T("in.zip"));
wxFFileOutputStream out(_T("out.zip"));
wxZipInputStream inzip(in);
wxZipOutputStream outzip(out);
wxZipEntryPtr entry;
// transfer any meta-data for the archive as a whole (the zip comment
// in the case of zip)
outzip.CopyArchiveMetaData(inzip);
// call CopyEntry for each entry except those matching the pattern
while (entry.reset(inzip.GetNextEntry()), entry.get() != NULL)
if (!entry->GetName().Matches(_T("*.txt")))
if (!outzip.CopyEntry(entry.release(), inzip))
break;
bool success = inzip.Eof() && outzip.Close();
\end{verbatim}
\subsection{Looking up an archive entry by name}\label{wxarcbyname}
\helpref{Archive formats such as zip}{wxarc}
Also see \helpref{wxFileSystem}{fs} for a higher level interface that is
more convenient for accessing archive entries by name.
To open just one entry in an archive, the most efficient way is
to simply search for it linearly by calling
\helpref{GetNextEntry()}{wxarchiveinputstreamgetnextentry} until the
required entry is found. This works both for archives on seekable and
non-seekable streams.
The format of filenames in the archive is likely to be different
from the local filename format. For example zips and tars use
unix style names, with forward slashes as the path separator,
and absolute paths are not allowed. So if on Windows the file
"C:$\backslash$MYDIR$\backslash$MYFILE.TXT" is stored, then when reading
the entry back \helpref{GetName()}{wxarchiveentryname} will return
"MYDIR$\backslash$MYFILE.TXT". The conversion into the internal format
and back has lost some information.
So to avoid ambiguity when searching for an entry matching a local name,
it is better to convert the local name to the archive's internal format
and search for that:
\begin{verbatim}
wxDEFINE_SCOPED_PTR_TYPE(wxZipEntry);
wxZipEntryPtr entry;
// convert the local name we are looking for into the internal format
wxString name = wxZipEntry::GetInternalName(localname);
// open the zip
wxFFileInputStream in(_T("test.zip"));
wxZipInputStream zip(in);
// call GetNextEntry() until the required internal name is found
do {
entry.reset(zip.GetNextEntry());
}
while (entry.get() != NULL && entry->GetInternalName() != name);
if (entry.get() != NULL) {
// read the entry's data...
}
\end{verbatim}
To access several entries randomly, it is most efficient to transfer the
entire catalogue of entries to a container such as a std::map or a
\helpref{wxHashMap}{wxhashmap} then entries looked up by name can be
opened using the \helpref{OpenEntry()}{wxarchiveinputstreamopenentry} method.
\begin{verbatim}
WX_DECLARE_STRING_HASH_MAP(wxZipEntry*, ZipCatalog);
ZipCatalog::iterator it;
wxZipEntry *entry;
ZipCatalog cat;
// open the zip
wxFFileInputStream in(_T("test.zip"));
wxZipInputStream zip(in);
// load the zip catalog
while ((entry = zip.GetNextEntry()) != NULL) {
wxZipEntry*& current = cat[entry->GetInternalName()];
// some archive formats can have multiple entries with the same name
// (e.g. tar) though it is an error in the case of zip
delete current;
current = entry;
}
// open an entry by name
if ((it = cat.find(wxZipEntry::GetInternalName(localname))) != cat.end()) {
zip.OpenEntry(*it->second);
// ... now read entry's data
}
\end{verbatim}
To open more than one entry simultaneously you need more than one
underlying stream on the same archive:
\begin{verbatim}
// opening another entry without closing the first requires another
// input stream for the same file
wxFFileInputStream in2(_T("test.zip"));
wxZipInputStream zip2(in2);
if ((it = cat.find(wxZipEntry::GetInternalName(local2))) != cat.end())
zip2.OpenEntry(*it->second);
\end{verbatim}
\subsection{Generic archive programming}\label{wxarcgeneric}
\helpref{Archive formats such as zip}{wxarc}
Also see \helpref{wxFileSystem}{fs} for a higher level interface that
can handle archive files in a generic way.
The specific archive classes, such as the wxZip classes, inherit from
the following abstract classes which can be used to write code that can
handle any of the archive types:
\begin{twocollist}\twocolwidtha{5cm}
\twocolitem{\helpref{wxArchiveInputStream}{wxarchiveinputstream}}{Input stream}
\twocolitem{\helpref{wxArchiveOutputStream}{wxarchiveoutputstream}}{Output stream}
\twocolitem{\helpref{wxArchiveEntry}{wxarchiveentry}}{Holds the meta-data for an
entry (e.g. filename)}
\end{twocollist}
In order to able to write generic code it's necessary to be able to create
instances of the classes without knowing which archive type is being used.
So there is a class factory for each archive type, derived from
\helpref{wxArchiveClassFactory}{wxarchiveclassfactory}, which can create
the other classes.
For example, given {\it wxArchiveClassFactory* factory}:
\begin{verbatim}
// create streams without knowing their type
wxArchiveInputStreamPtr inarc(factory->NewStream(in));
wxArchiveOutputStreamPtr outarc(factory->NewStream(out));
// create an empty entry object
wxArchiveEntryPtr entry(factory->NewEntry());
\end{verbatim}
The class factory itself can either be created explicitly:
\begin{verbatim}
wxArchiveClassFactory *factory = new wxZipClassFactory;
\end{verbatim}
or using wxWidgets' \helpref{RTTI}{runtimeclassoverview}:
\begin{verbatim}
wxArchiveClassFactory *MakeFactory(const wxString& type)
{
wxString name = _T("wx") + type.Left(1).Upper() +
type.Mid(1).Lower() + _T("ClassFactory");
wxObject *pObj = wxCreateDynamicObject(name);
wxArchiveClassFactory *pcf = wxDynamicCast(pObj, wxArchiveClassFactory);
if (!pcf) {
wxLogError(_T("can't handle '%s' archives"), type.c_str());
delete pObj;
}
return pcf;
}
\end{verbatim}
\subsection{Archives on non-seekable streams}\label{wxarcnoseek}
\helpref{Archive formats such as zip}{wxarc}
In general, handling archives on non-seekable streams is done in the same
way as for seekable streams, with a few caveats.
The main limitation is that accessing entries randomly using
\helpref{OpenEntry()}{wxarchiveinputstreamopenentry}
is not possible, the entries can only be accessed sequentially in the order
they are stored within the archive.
For each archive type, there will also be other limitations which will
depend on the order the entries' meta-data is stored within the archive.
These are not too difficult to deal with, and are outlined below.
\wxheading{PutNextEntry and the entry size}
When writing archives, some archive formats store the entry size before
the entry's data (tar has this limitation, zip doesn't). In this case
the entry's size must be passed to
\helpref{PutNextEntry()}{wxarchiveoutputstreamputnextentry} or an error
occurs.
This is only an issue on non-seekable streams, since otherwise the archive
output stream can seek back and fix up the header once the size of the
entry is known.
For generic programming, one way to handle this is to supply the size
whenever it is known, and rely on the error message from the output
stream when the operation is not supported.
\wxheading{GetNextEntry and the weak reference mechanism}
Some archive formats do not store all an entry's meta-data before the
entry's data (zip is an example). In this case, when reading from a
non-seekable stream, \helpref{GetNextEntry()}{wxarchiveinputstreamgetnextentry}
can only return a partially populated \helpref{wxArchiveEntry}{wxarchiveentry}
object - not all the fields are set.
The input stream then keeps a weak reference to the entry object and
updates it when more meta-data becomes available. A weak reference being
one that does not prevent you from deleting the wxArchiveEntry object - the
input stream only attempts to update it if it is still around.
The documentation for each archive entry type gives the details
of what meta-data becomes available and when. For generic programming,
when the worst case must be assumed, you can rely on all the fields
of wxArchiveEntry being fully populated when GetNextEntry() returns,
with the the following exceptions:
\begin{twocollist}\twocolwidtha{3cm}
\twocolitem{\helpref{GetSize()}{wxarchiveentrysize}}{Guaranteed to be
available after the entry has been read to \helpref{Eof()}{wxinputstreameof},
or \helpref{CloseEntry()}{wxarchiveinputstreamcloseentry} has been called}
\twocolitem{\helpref{IsReadOnly()}{wxarchiveentryisreadonly}}{Guaranteed to
be available after the end of the archive has been reached, i.e. after
GetNextEntry() returns NULL and Eof() is true}
\end{twocollist}
This mechanism allows \helpref{CopyEntry()}{wxarchiveoutputstreamcopyentry}
to always fully preserve entries' meta-data. No matter what order order
the meta-data occurs within the archive, the input stream will always
have read it before the output stream must write it.
\wxheading{wxArchiveNotifier}
Notifier objects can be used to get a notification whenever an input
stream updates a \helpref{wxArchiveEntry}{wxarchiveentry} object's data
via the weak reference mechanism.
Consider the following code which renames an entry in an archive.
This is the usual way to modify an entry's meta-data, simply set the
required field before writing it with
\helpref{CopyEntry()}{wxarchiveoutputstreamcopyentry}:
\begin{verbatim}
wxArchiveInputStreamPtr arc(factory->NewStream(in));
wxArchiveOutputStreamPtr outarc(factory->NewStream(out));
wxArchiveEntryPtr entry;
outarc->CopyArchiveMetaData(*arc);
while (entry.reset(arc->GetNextEntry()), entry.get() != NULL) {
if (entry->GetName() == from)
entry->SetName(to);
if (!outarc->CopyEntry(entry.release(), *arc))
break;
}
bool success = arc->Eof() && outarc->Close();
\end{verbatim}
However, for non-seekable streams, this technique cannot be used for
fields such as \helpref{IsReadOnly()}{wxarchiveentryisreadonly},
which are not necessarily set when
\helpref{GetNextEntry()}{wxarchiveinputstreamgetnextentry} returns. In
this case a \helpref{wxArchiveNotifier}{wxarchivenotifier} can be used:
\begin{verbatim}
class MyNotifier : public wxArchiveNotifier
{
public:
void OnEntryUpdated(wxArchiveEntry& entry) { entry.SetIsReadOnly(false); }
};
\end{verbatim}
The meta-data changes are done in your notifier's
\helpref{OnEntryUpdated()}{wxarchivenotifieronentryupdated} method,
then \helpref{SetNotifier()}{wxarchiveentrynotifier} is called before
CopyEntry():
\begin{verbatim}
wxArchiveInputStreamPtr arc(factory->NewStream(in));
wxArchiveOutputStreamPtr outarc(factory->NewStream(out));
wxArchiveEntryPtr entry;
MyNotifier notifier;
outarc->CopyArchiveMetaData(*arc);
while (entry.reset(arc->GetNextEntry()), entry.get() != NULL) {
entry->SetNotifier(notifier);
if (!outarc->CopyEntry(entry.release(), *arc))
break;
}
bool success = arc->Eof() && outarc->Close();
\end{verbatim}
SetNotifier() calls OnEntryUpdated() immediately, then the input
stream calls it again whenever it sets more fields in the entry. Since
OnEntryUpdated() will be called at least once, this technique always
works even when it is not strictly necessary to use it. For example,
changing the entry name can be done this way too and it works on seekable
streams as well as non-seekable.

648
docs/latex/wx/archive.tex Normal file
View File

@@ -0,0 +1,648 @@
%
% automatically generated by HelpGen $Revision$ from
% wx/archive.h at 16/Sep/04 12:19:29
%
\section{\class{wxArchiveClassFactory}}\label{wxarchiveclassfactory}
An abstract base class which serves as a common interface to
archive class factories such as \helpref{wxZipClassFactory}{wxzipclassfactory}.
For each supported archive type (such as zip) there is a class factory
derived from wxArchiveClassFactory, which allows archive objects to be
created in a generic way, without knowing the particular type of archive
being used.
\wxheading{Derived from}
\helpref{wxObject}{wxobject}
\wxheading{Include files}
<wx/archive.h>
\wxheading{See also}
\helpref{Archive formats such as zip}{wxarc}\\
\helpref{Generic archive programming}{wxarcgeneric}\\
\helpref{wxArchiveEntry}{wxarchiveentry}\\
\helpref{wxArchiveInputStream}{wxarchiveinputstream}\\
\helpref{wxArchiveOutputStream}{wxarchiveoutputstream}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxArchiveClassFactory::Get/SetConv}\label{wxarchiveclassfactoryconv}
\constfunc{wxMBConv\&}{GetConv}{\void}
\func{void}{SetConv}{\param{wxMBConv\& }{conv}}
The \helpref{wxMBConv}{wxmbconv} object that the created streams
will use when translating meta-data. The initial default, set by the
constructor, is wxConvLocal.
\membersection{wxArchiveClassFactory::GetInternalName}\label{wxarchiveclassfactorygetinternalname}
\constfunc{wxString}{GetInternalName}{\param{const wxString\& }{name}, \param{wxPathFormat }{format = wxPATH\_NATIVE}}
Calls the static GetInternalName() function for the archive entry type,
for example
\helpref{wxZipEntry::GetInternalName()}{wxzipentrygetinternalname}.
\membersection{wxArchiveClassFactory::NewEntry}\label{wxarchiveclassfactorynewentry}
\constfunc{wxArchiveEntry*}{NewEntry}{\void}
Create a new \helpref{wxArchiveEntry}{wxarchiveentry} object of the
appropriate type.
\membersection{wxArchiveClassFactory::NewStream}\label{wxarchiveclassfactorynewstream}
\constfunc{wxArchiveInputStream*}{NewStream}{\param{wxInputStream\& }{stream}}
\constfunc{wxArchiveOutputStream*}{NewStream}{\param{wxOutputStream\& }{stream}}
Create a new \helpref{wxArchiveInputStream}{wxarchiveinputstream}
or \helpref{wxArchiveOutputStream}{wxarchiveoutputstream} of the
appropriate type.
%
% automatically generated by HelpGen $Revision$ from
% wx/archive.h at 16/Sep/04 12:19:29
%
\section{\class{wxArchiveEntry}}\label{wxarchiveentry}
An abstract base class which serves as a common interface to
archive entry classes such as \helpref{wxZipEntry}{wxzipentry}.
These hold the meta-data (filename, timestamp, etc.), for entries
in archive files such as zips and tars.
\wxheading{Derived from}
\helpref{wxObject}{wxobject}
\wxheading{Include files}
<wx/archive.h>
\wxheading{See also}
\helpref{Archive formats such as zip}{wxarc}\\
\helpref{Generic archive programming}{wxarcgeneric}\\
\helpref{wxArchiveInputStream}{wxarchiveinputstream}\\
\helpref{wxArchiveOutputStream}{wxarchiveoutputstream}\\
\helpref{wxArchiveNotifier}{wxarchivenotifier}
\wxheading{Non-seekable streams}
This information applies only when reading archives from non-seekable
streams. When the stream is
seekable \helpref{GetNextEntry()}{wxarchiveinputstreamgetnextentry}
returns a fully populated \helpref{wxArchiveEntry}{wxarchiveentry}.
See '\helpref{Archives on non-seekable streams}{wxarcnoseek}' for
more information.
For generic programming, when the worst case must be assumed, you can
rely on all the fields of wxArchiveEntry being fully populated when
GetNextEntry() returns, with the the following exceptions:
\begin{twocollist}\twocolwidtha{3cm}
\twocolitem{\helpref{GetSize()}{wxarchiveentrysize}}{Guaranteed to be
available after the entry has been read to \helpref{Eof()}{wxinputstreameof},
or \helpref{CloseEntry()}{wxarchiveinputstreamcloseentry} has been called}
\twocolitem{\helpref{IsReadOnly()}{wxarchiveentryisreadonly}}{Guaranteed to
be available after the end of the archive has been reached, i.e. after
GetNextEntry() returns NULL and Eof() is true}
\end{twocollist}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxArchiveEntry::Clone}\label{wxarchiveentryclone}
\constfunc{wxArchiveEntry*}{Clone}{\void}
Returns a copy of this entry object.
\membersection{wxArchiveEntry::Get/SetDateTime}\label{wxarchiveentrydatetime}
\constfunc{wxDateTime}{GetDateTime}{\void}
\func{void}{SetDateTime}{\param{const wxDateTime\& }{dt}}
The entry's timestamp.
\membersection{wxArchiveEntry::GetInternalFormat}\label{wxarchiveentrygetinternalformat}
\constfunc{wxPathFormat}{GetInternalFormat}{\void}
Returns the path format used internally within the archive to store
filenames.
\membersection{wxArchiveEntry::GetInternalName}\label{wxarchiveentrygetinternalname}
\constfunc{wxString}{GetInternalName}{\void}
Returns the entry's filename in the internal format used within the
archive. The name can include directory components, i.e. it can be a
full path.
The names of directory entries are returned without any trailing path
separator. This gives a canonical name that can be used in comparisons.
\wxheading{See also}
\helpref{Looking up an archive entry by name}{wxarcbyname}
\membersection{wxArchiveEntry::Get/SetName}\label{wxarchiveentryname}
\constfunc{wxString}{GetName}{\param{wxPathFormat }{format = wxPATH\_NATIVE}}
\func{void}{SetName}{\param{const wxString\& }{name}, \param{wxPathFormat }{format = wxPATH\_NATIVE}}
The entry's name, by default in the native format. The name can include
directory components, i.e. it can be a full path.
If this is a directory entry, (i.e. if \helpref{IsDir()}{wxarchiveentryisdir}
is true) then GetName() returns the name with a trailing path separator.
Similarly, setting a name with a trailing path separator sets IsDir().
\membersection{wxArchiveEntry::GetOffset}\label{wxarchiveentrygetoffset}
\constfunc{off\_t}{GetOffset}{\void}
Returns a numeric value unique to the entry within the archive.
\membersection{wxArchiveEntry::Get/SetSize}\label{wxarchiveentrysize}
\constfunc{off\_t}{GetSize}{\void}
\func{void}{SetSize}{\param{off\_t }{size}}
The size of the entry's data in bytes.
\membersection{wxArchiveEntry::IsDir/SetIsDir}\label{wxarchiveentryisdir}
\constfunc{bool}{IsDir}{\void}
\func{void}{SetIsDir}{\param{bool }{isDir = true}}
True if this is a directory entry.
Directory entries are entries with no data, which are used to store
the meta-data of directories. They also make it possible for completely
empty directories to be stored.
The names of entries within an archive can be complete paths, and
unarchivers typically create whatever directories are necessary as they
restore files, even if the archive contains no explicit directory entries.
\membersection{wxArchiveEntry::IsReadOnly/SetIsReadOnly}\label{wxarchiveentryisreadonly}
\constfunc{bool}{IsReadOnly}{\void}
\func{void}{SetIsReadOnly}{\param{bool }{isReadOnly = true}}
True if the entry is a read-only file.
\membersection{wxArchiveEntry::Set/UnsetNotifier}\label{wxarchiveentrynotifier}
\func{void}{SetNotifier}{\param{wxArchiveNotifier\& }{notifier}}
\func{void}{UnsetNotifier}{\void}
Sets the \helpref{notifier}{wxarchivenotifier} for this entry.
Whenever the \helpref{wxArchiveInputStream}{wxarchiveinputstream} updates
this entry, it will then invoke the associated
notifier's \helpref{OnEntryUpdated}{wxarchivenotifieronentryupdated}
method.
Setting a notifier is not usually necessary. It is used to handle
certain cases when modifying an archive in a pipeline (i.e. between
non-seekable streams).
\wxheading{See also}
\helpref{Archives on non-seekable streams}{wxarcnoseek}\\
\helpref{wxArchiveNotifier}{wxarchivenotifier}
%
% automatically generated by HelpGen $Revision$ from
% wx/archive.h at 16/Sep/04 12:19:29
%
\section{\class{wxArchiveInputStream}}\label{wxarchiveinputstream}
An abstract base class which serves as a common interface to
archive input streams such as \helpref{wxZipInputStream}{wxzipinputstream}.
\helpref{GetNextEntry()}{wxarchiveinputstreamgetnextentry} returns an
\helpref{wxArchiveEntry}{wxarchiveentry} object containing the meta-data
for the next entry in the archive (and gives away ownership). Reading from
the wxArchiveInputStream then returns the entry's data. Eof() becomes true
after an attempt has been made to read past the end of the entry's data.
When there are no more entries, GetNextEntry() returns NULL and sets Eof().
\wxheading{Derived from}
\helpref{wxFilterInputStream}{wxfilterinputstream}
\wxheading{Include files}
<wx/archive.h>
\wxheading{Data structures}
{\small \begin{verbatim}
typedef wxArchiveEntry entry\_type
\end{verbatim}}
\wxheading{See also}
\helpref{Archive formats such as zip}{wxarc}\\
\helpref{wxArchiveEntry}{wxarchiveentry}\\
\helpref{wxArchiveOutputStream}{wxarchiveoutputstream}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxArchiveInputStream::CloseEntry}\label{wxarchiveinputstreamcloseentry}
\func{bool}{CloseEntry}{\void}
Closes the current entry. On a non-seekable stream reads to the end of
the current entry first.
\membersection{wxArchiveInputStream::GetNextEntry}\label{wxarchiveinputstreamgetnextentry}
\func{wxArchiveEntry*}{GetNextEntry}{\void}
Closes the current entry if one is open, then reads the meta-data for
the next entry and returns it in a \helpref{wxArchiveEntry}{wxarchiveentry}
object, giving away ownership. Reading this wxArchiveInputStream then
returns the entry's data.
\membersection{wxArchiveInputStream::OpenEntry}\label{wxarchiveinputstreamopenentry}
\func{bool}{OpenEntry}{\param{wxArchiveEntry\& }{entry}}
Closes the current entry if one is open, then opens the entry specified
by the \helpref{wxArchiveEntry}{wxarchiveentry} object.
{\it entry} must be from the same archive file that this
wxArchiveInputStream is reading, and it must be reading it from a
seekable stream.
\wxheading{See also}
\helpref{Looking up an archive entry by name}{wxarcbyname}
%
% automatically generated by HelpGen $Revision$ from
% wx/archive.h at 16/Sep/04 12:19:29
%
\section{\class{wxArchiveIterator}}\label{wxarchiveiterator}
An input iterator template class that can be used to transfer an archive's
catalogue to a container. It is only available if wxUSE\_STL is set to 1
in setup.h, and the uses for it outlined below require a compiler which
supports member templates.
\begin{verbatim}
template <class Arc, class T = typename Arc::entry_type*>
class wxArchiveIterator
{
// this constructor creates an 'end of sequence' object
wxArchiveIterator();
// template parameter 'Arc' should be the type of an archive input stream
wxArchiveIterator(Arc& arc) {
/* ... */
};
\end{verbatim}
The first template parameter should be the type of archive input stream
(e.g. \helpref{wxArchiveInputStream}{wxarchiveinputstream}) and the
second can either be a pointer to an entry
(e.g. \helpref{wxArchiveEntry}{wxarchiveentry}*), or a string/pointer pair
(e.g. std::pair<wxString, wxArchiveEntry*>).
The {\tt <wx/archive.h>} header defines the following typedefs:
\begin{verbatim}
typedef wxArchiveIterator<wxArchiveInputStream> wxArchiveIter;
typedef wxArchiveIterator<wxArchiveInputStream,
std::pair<wxString, wxArchiveEntry*> > wxArchivePairIter;
\end{verbatim}
The header for any implementation of this interface should define similar
typedefs for its types, for example in {\tt <wx/zipstrm.h>} there is:
\begin{verbatim}
typedef wxArchiveIterator<wxZipInputStream> wxZipIter;
typedef wxArchiveIterator<wxZipInputStream,
std::pair<wxString, wxZipEntry*> > wxZipPairIter;
\end{verbatim}
Transferring the catalogue of an archive {\it arc} to a vector {\it cat},
can then be done something like this:
\begin{verbatim}
std::vector<wxArchiveEntry*> cat((wxArchiveIter)arc, wxArchiveIter());
\end{verbatim}
When the iterator is dereferenced, it gives away ownership of an entry
object. So in the above example, when you have finished with {\it cat}
you must delete the pointers it contains.
If you have smart pointers with normal copy semantics (i.e. not auto\_ptr
or \helpref{wxScopedPtr}{wxscopedptr}), then you can create an iterator
which uses them instead. For example, with a smart pointer class for
zip entries {\it ZipEntryPtr}:
\begin{verbatim}
typedef std::vector<ZipEntryPtr> ZipCatalog;
typedef wxArchiveIterator<wxZipInputStream, ZipEntryPtr> ZipIter;
ZipCatalog cat((ZipIter)zip, ZipIter());
\end{verbatim}
Iterators that return std::pair objects can be used to
populate a std::multimap, to allow entries to be looked
up by name. The string is initialised using the wxArchiveEntry object's
\helpref{GetInternalName()}{wxarchiveentrygetinternalname} function.
\begin{verbatim}
typedef std::multimap<wxString, wxZipEntry*> ZipCatalog;
ZipCatalog cat((wxZipPairIter)zip, wxZipPairIter());
\end{verbatim}
Note that this iterator also gives away ownership of an entry
object each time it is dereferenced. So in the above example, when
you have finished with {\it cat} you must delete the pointers it contains.
Or if you have them, a pair containing a smart pointer can be used
(again {\it ZipEntryPtr}), no worries about ownership:
\begin{verbatim}
typedef std::multimap<wxString, ZipEntryPtr> ZipCatalog;
typedef wxArchiveIterator<wxZipInputStream,
std::pair<wxString, ZipEntryPtr> > ZipPairIter;
ZipCatalog cat((ZipPairIter)zip, ZipPairIter());
\end{verbatim}
\wxheading{Derived from}
No base class
\wxheading{Include files}
<wx/archive.h>
\wxheading{See also}
\helpref{wxArchiveEntry}{wxarchiveentry}\\
\helpref{wxArchiveInputStream}{wxarchiveinputstream}\\
\helpref{wxArchiveOutputStream}{wxarchiveoutputstream}
\wxheading{Data structures}
{\small \begin{verbatim}
typedef std::input\_iterator\_tag iterator\_category
typedef T value\_type
typedef ptrdiff\_t difference\_type
typedef T* pointer
typedef T\& reference
\end{verbatim}}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxArchiveIterator::wxArchiveIterator}\label{wxarchiveiteratorwxarchiveiterator}
\func{}{wxArchiveIterator}{\void}
Construct an 'end of sequence' instance.
\func{}{wxArchiveIterator}{\param{Arc\& }{arc}}
Construct iterator that returns all the entries in the archive input
stream {\it arc}.
\membersection{wxArchiveIterator::operator*}\label{wxarchiveiteratoroperatorunknown}
\constfunc{const T\&}{operator*}{\void}
Returns an entry object from the archive input stream, giving away
ownership.
\membersection{wxArchiveIterator::operator++}\label{wxarchiveiteratoroperatorunknown}
\func{wxArchiveIterator\&}{operator++}{\void}
\func{wxArchiveIterator\&}{operator++}{\param{int}{}}
Position the input iterator at the next entry in the archive input stream.
%
% automatically generated by HelpGen $Revision$ from
% wx/archive.h at 16/Sep/04 12:19:29
%
\section{\class{wxArchiveNotifier}}\label{wxarchivenotifier}
If you need to know when a
\helpref{wxArchiveInputStream}{wxarchiveinputstream} updates a
\helpref{wxArchiveEntry}{wxarchiveentry} object, you can create
a notifier by deriving from this abstract base class, overriding
\helpref{OnEntryUpdated()}{wxarchivenotifieronentryupdated}. An instance
of your notifier class can then be assigned to the wxArchiveEntry object
using \helpref{wxArchiveEntry::SetNotifier()}{wxarchiveentrynotifier}.
Your OnEntryUpdated() method will then be invoked whenever the input
stream updates the entry.
Setting a notifier is not usually necessary. It is used to handle
certain cases when modifying an archive in a pipeline (i.e. between
non-seekable streams).
See \helpref{Archives on non-seekable streams}{wxarcnoseek}.
\wxheading{Derived from}
No base class
\wxheading{Include files}
<wx/archive.h>
\wxheading{See also}
\helpref{Archives on non-seekable streams}{wxarcnoseek}\\
\helpref{wxArchiveEntry}{wxarchiveentry}\\
\helpref{wxArchiveInputStream}{wxarchiveinputstream}\\
\helpref{wxArchiveOutputStream}{wxarchiveoutputstream}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxArchiveNotifier::OnEntryUpdated}\label{wxarchivenotifieronentryupdated}
\func{void}{OnEntryUpdated}{\param{class wxArchiveEntry\& }{entry}}
This method must be overridden in your derived class.
%
% automatically generated by HelpGen $Revision$ from
% wx/archive.h at 16/Sep/04 12:19:29
%
\section{\class{wxArchiveOutputStream}}\label{wxarchiveoutputstream}
An abstract base class which serves as a common interface to
archive output streams such as \helpref{wxZipOutputStream}{wxzipoutputstream}.
\helpref{PutNextEntry()}{wxarchiveoutputstreamputnextentry} is used
to create a new entry in the output archive, then the entry's data is
written to the wxArchiveOutputStream. Another call to PutNextEntry()
closes the current entry and begins the next.
\wxheading{Derived from}
\helpref{wxFilterOutputStream}{wxfilteroutputstream}
\wxheading{Include files}
<wx/archive.h>
\wxheading{See also}
\helpref{Archive formats such as zip}{wxarc}\\
\helpref{wxArchiveEntry}{wxarchiveentry}\\
\helpref{wxArchiveInputStream}{wxarchiveinputstream}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxArchiveOutputStream::\destruct{wxArchiveOutputStream}}\label{wxarchiveoutputstreamdtor}
\func{}{\destruct{wxArchiveOutputStream}}{\void}
Calls \helpref{Close()}{wxarchiveoutputstreamclose} if it has not already
been called.
\membersection{wxArchiveOutputStream::Close}\label{wxarchiveoutputstreamclose}
\func{bool}{Close}{\void}
Closes the archive, returning true if it was successfully written.
Called by the destructor if not called explicitly.
\membersection{wxArchiveOutputStream::CloseEntry}\label{wxarchiveoutputstreamcloseentry}
\func{bool}{CloseEntry}{\void}
Close the current entry. It is called implicitly whenever another new
entry is created with \helpref{CopyEntry()}{wxarchiveoutputstreamcopyentry}
or \helpref{PutNextEntry()}{wxarchiveoutputstreamputnextentry}, or
when the archive is closed.
\membersection{wxArchiveOutputStream::CopyArchiveMetaData}\label{wxarchiveoutputstreamcopyarchivemetadata}
\func{bool}{CopyArchiveMetaData}{\param{wxArchiveInputStream\& }{stream}}
Some archive formats have additional meta-data that applies to the archive
as a whole. For example in the case of zip there is a comment, which
is stored at the end of the zip file. CopyArchiveMetaData() can be used
to transfer such information when writing a modified copy of an archive.
Since the position of the meta-data can vary between the various archive
formats, it is best to call CopyArchiveMetaData() before transferring
the entries. The \helpref{wxArchiveOutputStream}{wxarchiveoutputstream}
will then hold on to the meta-data and write it at the correct point in
the output file.
When the input archive is being read from a non-seekable stream, the
meta-data may not be available when CopyArchiveMetaData() is called,
in which case the two streams set up a link and transfer the data
when it becomes available.
\membersection{wxArchiveOutputStream::CopyEntry}\label{wxarchiveoutputstreamcopyentry}
\func{bool}{CopyEntry}{\param{wxArchiveEntry* }{entry}, \param{wxArchiveInputStream\& }{stream}}
Takes ownership of {\it entry} and uses it to create a new entry in the
archive. {\it entry} is then opened in the input stream {\it stream}
and its contents copied to this stream.
For archive types which compress entry data, CopyEntry() is likely to be
much more efficient than transferring the data using Read() and Write()
since it will copy them without decompressing and recompressing them.
{\it entry} must be from the same archive file that {\it stream} is
accessing. For non-seekable streams, {\it entry} must also be the last
thing read from {\it stream}.
\membersection{wxArchiveOutputStream::PutNextDirEntry}\label{wxarchiveoutputstreamputnextdirentry}
\func{bool}{PutNextDirEntry}{\param{const wxString\& }{name}, \param{const wxDateTime\& }{dt = wxDateTime::Now()}}
Create a new directory entry
(see \helpref{wxArchiveEntry::IsDir()}{wxarchiveentryisdir})
with the given name and timestamp.
\helpref{PutNextEntry()}{wxarchiveoutputstreamputnextentry} can
also be used to create directory entries, by supplying a name with
a trailing path separator.
\membersection{wxArchiveOutputStream::PutNextEntry}\label{wxarchiveoutputstreamputnextentry}
\func{bool}{PutNextEntry}{\param{wxArchiveEntry* }{entry}}
Takes ownership of {\it entry} and uses it to create a new entry in
the archive. The entry's data can then be written by writing to this
wxArchiveOutputStream.
\func{bool}{PutNextEntry}{\param{const wxString\& }{name}, \param{const wxDateTime\& }{dt = wxDateTime::Now()}, \param{off\_t }{size = wxInvalidOffset}}
Create a new entry with the given name, timestamp and size. The entry's
data can then be written by writing to this wxArchiveOutputStream.

View File

@@ -9,6 +9,7 @@
\input accessible.tex
\input activevt.tex
\input app.tex
\input archive.tex
\input array.tex
\input arrstrng.tex
\input artprov.tex

View File

@@ -59,4 +59,5 @@ This chapter contains a selection of topic overviews, first things first:
\input tenvvars.tex
\input wxPython.tex
\input re_syntax.tex
\input arc.tex

View File

@@ -1,40 +1,706 @@
%
% automatically generated by HelpGen from
% zipstream.h at 02/May/99 19:54:25
% automatically generated by HelpGen $Revision$ from
% wx/zipstrm.h at 16/Sep/04 12:19:29
%
\section{\class{wxZipInputStream}}\label{wxzipinputstream}
This class is input stream from ZIP archive. The archive
must be local file (accessible via FILE*).
It has all features including GetSize and seeking.
\wxheading{Note}
If you need to enumerate files in ZIP archive, you can use
\helpref{wxFileSystem}{wxfilesystem} together with wxZipFSHandler (see
\helpref{the overview}{fs}).
\section{\class{wxZipClassFactory}}\label{wxzipclassfactory}
Class factory for the zip archive format. See the base class
for details.
\wxheading{Derived from}
\helpref{wxInputStream}{wxinputstream}
\helpref{wxArchiveClassFactory}{wxarchiveclassfactory}
\wxheading{Include files}
<wx/zipstrm.h>
\wxheading{See also}
\helpref{Archive formats such as zip}{wxarc}\\
\helpref{Generic archive programming}{wxarcgeneric}
\helpref{wxZipEntry}{wxzipentry}\\
\helpref{wxZipInputStream}{wxzipinputstream}\\
\helpref{wxZipOutputStream}{wxzipoutputstream}
%
% automatically generated by HelpGen $Revision$ from
% wx/zipstrm.h at 16/Sep/04 12:19:29
%
\section{\class{wxZipEntry}}\label{wxzipentry}
Holds the meta-data for an entry in a zip.
\wxheading{Derived from}
\helpref{wxArchiveEntry}{wxarchiveentry}
\wxheading{Include files}
<wx/zipstrm.h>
\wxheading{Data structures}
Constants for \helpref{Get/SetMethod}{wxzipentrymethod}:
\begin{verbatim}
// Compression Method, only 0 (store) and 8 (deflate) are supported here
//
enum wxZipMethod
{
wxZIP_METHOD_STORE,
wxZIP_METHOD_SHRINK,
wxZIP_METHOD_REDUCE1,
wxZIP_METHOD_REDUCE2,
wxZIP_METHOD_REDUCE3,
wxZIP_METHOD_REDUCE4,
wxZIP_METHOD_IMPLODE,
wxZIP_METHOD_TOKENIZE,
wxZIP_METHOD_DEFLATE,
wxZIP_METHOD_DEFLATE64,
wxZIP_METHOD_BZIP2 = 12,
wxZIP_METHOD_DEFAULT = 0xffff
};
\end{verbatim}
Constants for \helpref{Get/SetSystemMadeBy}{wxzipentrysystemmadeby}:
\begin{verbatim}
// Originating File-System.
//
// These are Pkware's values. Note that Info-zip disagree on some of them,
// most notably NTFS.
//
enum wxZipSystem
{
wxZIP_SYSTEM_MSDOS,
wxZIP_SYSTEM_AMIGA,
wxZIP_SYSTEM_OPENVMS,
wxZIP_SYSTEM_UNIX,
wxZIP_SYSTEM_VM_CMS,
wxZIP_SYSTEM_ATARI_ST,
wxZIP_SYSTEM_OS2_HPFS,
wxZIP_SYSTEM_MACINTOSH,
wxZIP_SYSTEM_Z_SYSTEM,
wxZIP_SYSTEM_CPM,
wxZIP_SYSTEM_WINDOWS_NTFS,
wxZIP_SYSTEM_MVS,
wxZIP_SYSTEM_VSE,
wxZIP_SYSTEM_ACORN_RISC,
wxZIP_SYSTEM_VFAT,
wxZIP_SYSTEM_ALTERNATE_MVS,
wxZIP_SYSTEM_BEOS,
wxZIP_SYSTEM_TANDEM,
wxZIP_SYSTEM_OS_400
};
\end{verbatim}
Constants for \helpref{Get/SetExternalAttributes}{wxzipentryexternalattributes}:
\begin{verbatim}
// Dos/Win file attributes
//
enum wxZipAttributes
{
wxZIP_A_RDONLY = 0x01,
wxZIP_A_HIDDEN = 0x02,
wxZIP_A_SYSTEM = 0x04,
wxZIP_A_SUBDIR = 0x10,
wxZIP_A_ARCH = 0x20,
wxZIP_A_MASK = 0x37
};
\end{verbatim}
Constants for \helpref{Get/SetFlags}{wxzipentrygetflags}:
\begin{verbatim}
// Values for the flags field in the zip headers
//
enum wxZipFlags
{
wxZIP_ENCRYPTED = 0x0001,
wxZIP_DEFLATE_NORMAL = 0x0000, // normal compression
wxZIP_DEFLATE_EXTRA = 0x0002, // extra compression
wxZIP_DEFLATE_FAST = 0x0004, // fast compression
wxZIP_DEFLATE_SUPERFAST = 0x0006, // superfast compression
wxZIP_DEFLATE_MASK = 0x0006,
wxZIP_SUMS_FOLLOW = 0x0008, // crc and sizes come after the data
wxZIP_ENHANCED = 0x0010,
wxZIP_PATCH = 0x0020,
wxZIP_STRONG_ENC = 0x0040,
wxZIP_UNUSED = 0x0F80,
wxZIP_RESERVED = 0xF000
};
\end{verbatim}
\wxheading{See also}
\helpref{Archive formats such as zip}{wxarc}\\
\helpref{wxZipInputStream}{wxzipinputstream}\\
\helpref{wxZipOutputStream}{wxzipoutputstream}\\
\helpref{wxZipNotifier}{wxzipnotifier}
\wxheading{Field availability}
When reading a zip from a stream that is seekable,
\helpref{GetNextEntry()}{wxzipinputstreamgetnextentry} returns
a fully populated wxZipEntry object except for
\helpref{wxZipEntry::GetLocalExtra()}{wxzipentrylocalextra}. GetLocalExtra()
becomes available when the entry is opened, either by calling
\helpref{wxZipInputStream::OpenEntry}{wxzipinputstreamopenentry} or by
making an attempt to read the entry's data.
For zips on \helpref{non-seekable}{wxarcnoseek} streams, the following
fields are always available when GetNextEntry() returns:
\helpref{GetDateTime}{wxarchiveentrydatetime}\\
\helpref{GetInternalFormat}{wxarchiveentrygetinternalformat}\\
\helpref{GetInternalName}{wxzipentrygetinternalname}\\
\helpref{GetFlags}{wxzipentrygetflags}\\
\helpref{GetLocalExtra}{wxzipentrylocalextra}\\
\helpref{GetMethod}{wxzipentrymethod}\\
\helpref{GetName}{wxarchiveentryname}\\
\helpref{GetOffset}{wxarchiveentrygetoffset}\\
\helpref{IsDir}{wxarchiveentryisdir}
The following fields are also usually available when GetNextEntry()
returns, however, if the zip was also written to a non-seekable stream
the zipper is permitted to store them after the entry's data. In that
case they become available when the entry's data has been read to Eof(),
or \helpref{CloseEntry()}{wxarchiveinputstreamcloseentry} has been called.
{\tt (GetFlags() \& wxZIP\_SUMS\_FOLLOW) != 0} indicates that one or
more of these come after the data:
\helpref{GetCompressedSize}{wxzipentrygetcompressedsize}\\
\helpref{GetCrc}{wxzipentrygetcrc}\\
\helpref{GetSize}{wxarchiveentrysize}
The following are stored at the end of the zip, and become available
when the end of the zip has been reached, i.e. after GetNextEntry()
returns NULL and Eof() is true:
\helpref{GetComment}{wxzipentrycomment}\\
\helpref{GetExternalAttributes}{wxzipentryexternalattributes}\\
\helpref{GetExtra}{wxzipentryextra}\\
\helpref{GetMode}{wxzipentrymode}\\
\helpref{GetSystemMadeBy}{wxzipentrysystemmadeby}\\
\helpref{IsReadOnly}{wxarchiveentryisreadonly}\\
\helpref{IsMadeByUnix}{wxzipentryismadebyunix}\\
\helpref{IsText}{wxzipentryistext}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxZipInputStream::wxZipInputStream}\label{wxzipinputstreamwxzipinputstream}
\func{}{wxZipInputStream}{\param{const wxString\& }{archive}, \param{const wxString\& }{file}}
\membersection{wxZipEntry::wxZipEntry}\label{wxzipentrywxzipentry}
\func{}{wxZipEntry}{\param{const wxString\& }{name = wxEmptyString}, \param{const wxDateTime\& }{dt = wxDateTime::Now()}, \param{off\_t }{size = wxInvalidOffset}}
Constructor.
\wxheading{Parameters}
\func{}{wxZipEntry}{\param{const wxZipEntry\& }{entry}}
\docparam{archive}{name of ZIP file}
Copy constructor.
\docparam{file}{name of file stored in the archive}
\membersection{wxZipEntry::Clone}\label{wxzipentryclone}
\constfunc{wxZipEntry*}{Clone}{\void}
Make a copy of this entry.
\membersection{wxZipEntry::Get/SetComment}\label{wxzipentrycomment}
\constfunc{wxString}{GetComment}{\void}
\func{void}{SetComment}{\param{const wxString\& }{comment}}
A short comment for this entry.
\membersection{wxZipEntry::GetCompressedSize}\label{wxzipentrygetcompressedsize}
\constfunc{off\_t}{GetCompressedSize}{\void}
The compressed size of this entry in bytes.
\membersection{wxZipEntry::GetCrc}\label{wxzipentrygetcrc}
\constfunc{wxUint32}{GetCrc}{\void}
CRC32 for this entry's data.
\membersection{wxZipEntry::Get/SetExternalAttributes}\label{wxzipentryexternalattributes}
\constfunc{wxUint32}{GetExternalAttributes}{\void}
\func{void}{SetExternalAttributes}{\param{wxUint32 }{attr}}
The low 8 bits are always the DOS/Windows file attributes for this entry.
The values of these attributes are given in the
enumeration {\tt wxZipAttributes}.
The remaining bits can store platform specific permission bits or
attributes, and their meaning depends on the value
of \helpref{SetSystemMadeBy()}{wxzipentrysystemmadeby}.
If \helpref{IsMadeByUnix()}{wxzipentryismadebyunix} is true then the
high 16 bits are unix mode bits.
The following other accessors access these bits:
\helpref{IsReadOnly/SetIsReadOnly}{wxarchiveentryisreadonly}\\
\helpref{IsDir/SetIsDir}{wxarchiveentryisdir}\\
\helpref{Get/SetMode}{wxzipentrymode}
\membersection{wxZipEntry::Get/SetExtra}\label{wxzipentryextra}
\constfunc{const char*}{GetExtra}{\void}
\constfunc{size\_t}{GetExtraLen}{\void}
\func{void}{SetExtra}{\param{const char* }{extra}, \param{size\_t }{len}}
The extra field from the entry's central directory record.
The extra field is used to store platform or application specific
data. See Pkware's document 'appnote.txt' for information on its format.
\membersection{wxZipEntry::GetFlags}\label{wxzipentrygetflags}
\constfunc{int}{GetFlags}{\void}
Returns a combination of the bits flags in the enumeration {\tt wxZipFlags}.
\membersection{wxZipEntry::GetInternalName}\label{wxzipentrygetinternalname}
\constfunc{wxString}{GetInternalName}{\void}
Returns the entry's filename in the internal format used within the
archive. The name can include directory components, i.e. it can be a
full path.
The names of directory entries are returned without any trailing path
separator. This gives a canonical name that can be used in comparisons.
\func{wxString}{GetInternalName}{\param{const wxString\& }{name}, \param{wxPathFormat }{format = wxPATH\_NATIVE}, \param{bool* }{pIsDir = NULL}}
A static member that translates a filename into the internal format used
within the archive. If the third parameter is provided, the bool pointed
to is set to indicate whether the name looks like a directory name
(i.e. has a trailing path separator).
\wxheading{See also}
\helpref{Looking up an archive entry by name}{wxarcbyname}
\membersection{wxZipEntry::Get/SetLocalExtra}\label{wxzipentrylocalextra}
\constfunc{const char*}{GetLocalExtra}{\void}
\constfunc{size\_t}{GetLocalExtraLen}{\void}
\func{void}{SetLocalExtra}{\param{const char* }{extra}, \param{size\_t }{len}}
The extra field from the entry's local record.
The extra field is used to store platform or application specific
data. See Pkware's document 'appnote.txt' for information on its format.
\membersection{wxZipEntry::Get/SetMethod}\label{wxzipentrymethod}
\constfunc{int}{GetMethod}{\void}
\func{void}{SetMethod}{\param{int }{method}}
The compression method. The enumeration {\tt wxZipMethod} lists the
possible values.
The default constructor sets this to wxZIP\_METHOD\_DEFAULT,
which allows \helpref{wxZipOutputStream}{wxzipoutputstream} to
choose the method when writing the entry.
\membersection{wxZipEntry::Get/SetMode}\label{wxzipentrymode}
\constfunc{int}{GetMode}{\void}
If \helpref{IsMadeByUnix()}{wxzipentryismadebyunix} is true then
returns the unix permission bits stored in
\helpref{GetExternalAttributes()}{wxzipentryexternalattributes}.
Otherwise synthesises them from the DOS attributes.
\func{void}{SetMode}{\param{int }{mode}}
Sets the DOS attributes
in \helpref{GetExternalAttributes()}{wxzipentryexternalattributes}
to be consistent with the {\tt mode} given.
If \helpref{IsMadeByUnix()}{wxzipentryismadebyunix} is true then also
stores {\tt mode} in GetExternalAttributes().
Note that the default constructor
sets \helpref{GetSystemMadeBy()}{wxzipentrysystemmadeby} to
wxZIP\_SYSTEM\_MSDOS by default. So to be able to store unix
permissions when creating zips, call SetSystemMadeBy(wxZIP\_SYSTEM\_UNIX).
\membersection{wxZipEntry::SetNotifier}\label{wxzipentrynotifier}
\func{void}{SetNotifier}{\param{wxZipNotifier\& }{notifier}}
\func{void}{UnsetNotifier}{\void}
Sets the \helpref{notifier}{wxzipnotifier} for this entry.
Whenever the \helpref{wxZipInputStream}{wxzipinputstream} updates
this entry, it will then invoke the associated
notifier's \helpref{OnEntryUpdated}{wxzipnotifieronentryupdated}
method.
Setting a notifier is not usually necessary. It is used to handle
certain cases when modifying an zip in a pipeline (i.e. between
non-seekable streams).
\wxheading{See also}
\helpref{Archives on non-seekable streams}{wxarcnoseek}\\
\helpref{wxZipNotifier}{wxzipnotifier}
\membersection{wxZipEntry::Get/SetSystemMadeBy}\label{wxzipentrysystemmadeby}
\constfunc{int}{GetSystemMadeBy}{\void}
\func{void}{SetSystemMadeBy}{\param{int }{system}}
The originating file-system. The default constructor sets this to
wxZIP\_SYSTEM\_MSDOS. Set it to wxZIP\_SYSTEM\_UNIX in order to be
able to store unix permissions using \helpref{SetMode()}{wxzipentrymode}.
\membersection{wxZipEntry::IsMadeByUnix}\label{wxzipentryismadebyunix}
\constfunc{bool}{IsMadeByUnix}{\void}
Returns true if \helpref{GetSystemMadeBy()}{wxzipentrysystemmadeby}
is a flavour of unix.
\membersection{wxZipEntry::IsText/SetIsText}\label{wxzipentryistext}
\constfunc{bool}{IsText}{\void}
\func{void}{SetIsText}{\param{bool }{isText = true}}
Indicates that this entry's data is text in an 8-bit encoding.
\membersection{wxZipEntry::operator=}\label{wxzipentryoperatorassign}
\func{wxZipEntry\& operator}{operator=}{\param{const wxZipEntry\& }{entry}}
Assignment operator.
%
% automatically generated by HelpGen $Revision$ from
% wx/zipstrm.h at 16/Sep/04 12:19:29
%
\section{\class{wxZipInputStream}}\label{wxzipinputstream}
Input stream for reading zip files.
\helpref{GetNextEntry()}{wxzipinputstreamgetnextentry} returns an
\helpref{wxZipEntry}{wxzipentry} object containing the meta-data
for the next entry in the zip (and gives away ownership). Reading from
the wxZipInputStream then returns the entry's data. Eof() becomes true
after an attempt has been made to read past the end of the entry's data.
When there are no more entries, GetNextEntry() returns NULL and sets Eof().
\wxheading{Derived from}
\helpref{wxArchiveInputStream}{wxarchiveinputstream}
\wxheading{Include files}
<wx/zipstrm.h>
\wxheading{Data structures}
{\small \begin{verbatim}
typedef wxZipEntry entry\_type
\end{verbatim}}
\wxheading{See also}
\helpref{Archive formats such as zip}{wxarc}\\
\helpref{wxZipEntry}{wxzipentry}\\
\helpref{wxZipOutputStream}{wxzipoutputstream}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxZipInputStream::wxZipInputStream}\label{wxzipinputstreamwxzipinputstream}
\func{}{wxZipInputStream}{\param{wxInputStream\& }{stream}, \param{wxMBConv\& }{conv = wxConvLocal}}
Constructor. In a Unicode build the second parameter {\tt conv} is
used to translate the filename and comment fields into Unicode. It has
no effect on the stream's data.
\func{}{wxZipInputStream}{\param{const wxString\& }{archive}, \param{const wxString\& }{file}}
Compatibility constructor.
\membersection{wxZipInputStream::CloseEntry}\label{wxzipinputstreamcloseentry}
\func{bool}{CloseEntry}{\void}
Closes the current entry. On a non-seekable stream reads to the end of
the current entry first.
\membersection{wxZipInputStream::GetComment}\label{wxzipinputstreamgetcomment}
\func{wxString}{GetComment}{\void}
Returns the zip comment.
This is stored a the end of the zip, therefore when reading a zip
from a non-seekable stream, it returns the empty string until the
end of the zip has been reached, i.e. when GetNextEntry() returns
NULL.
\membersection{wxZipInputStream::GetNextEntry}\label{wxzipinputstreamgetnextentry}
\func{wxZipEntry*}{GetNextEntry}{\void}
Closes the current entry if one is open, then reads the meta-data for
the next entry and returns it in a \helpref{wxZipEntry}{wxzipentry}
object, giving away ownership. The stream is then open and can be read.
\membersection{wxZipInputStream::GetTotalEntries}\label{wxzipinputstreamgettotalentries}
\func{int}{GetTotalEntries}{\void}
For a zip on a seekable stream returns the total number of entries in
the zip. For zips on non-seekable streams returns the number of entries
returned so far by \helpref{GetNextEntry()}{wxzipinputstreamgetnextentry}.
\membersection{wxZipInputStream::OpenEntry}\label{wxzipinputstreamopenentry}
\func{bool}{OpenEntry}{\param{wxZipEntry\& }{entry}}
Closes the current entry if one is open, then opens the entry specified
by the {\it entry} object.
{\it entry} should be from the same zip file, and the zip should
be on a seekable stream.
\wxheading{See also}
\helpref{Looking up an archive entry by name}{wxarcbyname}
%
% automatically generated by HelpGen $Revision$ from
% wx/zipstrm.h at 16/Sep/04 12:19:29
%
\section{\class{wxZipNotifier}}\label{wxzipnotifier}
If you need to know when a \helpref{wxZipInputStream}{wxzipinputstream}
updates a \helpref{wxZipEntry}{wxzipentry},
you can create a notifier by deriving from this abstract base class,
overriding \helpref{OnEntryUpdated()}{wxzipnotifieronentryupdated}.
An instance of your notifier class can then be assigned to wxZipEntry
objects, using \helpref{wxZipEntry::SetNotifier()}{wxzipentrynotifier}.
Setting a notifier is not usually necessary. It is used to handle
certain cases when modifying an zip in a pipeline (i.e. between
non-seekable streams).
See '\helpref{Archives on non-seekable streams}{wxarcnoseek}'.
\wxheading{Derived from}
No base class
\wxheading{Include files}
<wx/zipstrm.h>
\wxheading{See also}
\helpref{Archives on non-seekable streams}{wxarcnoseek}\\
\helpref{wxZipEntry}{wxzipentry}\\
\helpref{wxZipInputStream}{wxzipinputstream}\\
\helpref{wxZipOutputStream}{wxzipoutputstream}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxZipNotifier::OnEntryUpdated}\label{wxzipnotifieronentryupdated}
\func{void}{OnEntryUpdated}{\param{wxZipEntry\& }{entry}}
Override this to receive notifications when
an \helpref{wxZipEntry}{wxzipentry} object changes.
%
% automatically generated by HelpGen $Revision$ from
% wx/zipstrm.h at 16/Sep/04 12:19:29
%
\section{\class{wxZipOutputStream}}\label{wxzipoutputstream}
Output stream for writing zip files.
\helpref{PutNextEntry()}{wxzipoutputstreamputnextentry} is used to create
a new entry in the output zip, then the entry's data is written to the
wxZipOutputStream. Another call to PutNextEntry() closes the current
entry and begins the next.
\wxheading{Derived from}
\helpref{wxArchiveOutputStream}{wxarchiveoutputstream}
\wxheading{Include files}
<wx/zipstrm.h>
\wxheading{See also}
\helpref{Archive formats such as zip}{wxarc}\\
\helpref{wxZipEntry}{wxzipentry}\\
\helpref{wxZipInputStream}{wxzipinputstream}
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxZipOutputStream::wxZipOutputStream}\label{wxzipoutputstreamwxzipoutputstream}
\func{}{wxZipOutputStream}{\param{wxOutputStream\& }{stream}, \param{int }{level = -1}, \param{wxMBConv\& }{conv = wxConvLocal}}
Constructor. {\tt level} is the compression level to use.
It can be a value between 0 and 9 or -1 to use the default value
which currently is equivalent to 6.
In a Unicode build the third parameter {\tt conv} is used to translate
the filename and comment fields to Unicode. It has no effect on the
stream's data.
\membersection{wxZipOutputStream::\destruct{wxZipOutputStream}}\label{wxzipoutputstreamdtor}
\func{}{\destruct{wxZipOutputStream}}{\void}
The destructor calls \helpref{Close()}{wxzipoutputstreamclose} to finish
writing the zip if it has not been called already.
\membersection{wxZipOutputStream::Close}\label{wxzipoutputstreamclose}
\func{bool}{Close}{\void}
Finishes writing the zip, returning true if successfully.
Called by the destructor if not called explicitly.
\membersection{wxZipOutputStream::CloseEntry}\label{wxzipoutputstreamcloseentry}
\func{bool}{CloseEntry}{\void}
Close the current entry. It is called implicitly whenever another new
entry is created with \helpref{CopyEntry()}{wxzipoutputstreamcopyentry}
or \helpref{PutNextEntry()}{wxzipoutputstreamputnextentry}, or
when the zip is closed.
\membersection{wxZipOutputStream::CopyArchiveMetaData}\label{wxzipoutputstreamcopyarchivemetadata}
\func{bool}{CopyArchiveMetaData}{\param{wxZipInputStream\& }{inputStream}}
Transfers the zip comment from the \helpref{wxZipInputStream}{wxzipinputstream}
to this output stream.
\membersection{wxZipOutputStream::CopyEntry}\label{wxzipoutputstreamcopyentry}
\func{bool}{CopyEntry}{\param{wxZipEntry* }{entry}, \param{wxZipInputStream\& }{inputStream}}
Takes ownership of {\tt entry} and uses it to create a new entry
in the zip. {\tt entry} is then opened in {\tt inputStream} and its contents
copied to this stream.
CopyEntry() is much more efficient than transferring the data using
Read() and Write() since it will copy them without decompressing and
recompressing them.
For zips on seekable streams, {\tt entry} must be from the same zip file
as {\tt stream}. For non-seekable streams, {\tt entry} must also be the
last thing read from {\tt inputStream}.
\membersection{wxZipOutputStream::Get/SetLevel}\label{wxzipoutputstreamlevel}
\constfunc{int}{GetLevel}{\void}
\func{void}{SetLevel}{\param{int }{level}}
Set the compression level that will be used the next time an entry is
created. It can be a value between 0 and 9 or -1 to use the default value
which currently is equivalent to 6.
\membersection{wxZipOutputStream::PutNextDirEntry}\label{wxzipoutputstreamputnextdirentry}
\func{bool}{PutNextDirEntry}{\param{const wxString\& }{name}, \param{const wxDateTime\& }{dt = wxDateTime::Now()}}
Create a new directory entry
(see \helpref{wxArchiveEntry::IsDir()}{wxarchiveentryisdir})
with the given name and timestamp.
\helpref{PutNextEntry()}{wxzipoutputstreamputnextentry} can
also be used to create directory entries, by supplying a name with
a trailing path separator.
\membersection{wxZipOutputStream::PutNextEntry}\label{wxzipoutputstreamputnextentry}
\func{bool}{PutNextEntry}{\param{wxZipEntry* }{entry}}
Takes ownership of {\tt entry} and uses it to create a new entry
in the zip.
\func{bool}{PutNextEntry}{\param{const wxString\& }{name}, \param{const wxDateTime\& }{dt = wxDateTime::Now()}, \param{off\_t }{size = wxInvalidOffset}}
Create a new entry with the given name, timestamp and size.
\membersection{wxZipOutputStream::SetComment}\label{wxzipoutputstreamsetcomment}
\func{void}{SetComment}{\param{const wxString\& }{comment}}
Sets a comment for the zip as a whole. It is written at the end of the
zip.

353
include/wx/archive.h Normal file
View File

@@ -0,0 +1,353 @@
/////////////////////////////////////////////////////////////////////////////
// Name: archive.h
// Purpose: Streams for archive formats
// Author: Mike Wetherell
// RCS-ID: $Id$
// Copyright: (c) 2004 Mike Wetherell
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _WX_ARCHIVE_H__
#define _WX_ARCHIVE_H__
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma interface "archive.h"
#endif
#include "wx/defs.h"
#if wxUSE_ZLIB && wxUSE_STREAMS && wxUSE_ZIPSTREAM
#include "wx/stream.h"
#include "wx/filename.h"
/////////////////////////////////////////////////////////////////////////////
// wxArchiveNotifier
class WXDLLIMPEXP_BASE wxArchiveNotifier
{
public:
virtual ~wxArchiveNotifier() { }
virtual void OnEntryUpdated(class wxArchiveEntry& entry) = 0;
};
/////////////////////////////////////////////////////////////////////////////
// wxArchiveEntry
//
// Holds an entry's meta data, such as filename and timestamp.
class WXDLLIMPEXP_BASE wxArchiveEntry : public wxObject
{
public:
virtual ~wxArchiveEntry() { }
virtual wxDateTime GetDateTime() const = 0;
virtual wxFileOffset GetSize() const = 0;
virtual wxFileOffset GetOffset() const = 0;
virtual bool IsDir() const = 0;
virtual bool IsReadOnly() const = 0;
virtual wxString GetInternalName() const = 0;
virtual wxPathFormat GetInternalFormat() const = 0;
virtual wxString GetName(wxPathFormat format = wxPATH_NATIVE) const = 0;
virtual void SetDateTime(const wxDateTime& dt) = 0;
virtual void SetSize(wxFileOffset size) = 0;
virtual void SetIsDir(bool isDir = true) = 0;
virtual void SetIsReadOnly(bool isReadOnly = true) = 0;
virtual void SetName(const wxString& name,
wxPathFormat format = wxPATH_NATIVE) = 0;
wxArchiveEntry *Clone() const { return DoClone(); }
void SetNotifier(wxArchiveNotifier& notifier);
virtual void UnsetNotifier() { m_notifier = NULL; }
protected:
wxArchiveEntry() : m_notifier(NULL) { }
virtual void SetOffset(wxFileOffset offset) = 0;
virtual wxArchiveEntry* DoClone() const = 0;
wxArchiveNotifier *GetNotifier() const { return m_notifier; }
wxArchiveEntry& operator=(const wxArchiveEntry& entry);
private:
wxArchiveNotifier *m_notifier;
DECLARE_ABSTRACT_CLASS(wxArchiveEntry)
};
/////////////////////////////////////////////////////////////////////////////
// wxArchiveInputStream
//
// GetNextEntry() returns an wxArchiveEntry object containing the meta-data
// for the next entry in the archive (and gives away ownership). Reading from
// the wxArchiveInputStream then returns the entry's data. Eof() becomes true
// after an attempt has been made to read past the end of the entry's data.
//
// When there are no more entries, GetNextEntry() returns NULL and sets Eof().
class WXDLLIMPEXP_BASE wxArchiveInputStream : public wxFilterInputStream
{
public:
typedef wxArchiveEntry entry_type;
virtual ~wxArchiveInputStream() { }
virtual bool OpenEntry(wxArchiveEntry& entry) = 0;
virtual bool CloseEntry() = 0;
wxArchiveEntry *GetNextEntry() { return DoGetNextEntry(); }
virtual char Peek() { return wxInputStream::Peek(); }
protected:
wxArchiveInputStream(wxInputStream& stream, wxMBConv& conv);
virtual wxArchiveEntry *DoGetNextEntry() = 0;
wxMBConv& GetConv() const { return m_conv; }
private:
wxMBConv& m_conv;
};
/////////////////////////////////////////////////////////////////////////////
// wxArchiveOutputStream
//
// PutNextEntry is used to create a new entry in the output archive, then
// the entry's data is written to the wxArchiveOutputStream.
//
// Only one entry can be open for output at a time; another call to
// PutNextEntry closes the current entry and begins the next.
//
// The overload 'bool PutNextEntry(wxArchiveEntry *entry)' takes ownership
// of the entry object.
class WXDLLIMPEXP_BASE wxArchiveOutputStream : public wxFilterOutputStream
{
public:
virtual ~wxArchiveOutputStream() { }
virtual bool PutNextEntry(wxArchiveEntry *entry) = 0;
virtual bool PutNextEntry(const wxString& name,
const wxDateTime& dt = wxDateTime::Now(),
wxFileOffset size = wxInvalidOffset) = 0;
virtual bool PutNextDirEntry(const wxString& name,
const wxDateTime& dt = wxDateTime::Now()) = 0;
virtual bool CopyEntry(wxArchiveEntry *entry,
wxArchiveInputStream& stream) = 0;
virtual bool CopyArchiveMetaData(wxArchiveInputStream& stream) = 0;
virtual bool CloseEntry() = 0;
virtual bool Close() = 0;
protected:
wxArchiveOutputStream(wxOutputStream& stream, wxMBConv& conv);
wxMBConv& GetConv() const { return m_conv; }
private:
wxMBConv& m_conv;
};
/////////////////////////////////////////////////////////////////////////////
// wxArchiveClassFactory
//
// A wxArchiveClassFactory instance for a particular archive type allows
// the creation of the other classes that may be needed.
class WXDLLIMPEXP_BASE wxArchiveClassFactory : public wxObject
{
public:
virtual ~wxArchiveClassFactory() { }
wxArchiveEntry *NewEntry() const
{ return DoNewEntry(); }
wxArchiveInputStream *NewStream(wxInputStream& stream) const
{ return DoNewStream(stream); }
wxArchiveOutputStream *NewStream(wxOutputStream& stream) const
{ return DoNewStream(stream); }
virtual wxString GetInternalName(
const wxString& name,
wxPathFormat format = wxPATH_NATIVE) const = 0;
void SetConv(wxMBConv& conv) { m_pConv = &conv; }
wxMBConv& GetConv() const { return *m_pConv; }
protected:
virtual wxArchiveEntry *DoNewEntry() const = 0;
virtual wxArchiveInputStream *DoNewStream(wxInputStream& stream) const = 0;
virtual wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const = 0;
wxArchiveClassFactory() : m_pConv(&wxConvLocal) { }
wxArchiveClassFactory& operator=(const wxArchiveClassFactory& WXUNUSED(f))
{ return *this; }
private:
wxMBConv *m_pConv;
DECLARE_ABSTRACT_CLASS(wxArchiveClassFactory)
};
/////////////////////////////////////////////////////////////////////////////
// wxArchiveIterator
//
// An input iterator that can be used to transfer an archive's catalog to
// a container.
#if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
#include <iterator>
#include <utility>
template <class X, class Y>
void WXDLLIMPEXP_BASE _wxSetArchiveIteratorValue(
X& val, Y entry, void *WXUNUSED(d))
{
val = X(entry);
}
template <class X, class Y, class Z>
void WXDLLIMPEXP_BASE _wxSetArchiveIteratorValue(
std::pair<X, Y>& val, Z entry, Z WXUNUSED(d))
{
val = std::make_pair(X(entry->GetInternalName()), Y(entry));
}
#if defined _MSC_VER && _MSC_VER < 1300
template <class Arc, class T = Arc::entry_type*>
#else
template <class Arc, class T = typename Arc::entry_type*>
#endif
class WXDLLIMPEXP_BASE wxArchiveIterator
{
public:
typedef std::input_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
wxArchiveIterator() : m_rep(NULL) { }
wxArchiveIterator(Arc& arc) {
typename Arc::entry_type* entry = arc.GetNextEntry();
m_rep = entry ? new Rep(arc, entry) : NULL;
}
wxArchiveIterator(const wxArchiveIterator& it) : m_rep(it.m_rep) {
if (m_rep)
m_rep->AddRef();
}
~wxArchiveIterator() {
if (m_rep)
m_rep->UnRef();
}
const T& operator *() const {
return m_rep->GetValue();
}
const T* operator ->() const {
return &**this;
}
wxArchiveIterator& operator =(const wxArchiveIterator& it) {
if (it.m_rep)
it.m_rep.AddRef();
if (m_rep)
m_rep.UnRef();
m_rep = it.m_rep;
return *this;
}
wxArchiveIterator& operator ++() {
m_rep = m_rep->Next();
return *this;
}
wxArchiveIterator operator ++(int) {
wxArchiveIterator it(*this);
++(*this);
return it;
}
friend bool operator ==(const wxArchiveIterator& i,
const wxArchiveIterator& j) {
return i.m_rep == j.m_rep;
}
friend bool operator !=(const wxArchiveIterator& i,
const wxArchiveIterator& j) {
return !(i == j);
}
private:
class Rep {
Arc& m_arc;
typename Arc::entry_type* m_entry;
T m_value;
int m_ref;
public:
Rep(Arc& arc, typename Arc::entry_type* entry)
: m_arc(arc), m_entry(entry), m_value(), m_ref(1) { }
~Rep()
{ delete m_entry; }
void AddRef() {
m_ref++;
}
void UnRef() {
if (--m_ref == 0)
delete this;
}
Rep *Next() {
typename Arc::entry_type* entry = m_arc.GetNextEntry();
if (!entry) {
UnRef();
return NULL;
}
if (m_ref > 1) {
m_ref--;
return new Rep(m_arc, entry);
}
delete m_entry;
m_entry = entry;
m_value = T();
return this;
}
const T& GetValue() {
if (m_entry) {
_wxSetArchiveIteratorValue(m_value, m_entry, m_entry);
m_entry = NULL;
}
return m_value;
}
} *m_rep;
};
typedef wxArchiveIterator<wxArchiveInputStream> wxArchiveIter;
typedef wxArchiveIterator<wxArchiveInputStream,
std::pair<wxString, wxArchiveEntry*> > wxArchivePairIter;
#endif // wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
#endif // wxUSE_STREAMS
#endif // _WX_ARCHIVE_H__

View File

@@ -37,12 +37,13 @@ class WXDLLIMPEXP_BASE wxZipFSHandler : public wxFileSystemHandler
private:
// these vars are used by FindFirst/Next:
void *m_Archive;
class wxZipInputStream *m_Archive;
wxString m_Pattern, m_BaseDir, m_ZipFile;
bool m_AllowDirs, m_AllowFiles;
wxLongToLongHashMap *m_DirsFound;
wxString DoFind();
void CloseArchive(class wxZipInputStream *archive);
DECLARE_NO_COPY_CLASS(wxZipFSHandler)
};

View File

@@ -1,13 +1,14 @@
/////////////////////////////////////////////////////////////////////////////
// Name: zipstream.h
// Purpose: wxZipInputStream for reading files from ZIP archive
// Author: Vaclav Slavik
// Copyright: (c) 1999 Vaclav Slavik
// Name: zipstrm.h
// Purpose: Streams for Zip files
// Author: Mike Wetherell
// RCS-ID: $Id$
// Copyright: (c) Mike Wetherell
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef __ZIPSTREAM_H__
#define __ZIPSTREAM_H__
#ifndef _WX_WXZIPSTREAM_H__
#define _WX_WXZIPSTREAM_H__
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma interface "zipstrm.h"
@@ -15,47 +16,507 @@
#include "wx/defs.h"
#if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB
#if wxUSE_ZLIB && wxUSE_STREAMS && wxUSE_ZIPSTREAM
#include "wx/stream.h"
//--------------------------------------------------------------------------------
// wxZipInputStream
// This class is input stream from ZIP archive. The archive
// must be local file (accessible via FILE*)
//--------------------------------------------------------------------------------
#include "wx/archive.h"
#include "wx/hashmap.h"
#include "wx/filename.h"
class WXDLLIMPEXP_BASE wxZipInputStream : public wxInputStream
/////////////////////////////////////////////////////////////////////////////
// constants
// Compression Method, only 0 (store) and 8 (deflate) are supported here
//
enum wxZipMethod
{
wxZIP_METHOD_STORE,
wxZIP_METHOD_SHRINK,
wxZIP_METHOD_REDUCE1,
wxZIP_METHOD_REDUCE2,
wxZIP_METHOD_REDUCE3,
wxZIP_METHOD_REDUCE4,
wxZIP_METHOD_IMPLODE,
wxZIP_METHOD_TOKENIZE,
wxZIP_METHOD_DEFLATE,
wxZIP_METHOD_DEFLATE64,
wxZIP_METHOD_BZIP2 = 12,
wxZIP_METHOD_DEFAULT = 0xffff
};
// Originating File-System.
//
// These are Pkware's values. Note that Info-zip disagree on some of them,
// most notably NTFS.
//
enum wxZipSystem
{
wxZIP_SYSTEM_MSDOS,
wxZIP_SYSTEM_AMIGA,
wxZIP_SYSTEM_OPENVMS,
wxZIP_SYSTEM_UNIX,
wxZIP_SYSTEM_VM_CMS,
wxZIP_SYSTEM_ATARI_ST,
wxZIP_SYSTEM_OS2_HPFS,
wxZIP_SYSTEM_MACINTOSH,
wxZIP_SYSTEM_Z_SYSTEM,
wxZIP_SYSTEM_CPM,
wxZIP_SYSTEM_WINDOWS_NTFS,
wxZIP_SYSTEM_MVS,
wxZIP_SYSTEM_VSE,
wxZIP_SYSTEM_ACORN_RISC,
wxZIP_SYSTEM_VFAT,
wxZIP_SYSTEM_ALTERNATE_MVS,
wxZIP_SYSTEM_BEOS,
wxZIP_SYSTEM_TANDEM,
wxZIP_SYSTEM_OS_400
};
// Dos/Win file attributes
//
enum wxZipAttributes
{
wxZIP_A_RDONLY = 0x01,
wxZIP_A_HIDDEN = 0x02,
wxZIP_A_SYSTEM = 0x04,
wxZIP_A_SUBDIR = 0x10,
wxZIP_A_ARCH = 0x20,
wxZIP_A_MASK = 0x37
};
// Values for the flags field in the zip headers
//
enum wxZipFlags
{
wxZIP_ENCRYPTED = 0x0001,
wxZIP_DEFLATE_NORMAL = 0x0000, // normal compression
wxZIP_DEFLATE_EXTRA = 0x0002, // extra compression
wxZIP_DEFLATE_FAST = 0x0004, // fast compression
wxZIP_DEFLATE_SUPERFAST = 0x0006, // superfast compression
wxZIP_DEFLATE_MASK = 0x0006,
wxZIP_SUMS_FOLLOW = 0x0008, // crc and sizes come after the data
wxZIP_ENHANCED = 0x0010,
wxZIP_PATCH = 0x0020,
wxZIP_STRONG_ENC = 0x0040,
wxZIP_UNUSED = 0x0F80,
wxZIP_RESERVED = 0xF000
};
// Forward decls
//
class WXDLLIMPEXP_BASE wxZipEntry;
class WXDLLIMPEXP_BASE wxZipInputStream;
/////////////////////////////////////////////////////////////////////////////
// wxZipNotifier
class WXDLLIMPEXP_BASE wxZipNotifier
{
public:
wxZipInputStream(const wxString& archive, const wxString& file);
// archive is name of .zip archive, file is name of file to be extracted.
// Remember that archive must be local file accesible via fopen, fread functions!
~wxZipInputStream();
virtual ~wxZipNotifier() { }
virtual wxFileOffset GetLength() const {return m_Size;}
virtual bool Eof() const;
virtual void OnEntryUpdated(wxZipEntry& entry) = 0;
};
/////////////////////////////////////////////////////////////////////////////
// Zip Entry - holds the meta data for a file in the zip
class WXDLLIMPEXP_BASE wxZipEntry : public wxArchiveEntry
{
public:
wxZipEntry(const wxString& name = wxEmptyString,
const wxDateTime& dt = wxDateTime::Now(),
wxFileOffset size = wxInvalidOffset);
virtual ~wxZipEntry();
wxZipEntry(const wxZipEntry& entry);
wxZipEntry& operator=(const wxZipEntry& entry);
// Get accessors
wxDateTime GetDateTime() const { return m_DateTime; }
wxFileOffset GetSize() const { return m_Size; }
wxFileOffset GetOffset() const { return m_Offset; }
wxString GetInternalName() const { return m_Name; }
int GetMethod() const { return m_Method; }
int GetFlags() const { return m_Flags; }
wxUint32 GetCrc() const { return m_Crc; }
wxFileOffset GetCompressedSize() const { return m_CompressedSize; }
int GetSystemMadeBy() const { return m_SystemMadeBy; }
wxString GetComment() const { return m_Comment; }
wxUint32 GetExternalAttributes() const { return m_ExternalAttributes; }
wxPathFormat GetInternalFormat() const { return wxPATH_UNIX; }
int GetMode() const;
const char *GetLocalExtra() const;
size_t GetLocalExtraLen() const;
const char *GetExtra() const;
size_t GetExtraLen() const;
wxString GetName(wxPathFormat format = wxPATH_NATIVE) const;
// is accessors
inline bool IsDir() const;
inline bool IsText() const;
inline bool IsReadOnly() const;
inline bool IsMadeByUnix() const;
// set accessors
void SetDateTime(const wxDateTime& dt) { m_DateTime = dt; }
void SetSize(wxFileOffset size) { m_Size = size; }
void SetMethod(int method) { m_Method = method; }
void SetComment(const wxString& comment) { m_Comment = comment; }
void SetExternalAttributes(wxUint32 attr ) { m_ExternalAttributes = attr; }
void SetSystemMadeBy(int system);
void SetMode(int mode);
void SetExtra(const char *extra, size_t len);
void SetLocalExtra(const char *extra, size_t len);
inline void SetName(const wxString& name,
wxPathFormat format = wxPATH_NATIVE);
static wxString GetInternalName(const wxString& name,
wxPathFormat format = wxPATH_NATIVE,
bool *pIsDir = NULL);
// set is accessors
void SetIsDir(bool isDir = true);
inline void SetIsReadOnly(bool isReadOnly = true);
inline void SetIsText(bool isText = true);
wxZipEntry *Clone() const { return ZipClone(); }
void SetNotifier(wxZipNotifier& notifier);
void UnsetNotifier();
protected:
virtual size_t OnSysRead(void *buffer, size_t bufsize);
virtual wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode);
virtual wxFileOffset OnSysTell() const {return m_Pos;}
// Internal attributes
enum { TEXT_ATTR = 1 };
// protected Get accessors
int GetVersionNeeded() const { return m_VersionNeeded; }
wxFileOffset GetKey() const { return m_Key; }
int GetVersionMadeBy() const { return m_VersionMadeBy; }
int GetDiskStart() const { return m_DiskStart; }
int GetInternalAttributes() const { return m_InternalAttributes; }
void SetVersionNeeded(int version) { m_VersionNeeded = version; }
void SetOffset(wxFileOffset offset) { m_Offset = offset; }
void SetFlags(int flags) { m_Flags = flags; }
void SetVersionMadeBy(int version) { m_VersionMadeBy = version; }
void SetCrc(wxUint32 crc) { m_Crc = crc; }
void SetCompressedSize(wxFileOffset size) { m_CompressedSize = size; }
void SetKey(wxFileOffset offset) { m_Key = offset; }
void SetDiskStart(int start) { m_DiskStart = start; }
void SetInternalAttributes(int attr) { m_InternalAttributes = attr; }
virtual wxZipEntry *ZipClone() const { return new wxZipEntry(*this); }
void Notify();
private:
wxFileOffset m_Size;
wxFileOffset m_Pos;
wxArchiveEntry* DoClone() const { return ZipClone(); }
// this void* is handle of archive . I'm sorry it is void and not proper
// type but I don't want to make unzip.h header public.
void *m_Archive;
size_t ReadLocal(wxInputStream& stream, wxMBConv& conv);
size_t WriteLocal(wxOutputStream& stream, wxMBConv& conv) const;
size_t ReadCentral(wxInputStream& stream, wxMBConv& conv);
size_t WriteCentral(wxOutputStream& stream, wxMBConv& conv) const;
size_t ReadDescriptor(wxInputStream& stream);
size_t WriteDescriptor(wxOutputStream& stream, wxUint32 crc,
wxFileOffset compressedSize, wxFileOffset size);
wxUint8 m_SystemMadeBy; // one of enum wxZipSystem
wxUint8 m_VersionMadeBy; // major * 10 + minor
wxUint16 m_VersionNeeded; // ver needed to extract (20 i.e. v2.0)
wxUint16 m_Flags;
wxUint16 m_Method; // compression method (one of wxZipMethod)
wxDateTime m_DateTime;
wxUint32 m_Crc;
wxFileOffset m_CompressedSize;
wxFileOffset m_Size;
wxString m_Name; // in internal format
wxFileOffset m_Key; // the original offset for copied entries
wxFileOffset m_Offset; // file offset of the entry
wxString m_Comment;
wxUint16 m_DiskStart; // for multidisk archives, not unsupported
wxUint16 m_InternalAttributes; // bit 0 set for text files
wxUint32 m_ExternalAttributes; // system specific depends on SystemMadeBy
class wxZipMemory *m_Extra;
class wxZipMemory *m_LocalExtra;
wxZipNotifier *m_zipnotifier;
class wxZipWeakLinks *m_backlink;
friend class wxZipInputStream;
friend class wxZipOutputStream;
DECLARE_DYNAMIC_CLASS(wxZipEntry)
};
/////////////////////////////////////////////////////////////////////////////
// wxZipOutputStream
WX_DECLARE_LIST_WITH_DECL(wxZipEntry, _wxZipEntryList, class WXDLLIMPEXP_BASE);
class WXDLLIMPEXP_BASE wxZipOutputStream : public wxArchiveOutputStream
{
public:
wxZipOutputStream(wxOutputStream& stream,
int level = -1,
wxMBConv& conv = wxConvLocal);
virtual ~wxZipOutputStream();
bool PutNextEntry(wxZipEntry *entry) { return DoCreate(entry); }
bool PutNextEntry(const wxString& name,
const wxDateTime& dt = wxDateTime::Now(),
wxFileOffset size = wxInvalidOffset);
bool PutNextDirEntry(const wxString& name,
const wxDateTime& dt = wxDateTime::Now());
bool CopyEntry(wxZipEntry *entry, wxZipInputStream& inputStream);
bool CopyArchiveMetaData(wxZipInputStream& inputStream);
void Sync();
bool CloseEntry();
bool Close();
void SetComment(const wxString& comment) { m_Comment = comment; }
int GetLevel() const { return m_level; }
void SetLevel(int level);
protected:
virtual size_t OnSysWrite(const void *buffer, size_t size);
virtual wxFileOffset OnSysTell() const { return m_entrySize; }
struct Buffer { const char *m_data; size_t m_size; };
virtual wxOutputStream *OpenCompressor(wxOutputStream& stream,
wxZipEntry& entry,
const Buffer bufs[]);
virtual bool CloseCompressor(wxOutputStream *comp);
bool IsParentSeekable() const { return m_offsetAdjustment
!= wxInvalidOffset; }
private:
bool PutNextEntry(wxArchiveEntry *entry);
bool CopyEntry(wxArchiveEntry *entry, wxArchiveInputStream& stream);
bool CopyArchiveMetaData(wxArchiveInputStream& stream);
bool IsOpened() const { return m_comp || m_pending; }
bool DoCreate(wxZipEntry *entry, bool raw = false);
void CreatePendingEntry(const void *buffer, size_t size);
void CreatePendingEntry();
class wxStoredOutputStream *m_store;
class wxZlibOutputStream2 *m_deflate;
class wxZipStreamLink *m_backlink;
_wxZipEntryList m_entries;
char *m_initialData;
size_t m_initialSize;
wxZipEntry *m_pending;
bool m_raw;
wxFileOffset m_headerOffset;
size_t m_headerSize;
wxFileOffset m_entrySize;
wxUint32 m_crcAccumulator;
wxOutputStream *m_comp;
int m_level;
wxFileOffset m_offsetAdjustment;
wxString m_Comment;
DECLARE_NO_COPY_CLASS(wxZipOutputStream)
};
/////////////////////////////////////////////////////////////////////////////
// wxZipInputStream
class WXDLLIMPEXP_BASE wxZipInputStream : public wxArchiveInputStream
{
public:
typedef wxZipEntry entry_type;
wxZipInputStream(wxInputStream& stream, wxMBConv& conv = wxConvLocal);
wxZipInputStream(const wxString& archive, const wxString& file);
virtual ~wxZipInputStream();
bool OpenEntry(wxZipEntry& entry) { return DoOpen(&entry); }
bool CloseEntry();
wxZipEntry *GetNextEntry();
wxString GetComment();
int GetTotalEntries();
virtual wxFileOffset GetLength() const { return m_entry.GetSize(); }
protected:
size_t OnSysRead(void *buffer, size_t size);
wxFileOffset OnSysTell() const { return m_decomp ? m_decomp->TellI() : 0; }
wxFileOffset OnSysSeek(wxFileOffset seek, wxSeekMode mode);
virtual wxInputStream *OpenDecompressor(wxInputStream& stream);
virtual bool CloseDecompressor(wxInputStream *decomp);
private:
void Init();
wxInputStream& OpenFile(const wxString& archive);
wxArchiveEntry *DoGetNextEntry() { return GetNextEntry(); }
bool OpenEntry(wxArchiveEntry& entry);
wxStreamError ReadLocal(bool readEndRec = false);
wxStreamError ReadCentral();
wxUint32 ReadSignature();
bool FindEndRecord();
bool LoadEndRecord();
bool AtHeader() const { return m_headerSize == 0; }
bool AfterHeader() const { return m_headerSize > 0 && !m_decomp; }
bool IsOpened() const { return m_decomp != NULL; }
wxZipStreamLink *MakeLink(wxZipOutputStream *out);
bool DoOpen(wxZipEntry *entry = NULL, bool raw = false);
bool OpenDecompressor(bool raw = false);
class wxStoredInputStream *m_store;
class wxZlibInputStream2 *m_inflate;
class wxRawInputStream *m_rawin;
class wxFFileInputStream *m_ffile;
wxZipEntry m_entry;
bool m_raw;
size_t m_headerSize;
wxUint32 m_crcAccumulator;
wxInputStream *m_decomp;
bool m_parentSeekable;
class wxZipWeakLinks *m_weaklinks;
class wxZipStreamLink *m_streamlink;
wxFileOffset m_offsetAdjustment;
wxFileOffset m_position;
wxUint32 m_signature;
size_t m_TotalEntries;
wxString m_Comment;
friend bool wxZipOutputStream::CopyEntry(
wxZipEntry *entry, wxZipInputStream& inputStream);
friend bool wxZipOutputStream::CopyArchiveMetaData(
wxZipInputStream& inputStream);
DECLARE_NO_COPY_CLASS(wxZipInputStream)
};
#endif
// wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB
/////////////////////////////////////////////////////////////////////////////
// wxZipClassFactory
class WXDLLIMPEXP_BASE wxZipClassFactory : public wxArchiveClassFactory
{
public:
wxZipEntry *NewEntry() const
{ return new wxZipEntry; }
wxZipInputStream *NewStream(wxInputStream& stream) const
{ return new wxZipInputStream(stream, GetConv()); }
wxZipOutputStream *NewStream(wxOutputStream& stream) const
{ return new wxZipOutputStream(stream, -1, GetConv()); }
wxString GetInternalName(const wxString& name,
wxPathFormat format = wxPATH_NATIVE) const
{ return wxZipEntry::GetInternalName(name, format); }
protected:
wxArchiveEntry *DoNewEntry() const
{ return NewEntry(); }
wxArchiveInputStream *DoNewStream(wxInputStream& stream) const
{ return NewStream(stream); }
wxArchiveOutputStream *DoNewStream(wxOutputStream& stream) const
{ return NewStream(stream); }
private:
DECLARE_DYNAMIC_CLASS(wxZipClassFactory)
};
/////////////////////////////////////////////////////////////////////////////
// Iterators
#if wxUSE_STL || defined WX_TEST_ARCHIVE_ITERATOR
typedef wxArchiveIterator<wxZipInputStream> wxZipIter;
typedef wxArchiveIterator<wxZipInputStream,
std::pair<wxString, wxZipEntry*> > wxZipPairIter;
#endif
// __ZIPSTREAM_H__
/////////////////////////////////////////////////////////////////////////////
// wxZipEntry inlines
bool wxZipEntry::IsText() const
{
return (m_InternalAttributes & TEXT_ATTR) != 0;
}
bool wxZipEntry::IsDir() const
{
return (m_ExternalAttributes & wxZIP_A_SUBDIR) != 0;
}
bool wxZipEntry::IsReadOnly() const
{
return (m_ExternalAttributes & wxZIP_A_RDONLY) != 0;
}
bool wxZipEntry::IsMadeByUnix() const
{
const int pattern =
(1 << wxZIP_SYSTEM_OPENVMS) |
(1 << wxZIP_SYSTEM_UNIX) |
(1 << wxZIP_SYSTEM_ATARI_ST) |
(1 << wxZIP_SYSTEM_ACORN_RISC) |
(1 << wxZIP_SYSTEM_BEOS) | (1 << wxZIP_SYSTEM_TANDEM);
// note: some unix zippers put madeby = dos
return (m_SystemMadeBy == wxZIP_SYSTEM_MSDOS
&& (m_ExternalAttributes & ~0xFFFF))
|| ((pattern >> m_SystemMadeBy) & 1);
}
void wxZipEntry::SetIsText(bool isText)
{
if (isText)
m_InternalAttributes |= TEXT_ATTR;
else
m_InternalAttributes &= ~TEXT_ATTR;
}
void wxZipEntry::SetIsReadOnly(bool isReadOnly)
{
if (isReadOnly)
SetMode(GetMode() & ~0222);
else
SetMode(GetMode() | 0200);
}
void wxZipEntry::SetName(const wxString& name,
wxPathFormat format /*=wxPATH_NATIVE*/)
{
bool isDir;
m_Name = GetInternalName(name, format, &isDir);
SetIsDir(isDir);
}
#endif // wxUSE_ZLIB && wxUSE_STREAMS && wxUSE_ZIPSTREAM
#endif // _WX_WXZIPSTREAM_H__

74
src/common/archive.cpp Normal file
View File

@@ -0,0 +1,74 @@
/////////////////////////////////////////////////////////////////////////////
// Name: archive.cpp
// Purpose: Streams for archive formats
// Author: Mike Wetherell
// RCS-ID: $Id$
// Copyright: (c) Mike Wetherell
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "archive.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/defs.h"
#endif
#if wxUSE_ZLIB && wxUSE_STREAMS && wxUSE_ZIPSTREAM
#include "wx/archive.h"
#include "wx/html/forcelnk.h"
IMPLEMENT_ABSTRACT_CLASS(wxArchiveEntry, wxObject)
IMPLEMENT_ABSTRACT_CLASS(wxArchiveClassFactory, wxObject)
FORCE_LINK(zipstrm)
/////////////////////////////////////////////////////////////////////////////
// wxArchiveInputStream
wxArchiveInputStream::wxArchiveInputStream(wxInputStream& stream,
wxMBConv& conv)
: wxFilterInputStream(stream),
m_conv(conv)
{
}
/////////////////////////////////////////////////////////////////////////////
// wxArchiveOutputStream
wxArchiveOutputStream::wxArchiveOutputStream(wxOutputStream& stream,
wxMBConv& conv)
: wxFilterOutputStream(stream),
m_conv(conv)
{
}
/////////////////////////////////////////////////////////////////////////////
// wxArchiveEntry
void wxArchiveEntry::SetNotifier(wxArchiveNotifier& notifier)
{
UnsetNotifier();
m_notifier = &notifier;
m_notifier->OnEntryUpdated(*this);
}
wxArchiveEntry& wxArchiveEntry::operator=(const wxArchiveEntry& entry)
{
m_notifier = entry.m_notifier;
return *this;
}
#endif

View File

@@ -27,15 +27,10 @@
#endif
#include "wx/filesys.h"
#include "wx/wfstream.h"
#include "wx/zipstrm.h"
#include "wx/fs_zip.h"
/* Not the right solution (paths in makefiles) but... */
#ifdef __BORLANDC__
#include "../common/unzip.h"
#else
#include "unzip.h"
#endif
//----------------------------------------------------------------------------
// wxZipFSHandler
@@ -56,13 +51,22 @@ wxZipFSHandler::wxZipFSHandler() : wxFileSystemHandler()
wxZipFSHandler::~wxZipFSHandler()
{
if (m_Archive)
unzClose((unzFile)m_Archive);
CloseArchive(m_Archive);
if (m_DirsFound)
delete m_DirsFound;
}
void wxZipFSHandler::CloseArchive(wxZipInputStream *archive)
{
wxInputStream *stream = archive->GetFilterInputStream();
delete archive;
delete stream;
}
bool wxZipFSHandler::CanOpen(const wxString& location)
{
wxString p = GetProtocol(location);
@@ -125,7 +129,7 @@ wxString wxZipFSHandler::FindFirst(const wxString& spec, int flags)
if (m_Archive)
{
unzClose((unzFile)m_Archive);
CloseArchive(m_Archive);
m_Archive = NULL;
}
@@ -147,18 +151,11 @@ wxString wxZipFSHandler::FindFirst(const wxString& spec, int flags)
m_ZipFile = left;
wxString nativename = wxFileSystem::URLToFileName(m_ZipFile).GetFullPath();
m_Archive = (void*) unzOpen(nativename.mb_str(wxConvFile));
m_Archive = new wxZipInputStream(*new wxFFileInputStream(nativename));
m_Pattern = right.AfterLast(wxT('/'));
m_BaseDir = right.BeforeLast(wxT('/'));
if (m_Archive)
{
if (unzGoToFirstFile((unzFile)m_Archive) != UNZ_OK)
{
unzClose((unzFile)m_Archive);
m_Archive = NULL;
}
else
{
if (m_AllowDirs)
{
@@ -167,7 +164,6 @@ wxString wxZipFSHandler::FindFirst(const wxString& spec, int flags)
}
return DoFind();
}
}
return wxEmptyString;
}
@@ -183,16 +179,20 @@ wxString wxZipFSHandler::FindNext()
wxString wxZipFSHandler::DoFind()
{
static char namebuf[1024]; // char, not wxChar!
char *c;
wxString namestr, dir, filename;
wxString match = wxEmptyString;
while (match == wxEmptyString)
{
unzGetCurrentFileInfo((unzFile)m_Archive, NULL, namebuf, 1024, NULL, 0, NULL, 0);
for (c = namebuf; *c; c++) if (*c == '\\') *c = '/';
namestr = wxString::FromAscii(namebuf); // TODO what encoding does ZIP use?
wxZipEntry *entry = m_Archive->GetNextEntry();
if (!entry)
{
CloseArchive(m_Archive);
m_Archive = NULL;
break;
}
namestr = entry->GetName(wxPATH_UNIX);
delete entry;
if (m_AllowDirs)
{
@@ -221,13 +221,6 @@ wxString wxZipFSHandler::DoFind()
if (m_AllowFiles && !filename.IsEmpty() && m_BaseDir == dir &&
wxMatchWild(m_Pattern, filename, false))
match = m_ZipFile + wxT("#zip:") + namestr;
if (unzGoToNextFile((unzFile)m_Archive) != UNZ_OK)
{
unzClose((unzFile)m_Archive);
m_Archive = NULL;
break;
}
}
return match;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -9,6 +9,7 @@
template_append="wx_append_base">
<sources>
test.cpp
archive/archivetest.cpp
arrays/arrays.cpp
datetime/datetimetest.cpp
fileconf/fileconftest.cpp