FreeCAD

Форк
0
/
zipoutputstreambuf.cpp 
204 строки · 5.1 Кб
1

2
#include "zipios-config.h"
3

4
#include <algorithm>
5
#include <vector>
6
#include <ctime>
7
#include "meta-iostreams.h"
8

9
#include <zlib.h>
10

11
#include "zipoutputstreambuf.h"
12

13
namespace zipios {
14

15
using std::ios ;
16
using std::cerr ;
17
using std::endl ;
18
using std::min ;
19
using std::vector ;
20

21
ZipOutputStreambuf::ZipOutputStreambuf( streambuf *outbuf, bool del_outbuf ) 
22
  : DeflateOutputStreambuf( outbuf, false, del_outbuf ),
23
    _open_entry( false    ),
24
    _open      ( true     ),
25
    _method    ( DEFLATED ),
26
    _level     ( 6        )
27
{
28
}
29

30

31
void ZipOutputStreambuf::closeEntry() {
32
  if ( ! _open_entry )
33
    return ;
34

35
  closeStream() ;
36

37
  updateEntryHeaderInfo() ;
38
  setEntryClosedState( ) ;
39
}
40

41

42
void ZipOutputStreambuf::close() {
43
  finish() ;
44
}
45

46

47
void ZipOutputStreambuf::finish() {
48
  if( ! _open )
49
    return ;
50
  closeEntry() ;
51
  ostream os( _outbuf ) ;
52
  writeCentralDirectory( _entries, EndOfCentralDirectory( _zip_comment), os ) ;
53
  _open = false ;
54
}
55

56

57
ZipOutputStreambuf::~ZipOutputStreambuf() {
58
  finish() ;
59
}
60

61

62
void ZipOutputStreambuf::putNextEntry( const ZipCDirEntry &entry ) {
63
  if ( _open_entry )
64
    closeEntry() ;
65

66
  if ( ! init( _level ) )
67
    cerr << "ZipOutputStreambuf::putNextEntry(): init() failed!\n" ;
68

69
  _entries.push_back( entry ) ;
70
  ZipCDirEntry &ent = _entries.back() ;
71

72
  ostream os( _outbuf ) ;
73

74
  // Update entry header info
75
  ent.setLocalHeaderOffset( os.tellp() ) ;
76
  ent.setMethod( _method ) ;
77
  
78
  os << static_cast< ZipLocalEntry >( ent ) ;
79

80
  _open_entry = true ;
81
}
82

83

84
void ZipOutputStreambuf::setComment( const string &comment ) {
85
  _zip_comment = comment ;
86
}
87

88

89
void ZipOutputStreambuf::setLevel( int level ) {
90
  _level = level ;
91
}
92

93

94
void ZipOutputStreambuf::setMethod( StorageMethod method ) {
95
  _method = method ;
96
  if( method == STORED )
97
    setLevel( NO_COMPRESSION ) ;
98
  else if ( method == DEFLATED ) {
99
    if( _level == NO_COMPRESSION )
100
      setLevel( DEFAULT_COMPRESSION ) ; 
101
  } else 
102
    throw FCollException( "Specified compression method not supported" ) ;
103
}
104

105
//
106
// Protected and private methods
107
//
108

109
int ZipOutputStreambuf::overflow( int c ) {
110
  return DeflateOutputStreambuf::overflow( c ) ;
111
//    // FIXME: implement
112
  
113
//    cout << "ZipOutputStreambuf::overflow() not implemented yet!\n" ;
114
//    return EOF ;
115
}
116

117

118

119
int ZipOutputStreambuf::sync() {
120
  return DeflateOutputStreambuf::sync() ;
121
//    // FIXME: implement
122
//    cout << "ZipOutputStreambuf::sync() not implemented yet!\n" ;
123
//    return EOF ;
124
}
125

126

127

128
void ZipOutputStreambuf::setEntryClosedState() {
129
  _open_entry = false ;
130
  // FIXME: update put pointers to trigger overflow on write. overflow
131
  // should then return EOF while _open_entry is false.
132
}
133

134

135
void ZipOutputStreambuf::updateEntryHeaderInfo() {
136
  if ( ! _open_entry )
137
    return ;
138

139
  ostream os( _outbuf ) ;
140
  int curr_pos = os.tellp() ;
141
  
142
  // update fields in _entries.back()
143
  ZipCDirEntry &entry = _entries.back() ;
144
  entry.setSize( getCount() ) ;
145
  entry.setCrc( getCrc32() ) ;
146
  entry.setCompressedSize( curr_pos - entry.getLocalHeaderOffset() 
147
			   - entry.getLocalHeaderSize() ) ;
148

149
  // Mark Donszelmann: added current date and time
150
  time_t ltime;
151
  time( &ltime );
152
  struct tm *now;
153
  now = localtime( &ltime );
154
  int dosTime = (now->tm_year - 80) << 25 | (now->tm_mon + 1) << 21 | now->tm_mday << 16 |
155
              now->tm_hour << 11 | now->tm_min << 5 | now->tm_sec >> 1;
156
  entry.setTime(dosTime);
157

158
  // write ZipLocalEntry header to header position
159
  os.seekp( entry.getLocalHeaderOffset() ) ;
160
  os << static_cast< ZipLocalEntry >( entry ) ;
161
  os.seekp( curr_pos ) ;
162
}
163

164

165
void ZipOutputStreambuf::writeCentralDirectory( const vector< ZipCDirEntry > &entries, 
166
						EndOfCentralDirectory eocd, 
167
						ostream &os ) {
168
  int cdir_start = os.tellp() ;
169
  std::vector< ZipCDirEntry >::const_iterator it ;
170
  int cdir_size = 0 ;
171

172
  for ( it = entries.begin() ; it != entries.end() ; ++it ) {
173
    os << *it ;
174
    cdir_size += it->getCDirHeaderSize() ;
175
  }
176
  eocd.setOffset( cdir_start ) ;
177
  eocd.setCDirSize( cdir_size ) ;
178
  eocd.setTotalCount( entries.size() ) ;
179
  os << eocd ;
180
}
181

182
} // namespace
183

184
/** \file
185
    Implementation of ZipOutputStreambuf.
186
*/
187

188
/*
189
  Zipios++ - a small C++ library that provides easy access to .zip files.
190
  Copyright (C) 2000  Thomas Søndergaard
191
  
192
  This library is free software; you can redistribute it and/or
193
  modify it under the terms of the GNU Lesser General Public
194
  License as published by the Free Software Foundation; either
195
  version 2 of the License, or (at your option) any later version.
196
  
197
  This library is distributed in the hope that it will be useful,
198
  but WITHOUT ANY WARRANTY; without even the implied warranty of
199
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
200
  Lesser General Public License for more details.
201
  
202
  You should have received a copy of the GNU Lesser General Public
203
  License along with this library; if not, write to the Free Software
204
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
205
*/
206

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.