2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 | Copyright (c) 1997-2010 The PHP Group |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
18 #include "hphp/runtime/ext/zlib/zip-file.h"
19 #include "hphp/runtime/base/mem-file.h"
20 #include "hphp/runtime/base/temp-file.h"
21 #include "hphp/runtime/base/runtime-error.h"
25 ///////////////////////////////////////////////////////////////////////////////
27 ZipFile::ZipFile() : m_gzFile(nullptr) {
36 void ZipFile::sweep() {
41 bool ZipFile::open(const String
& filename
, const String
& mode
) {
42 assertx(m_gzFile
== nullptr);
44 if (strchr(mode
.c_str(), '+')) {
45 raise_warning("cannot open a zlib stream for reading and writing "
50 m_innerFile
= File::Open(filename
, mode
);
51 if (isa
<MemFile
>(m_innerFile
)) {
52 // We need an FD for the correct zlib APIs; MemFiles don't have an FD
53 if (strchr(mode
.c_str(), 'w')) {
54 raise_warning("Cannot write to this stream type");
57 auto file
= req::make
<TempFile
>();
58 while (!m_innerFile
->eof()) {
59 file
->write(m_innerFile
->read(file
->getChunkSize()));
63 return (m_gzFile
= gzdopen(dup(file
->fd()), mode
.data()));
67 return (m_gzFile
= gzdopen(dup(m_innerFile
->fd()), mode
.data()));
72 bool ZipFile::close() {
73 invokeFiltersOnClose();
77 bool ZipFile::closeImpl() {
82 s_pcloseRet
= gzclose(m_gzFile
);
83 ret
= (s_pcloseRet
== 0);
99 ///////////////////////////////////////////////////////////////////////////////
101 int64_t ZipFile::readImpl(char *buffer
, int64_t length
) {
103 int64_t nread
= gzread(m_gzFile
, buffer
, length
);
104 if (nread
== 0 || gzeof(m_gzFile
)) {
108 gzerror(m_gzFile
, &errno
);
109 if (errno
== 1) { // Z_STREAM_END = 1
113 return (nread
< 0) ? 0 : nread
;
116 int64_t ZipFile::writeImpl(const char *buffer
, int64_t length
) {
118 return gzwrite(m_gzFile
, buffer
, length
);
121 bool ZipFile::seek(int64_t offset
, int whence
/* = SEEK_SET */) {
124 if (whence
== SEEK_CUR
) {
125 off_t result
= gzseek(m_gzFile
, 0, SEEK_CUR
);
126 if (result
!= (off_t
)-1) {
127 offset
+= result
- (bufferedLen() + getPosition());
129 if (offset
> 0 && offset
< bufferedLen()) {
130 setReadPosition(getReadPosition() + offset
);
131 setPosition(getPosition() + offset
);
134 offset
+= getPosition();
138 // invalidate the current buffer
142 gzclearerr(m_gzFile
);
144 off_t result
= gzseek(m_gzFile
, offset
, whence
);
146 return result
!= (off_t
)-1;
149 int64_t ZipFile::tell() {
151 return getPosition();
154 bool ZipFile::eof() {
156 int64_t avail
= bufferedLen();
157 return avail
> 0 ? false : getEof();
160 bool ZipFile::rewind() {
171 bool ZipFile::flush() {
173 return gzflush(m_gzFile
, Z_SYNC_FLUSH
);
176 ///////////////////////////////////////////////////////////////////////////////