lib

KoZipStore.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2000-2002 David Faure <faure@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include "KoZipStore.h"
21
22#include <tqbuffer.h>
23
24#include <kzip.h>
25#include <kdebug.h>
26#include <tdeversion.h>
27#include <kurl.h>
28#include <tdeio/netaccess.h>
29#if ! KDE_IS_VERSION( 3, 4, 1 )
30#include <tqdir.h>
31#include <tqfileinfo.h>
32#endif
33
34KoZipStore::KoZipStore( const TQString & _filename, Mode _mode, const TQCString & appIdentification )
35{
36 kdDebug(s_area) << "KoZipStore Constructor filename = " << _filename
37 << " mode = " << int(_mode)
38 << " mimetype = " << appIdentification << endl;
39
40 m_pZip = new KZip( _filename );
41
42#if ! KDE_IS_VERSION( 3, 4, 1 )
43 // Workaround for KZip KSaveFile double deletion in tdelibs-3.4,
44 // when trying to write to a non-writable directory.
45 TQDir dir( TQFileInfo( _filename ).dir() );
46 if (_mode == Write && !TQFileInfo( dir.path() ).isWritable() )
47 {
48 kdWarning(s_area) << dir.path() << " isn't writable" << endl;
49 m_bGood = false;
50 m_currentDir = 0;
51 KoStore::init( _mode );
52 }
53 else
54#endif
55 {
56 m_bGood = init( _mode, appIdentification ); // open the zip file and init some vars
57 }
58}
59
60KoZipStore::KoZipStore( TQIODevice *dev, Mode mode, const TQCString & appIdentification )
61{
62 m_pZip = new KZip( dev );
63 m_bGood = init( mode, appIdentification );
64}
65
66KoZipStore::KoZipStore( TQWidget* window, const KURL & _url, const TQString & _filename, Mode _mode, const TQCString & appIdentification )
67{
68 kdDebug(s_area) << "KoZipStore Constructor url" << _url.prettyURL()
69 << " filename = " << _filename
70 << " mode = " << int(_mode)
71 << " mimetype = " << appIdentification << endl;
72
73 m_url = _url;
74 m_window = window;
75
76 if ( _mode == KoStore::Read )
77 {
78 m_fileMode = KoStoreBase::RemoteRead;
79 m_localFileName = _filename;
80
81 }
82 else
83 {
84 m_fileMode = KoStoreBase::RemoteWrite;
85 m_localFileName = "/tmp/kozip"; // ### FIXME with KTempFile
86 }
87
88 m_pZip = new KZip( m_localFileName );
89 m_bGood = init( _mode, appIdentification ); // open the zip file and init some vars
90}
91
92KoZipStore::~KoZipStore()
93{
94 kdDebug(s_area) << "KoZipStore::~KoZipStore" << endl;
95 m_pZip->close();
96 delete m_pZip;
97
98 // Now we have still some job to do for remote files.
99 if ( m_fileMode == KoStoreBase::RemoteRead )
100 {
101 TDEIO::NetAccess::removeTempFile( m_localFileName );
102 }
103 else if ( m_fileMode == KoStoreBase::RemoteWrite )
104 {
105 TDEIO::NetAccess::upload( m_localFileName, m_url, m_window );
106 // ### FIXME: delete temp file
107 }
108}
109
110bool KoZipStore::init( Mode _mode, const TQCString& appIdentification )
111{
112 KoStore::init( _mode );
113 m_currentDir = 0;
114 bool good = m_pZip->open( _mode == Write ? IO_WriteOnly : IO_ReadOnly );
115
116 if ( good && _mode == Read )
117 good = m_pZip->directory() != 0;
118 else if ( good && _mode == Write )
119 {
120 //kdDebug(s_area) << "KoZipStore::init writing mimetype " << appIdentification << endl;
121
122 m_pZip->setCompression( KZip::NoCompression );
123 m_pZip->setExtraField( KZip::NoExtraField );
124 // Write identification
125 (void)m_pZip->writeFile( "mimetype", "", "", appIdentification.length(), appIdentification.data() );
126 m_pZip->setCompression( KZip::DeflateCompression );
127 // We don't need the extra field in KOffice - so we leave it as "no extra field".
128 }
129 return good;
130}
131
132bool KoZipStore::openWrite( const TQString& name )
133{
134#if 0
135 // Prepare memory buffer for writing
136 m_byteArray.resize( 0 );
137 m_stream = new TQBuffer( m_byteArray );
138 m_stream->open( IO_WriteOnly );
139 return true;
140#endif
141 m_stream = 0L; // Don't use!
142 return m_pZip->prepareWriting( name, "", "" /*m_pZip->rootDir()->user(), m_pZip->rootDir()->group()*/, 0 );
143}
144
145bool KoZipStore::openRead( const TQString& name )
146{
147 const KArchiveEntry * entry = m_pZip->directory()->entry( name );
148 if ( entry == 0L )
149 {
150 //kdWarning(s_area) << "Unknown filename " << name << endl;
151 //return TDEIO::ERR_DOES_NOT_EXIST;
152 return false;
153 }
154 if ( entry->isDirectory() )
155 {
156 kdWarning(s_area) << name << " is a directory !" << endl;
157 //return TDEIO::ERR_IS_DIRECTORY;
158 return false;
159 }
160 // Must cast to KZipFileEntry, not only KArchiveFile, because device() isn't virtual!
161 const KZipFileEntry * f = static_cast<const KZipFileEntry *>(entry);
162 delete m_stream;
163 m_stream = f->device();
164 m_iSize = f->size();
165 return true;
166}
167
168TQ_LONG KoZipStore::write( const char* _data, TQ_ULONG _len )
169{
170 if ( _len == 0L ) return 0;
171 //kdDebug(s_area) << "KoZipStore::write " << _len << endl;
172
173 if ( !m_bIsOpen )
174 {
175 kdError(s_area) << "KoStore: You must open before writing" << endl;
176 return 0L;
177 }
178 if ( m_mode != Write )
179 {
180 kdError(s_area) << "KoStore: Can not write to store that is opened for reading" << endl;
181 return 0L;
182 }
183
184 m_iSize += _len;
185 if ( m_pZip->writeData( _data, _len ) ) // writeData returns a bool!
186 return _len;
187 return 0L;
188}
189
190bool KoZipStore::closeWrite()
191{
192 kdDebug(s_area) << "Wrote file " << m_sName << " into ZIP archive. size "
193 << m_iSize << endl;
194 return m_pZip->doneWriting( m_iSize );
195#if 0
196 if ( !m_pZip->writeFile( m_sName , "user", "group", m_iSize, m_byteArray.data() ) )
197 kdWarning( s_area ) << "Failed to write " << m_sName << endl;
198 m_byteArray.resize( 0 ); // save memory
199 return true;
200#endif
201}
202
203bool KoZipStore::enterRelativeDirectory( const TQString& dirName )
204{
205 if ( m_mode == Read ) {
206 if ( !m_currentDir ) {
207 m_currentDir = m_pZip->directory(); // initialize
208 Q_ASSERT( m_currentPath.isEmpty() );
209 }
210 const KArchiveEntry *entry = m_currentDir->entry( dirName );
211 if ( entry && entry->isDirectory() ) {
212 m_currentDir = dynamic_cast<const KArchiveDirectory*>( entry );
213 return m_currentDir != 0;
214 }
215 return false;
216 }
217 else // Write, no checking here
218 return true;
219}
220
221bool KoZipStore::enterAbsoluteDirectory( const TQString& path )
222{
223 if ( path.isEmpty() )
224 {
225 m_currentDir = 0;
226 return true;
227 }
228 m_currentDir = dynamic_cast<const KArchiveDirectory*>( m_pZip->directory()->entry( path ) );
229 Q_ASSERT( m_currentDir );
230 return m_currentDir != 0;
231}
232
233bool KoZipStore::fileExists( const TQString& absPath ) const
234{
235 const KArchiveEntry *entry = m_pZip->directory()->entry( absPath );
236 return entry && entry->isFile();
237}
virtual bool init(Mode mode)
Init store - called by constructor.
Definition KoStore.cpp:171
TQ_LONG write(const TQByteArray &_data)
Write data into the currently opened file.
Definition KoStore.cpp:308
const char * name(StdAction id)