VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/zip/pkzip.cpp@ 59827

Last change on this file since 59827 was 57372, checked in by vboxsync, 9 years ago

scm: fixes in previous cleanup run.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.5 KB
Line 
1/* $Id: pkzip.cpp 57372 2015-08-14 22:01:25Z vboxsync $ */
2/** @file
3 * IPRT - PKZIP archive I/O.
4 */
5
6/*
7 * Copyright (C) 2014-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/zip.h>
32#include <iprt/file.h>
33#include <iprt/fs.h>
34#include <iprt/mem.h>
35#include <iprt/string.h>
36#include <iprt/vfs.h>
37#include <iprt/vfslowlevel.h>
38
39
40/*********************************************************************************************************************************
41* Structures and Typedefs *
42*********************************************************************************************************************************/
43/**
44 * Memory stream private data.
45 */
46typedef struct MEMIOSTREAM
47{
48 /** Size of the memory buffer. */
49 size_t cbBuf;
50 /** Pointer to the memory buffer. */
51 uint8_t *pu8Buf;
52 /** Current offset. */
53 size_t off;
54} MEMIOSTREAM;
55typedef MEMIOSTREAM *PMEMIOSTREAM;
56
57
58/**
59 * @interface_method_impl{RTVFSOBJOPS,pfnClose}
60 */
61static DECLCALLBACK(int) memFssIos_Close(void *pvThis)
62{
63 NOREF(pvThis);
64 return VINF_SUCCESS;
65}
66
67/**
68 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
69 */
70static DECLCALLBACK(int) memFssIos_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
71{
72 PMEMIOSTREAM pThis = (PMEMIOSTREAM)pvThis;
73 switch (enmAddAttr)
74 {
75 case RTFSOBJATTRADD_NOTHING:
76 case RTFSOBJATTRADD_UNIX:
77 RT_ZERO(*pObjInfo);
78 pObjInfo->cbObject = pThis->cbBuf;
79 break;
80 default:
81 return VERR_NOT_SUPPORTED;
82 }
83 return VINF_SUCCESS;
84}
85
86/**
87 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
88 */
89static DECLCALLBACK(int) memFssIos_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
90{
91 PMEMIOSTREAM pThis = (PMEMIOSTREAM)pvThis;
92 Assert(pSgBuf->cSegs == 1);
93
94 if (off < 0)
95 off = pThis->off;
96 if (off >= (RTFOFF)pThis->cbBuf)
97 return pcbRead ? VINF_EOF : VERR_EOF;
98
99 size_t cbLeft = pThis->cbBuf - off;
100 size_t cbToRead = pSgBuf->paSegs[0].cbSeg;
101 if (cbToRead > cbLeft)
102 {
103 if (!pcbRead)
104 return VERR_EOF;
105 cbToRead = (size_t)cbLeft;
106 }
107
108 memcpy(pSgBuf->paSegs[0].pvSeg, pThis->pu8Buf + off, cbToRead);
109 pThis->off = off + cbToRead;
110 if (pcbRead)
111 *pcbRead = cbToRead;
112
113 return VINF_SUCCESS;
114}
115
116/**
117 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
118 */
119static DECLCALLBACK(int) memFssIos_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
120{
121 return VERR_NOT_IMPLEMENTED;
122}
123
124/**
125 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush}
126 */
127static DECLCALLBACK(int) memFssIos_Flush(void *pvThis)
128{
129 return VERR_NOT_IMPLEMENTED;
130}
131
132/**
133 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnPollOne}
134 */
135static DECLCALLBACK(int) memFssIos_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr, uint32_t *pfRetEvents)
136{
137 return VERR_NOT_IMPLEMENTED;
138}
139
140/**
141 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell}
142 */
143static DECLCALLBACK(int) memFssIos_Tell(void *pvThis, PRTFOFF poffActual)
144{
145 PMEMIOSTREAM pThis = (PMEMIOSTREAM)pvThis;
146 *poffActual = pThis->off;
147 return VINF_SUCCESS;
148}
149
150/**
151 * Memory I/O object stream operations.
152 */
153static const RTVFSIOSTREAMOPS g_memFssIosOps =
154{
155 { /* Obj */
156 RTVFSOBJOPS_VERSION,
157 RTVFSOBJTYPE_IO_STREAM,
158 "MemFsStream::IoStream",
159 memFssIos_Close,
160 memFssIos_QueryInfo,
161 RTVFSOBJOPS_VERSION
162 },
163 RTVFSIOSTREAMOPS_VERSION,
164 RTVFSIOSTREAMOPS_FEAT_NO_SG,
165 memFssIos_Read,
166 memFssIos_Write,
167 memFssIos_Flush,
168 memFssIos_PollOne,
169 memFssIos_Tell,
170 NULL /*Skip*/,
171 NULL /*ZeroFill*/,
172 RTVFSIOSTREAMOPS_VERSION
173};
174
175RTDECL(int) RTZipPkzipMemDecompress(void **ppvDst, size_t *pcbDst, const void *pvSrc, size_t cbSrc, const char *pszObject)
176{
177 PMEMIOSTREAM pIosData;
178 RTVFSIOSTREAM hVfsIos;
179 int rc = RTVfsNewIoStream(&g_memFssIosOps,
180 sizeof(*pIosData),
181 RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN,
182 NIL_RTVFS,
183 NIL_RTVFSLOCK,
184 &hVfsIos,
185 (void **)&pIosData);
186 if (RT_SUCCESS(rc))
187 {
188 pIosData->pu8Buf = (uint8_t*)pvSrc;
189 pIosData->cbBuf = cbSrc;
190 pIosData->off = 0;
191 RTVFSFSSTREAM hVfsFss;
192 rc = RTZipPkzipFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, &hVfsFss);
193 RTVfsIoStrmRelease(hVfsIos);
194 if (RT_SUCCESS(rc))
195 {
196 /*
197 * Loop through all objects. Actually this wouldn't be required
198 * for .zip files but we opened it as I/O stream.
199 */
200 for (bool fFound = false; !fFound;)
201 {
202 char *pszName;
203 RTVFSOBJ hVfsObj;
204 rc = RTVfsFsStrmNext(hVfsFss, &pszName, NULL /*penmType*/, &hVfsObj);
205 if (RT_FAILURE(rc))
206 break;
207 fFound = !strcmp(pszName, pszObject);
208 if (fFound)
209 {
210 RTFSOBJINFO UnixInfo;
211 rc = RTVfsObjQueryInfo(hVfsObj, &UnixInfo, RTFSOBJATTRADD_UNIX);
212 if (RT_SUCCESS(rc))
213 {
214 size_t cb = UnixInfo.cbObject;
215 void *pv = RTMemAlloc(cb);
216 if (pv)
217 {
218 RTVFSIOSTREAM hVfsIosObj = RTVfsObjToIoStream(hVfsObj);
219 if (hVfsIos)
220 {
221 rc = RTVfsIoStrmRead(hVfsIosObj, pv, cb, true /*fBlocking*/, NULL);
222 if (RT_SUCCESS(rc))
223 {
224 *ppvDst = pv;
225 *pcbDst = cb;
226 }
227 else
228 RTMemFree(pv);
229 }
230 }
231 }
232 }
233 RTVfsObjRelease(hVfsObj);
234 RTStrFree(pszName);
235 }
236 RTVfsFsStrmRelease(hVfsFss);
237 }
238 }
239 return rc;
240}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette