VirtualBox

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

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

*: scm cleanup run.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.2 KB
Line 
1/* $Id: pkzip.cpp 57358 2015-08-14 15:16:38Z 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#include <iprt/zip.h>
30#include <iprt/file.h>
31#include <iprt/fs.h>
32#include <iprt/mem.h>
33#include <iprt/string.h>
34#include <iprt/vfs.h>
35#include <iprt/vfslowlevel.h>
36
37
38/*********************************************************************************************************************************
39* Structures and Typedefs *
40*********************************************************************************************************************************/
41/**
42 * Memory stream private data.
43 */
44typedef struct MEMIOSTREAM
45{
46 /** Size of the memory buffer. */
47 size_t cbBuf;
48 /** Pointer to the memory buffer. */
49 uint8_t *pu8Buf;
50 /** Current offset. */
51 size_t off;
52} MEMIOSTREAM;
53typedef MEMIOSTREAM *PMEMIOSTREAM;
54
55
56/**
57 * @interface_method_impl{RTVFSOBJOPS,pfnClose}
58 */
59static DECLCALLBACK(int) memFssIos_Close(void *pvThis)
60{
61 NOREF(pvThis);
62 return VINF_SUCCESS;
63}
64
65/**
66 * @interface_method_impl{RTVFSOBJOPS,pfnQueryInfo}
67 */
68static DECLCALLBACK(int) memFssIos_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
69{
70 PMEMIOSTREAM pThis = (PMEMIOSTREAM)pvThis;
71 switch (enmAddAttr)
72 {
73 case RTFSOBJATTRADD_NOTHING:
74 case RTFSOBJATTRADD_UNIX:
75 RT_ZERO(*pObjInfo);
76 pObjInfo->cbObject = pThis->cbBuf;
77 break;
78 default:
79 return VERR_NOT_SUPPORTED;
80 }
81 return VINF_SUCCESS;
82}
83
84/**
85 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
86 */
87static DECLCALLBACK(int) memFssIos_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
88{
89 PMEMIOSTREAM pThis = (PMEMIOSTREAM)pvThis;
90 Assert(pSgBuf->cSegs == 1);
91
92 if (off < 0)
93 off = pThis->off;
94 if (off >= (RTFOFF)pThis->cbBuf)
95 return pcbRead ? VINF_EOF : VERR_EOF;
96
97 size_t cbLeft = pThis->cbBuf - off;
98 size_t cbToRead = pSgBuf->paSegs[0].cbSeg;
99 if (cbToRead > cbLeft)
100 {
101 if (!pcbRead)
102 return VERR_EOF;
103 cbToRead = (size_t)cbLeft;
104 }
105
106 memcpy(pSgBuf->paSegs[0].pvSeg, pThis->pu8Buf + off, cbToRead);
107 pThis->off = off + cbToRead;
108 if (pcbRead)
109 *pcbRead = cbToRead;
110
111 return VINF_SUCCESS;
112}
113
114/**
115 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnWrite}
116 */
117static DECLCALLBACK(int) memFssIos_Write(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten)
118{
119 return VERR_NOT_IMPLEMENTED;
120}
121
122/**
123 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnFlush}
124 */
125static DECLCALLBACK(int) memFssIos_Flush(void *pvThis)
126{
127 return VERR_NOT_IMPLEMENTED;
128}
129
130/**
131 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnPollOne}
132 */
133static DECLCALLBACK(int) memFssIos_PollOne(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr, uint32_t *pfRetEvents)
134{
135 return VERR_NOT_IMPLEMENTED;
136}
137
138/**
139 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnTell}
140 */
141static DECLCALLBACK(int) memFssIos_Tell(void *pvThis, PRTFOFF poffActual)
142{
143 PMEMIOSTREAM pThis = (PMEMIOSTREAM)pvThis;
144 *poffActual = pThis->off;
145 return VINF_SUCCESS;
146}
147
148/**
149 * Memory I/O object stream operations.
150 */
151static const RTVFSIOSTREAMOPS g_memFssIosOps =
152{
153 { /* Obj */
154 RTVFSOBJOPS_VERSION,
155 RTVFSOBJTYPE_IO_STREAM,
156 "MemFsStream::IoStream",
157 memFssIos_Close,
158 memFssIos_QueryInfo,
159 RTVFSOBJOPS_VERSION
160 },
161 RTVFSIOSTREAMOPS_VERSION,
162 RTVFSIOSTREAMOPS_FEAT_NO_SG,
163 memFssIos_Read,
164 memFssIos_Write,
165 memFssIos_Flush,
166 memFssIos_PollOne,
167 memFssIos_Tell,
168 NULL /*Skip*/,
169 NULL /*ZeroFill*/,
170 RTVFSIOSTREAMOPS_VERSION
171};
172
173RTDECL(int) RTZipPkzipMemDecompress(void **ppvDst, size_t *pcbDst, const void *pvSrc, size_t cbSrc, const char *pszObject)
174{
175 PMEMIOSTREAM pIosData;
176 RTVFSIOSTREAM hVfsIos;
177 int rc = RTVfsNewIoStream(&g_memFssIosOps,
178 sizeof(*pIosData),
179 RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN,
180 NIL_RTVFS,
181 NIL_RTVFSLOCK,
182 &hVfsIos,
183 (void **)&pIosData);
184 if (RT_SUCCESS(rc))
185 {
186 pIosData->pu8Buf = (uint8_t*)pvSrc;
187 pIosData->cbBuf = cbSrc;
188 pIosData->off = 0;
189 RTVFSFSSTREAM hVfsFss;
190 rc = RTZipPkzipFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, &hVfsFss);
191 RTVfsIoStrmRelease(hVfsIos);
192 if (RT_SUCCESS(rc))
193 {
194 /*
195 * Loop through all objects. Actually this wouldn't be required
196 * for .zip files but we opened it as I/O stream.
197 */
198 for (bool fFound = false; !fFound;)
199 {
200 char *pszName;
201 RTVFSOBJ hVfsObj;
202 rc = RTVfsFsStrmNext(hVfsFss, &pszName, NULL /*penmType*/, &hVfsObj);
203 if (RT_FAILURE(rc))
204 break;
205 fFound = !strcmp(pszName, pszObject);
206 if (fFound)
207 {
208 RTFSOBJINFO UnixInfo;
209 rc = RTVfsObjQueryInfo(hVfsObj, &UnixInfo, RTFSOBJATTRADD_UNIX);
210 if (RT_SUCCESS(rc))
211 {
212 size_t cb = UnixInfo.cbObject;
213 void *pv = RTMemAlloc(cb);
214 if (pv)
215 {
216 RTVFSIOSTREAM hVfsIosObj = RTVfsObjToIoStream(hVfsObj);
217 if (hVfsIos)
218 {
219 rc = RTVfsIoStrmRead(hVfsIosObj, pv, cb, true /*fBlocking*/, NULL);
220 if (RT_SUCCESS(rc))
221 {
222 *ppvDst = pv;
223 *pcbDst = cb;
224 }
225 else
226 RTMemFree(pv);
227 }
228 }
229 }
230 }
231 RTVfsObjRelease(hVfsObj);
232 RTStrFree(pszName);
233 }
234 RTVfsFsStrmRelease(hVfsFss);
235 }
236 }
237 return rc;
238}
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