VirtualBox

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

Last change on this file since 51714 was 51714, checked in by vboxsync, 10 years ago

Runtime: added RTZipPkzipMemDecompress()

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.2 KB
Line 
1/* $Id: pkzip.cpp 51714 2014-06-24 16:25:10Z vboxsync $ */
2/** @file
3 * IPRT - PKZIP archive I/O.
4 */
5
6/*
7 * Copyright (C) 2014 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,pfnQueryInfo}
60 */
61static DECLCALLBACK(int) memFssIos_QueryInfo(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr)
62{
63 PMEMIOSTREAM pThis = (PMEMIOSTREAM)pvThis;
64 switch (enmAddAttr)
65 {
66 case RTFSOBJATTRADD_NOTHING:
67 case RTFSOBJATTRADD_UNIX:
68 RT_ZERO(*pObjInfo);
69 pObjInfo->cbObject = pThis->cbBuf;
70 break;
71 default:
72 return VERR_NOT_SUPPORTED;
73 }
74 return VINF_SUCCESS;
75}
76
77/**
78 * @interface_method_impl{RTVFSIOSTREAMOPS,pfnRead}
79 */
80static DECLCALLBACK(int) memFssIos_Read(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead)
81{
82 PMEMIOSTREAM pThis = (PMEMIOSTREAM)pvThis;
83 Assert(pSgBuf->cSegs == 1);
84
85 if (off < 0)
86 off = pThis->off;
87 if (off >= (RTFOFF)pThis->cbBuf)
88 return pcbRead ? VINF_EOF : VERR_EOF;
89
90 size_t cbLeft = pThis->cbBuf - off;
91 size_t cbToRead = pSgBuf->paSegs[0].cbSeg;
92 if (cbToRead > cbLeft)
93 {
94 if (!pcbRead)
95 return VERR_EOF;
96 cbToRead = (size_t)cbLeft;
97 }
98
99 memcpy(pSgBuf->paSegs[0].pvSeg, pThis->pu8Buf + off, cbToRead);
100 pThis->off = off + cbToRead;
101 if (pcbRead)
102 *pcbRead = cbToRead;
103
104 return VINF_SUCCESS;
105}
106
107/**
108 * Memory I/O object stream operations.
109 */
110static const RTVFSIOSTREAMOPS g_memFssIosOps =
111{
112 { /* Obj */
113 RTVFSOBJOPS_VERSION,
114 RTVFSOBJTYPE_IO_STREAM,
115 "MemFsStream::IoStream",
116 NULL /*Close*/,
117 memFssIos_QueryInfo,
118 RTVFSOBJOPS_VERSION
119 },
120 RTVFSIOSTREAMOPS_VERSION,
121 RTVFSIOSTREAMOPS_FEAT_NO_SG,
122 memFssIos_Read,
123 NULL /*Write*/,
124 NULL /*Flush*/,
125 NULL /*PollOne*/,
126 NULL /*Tell*/,
127 NULL /*Skip*/,
128 NULL /*ZeroFill*/,
129 RTVFSIOSTREAMOPS_VERSION
130};
131
132RTDECL(int) RTZipPkzipMemDecompress(void **ppvDst, size_t *pcbDst, void *pvSrc, size_t cbSrc, const char *pszObject)
133{
134 PMEMIOSTREAM pIosData;
135 RTVFSIOSTREAM hVfsIos;
136 int rc = RTVfsNewIoStream(&g_memFssIosOps,
137 sizeof(*pIosData),
138 RTFILE_O_READ | RTFILE_O_DENY_WRITE | RTFILE_O_OPEN,
139 NIL_RTVFS,
140 NIL_RTVFSLOCK,
141 &hVfsIos,
142 (void **)&pIosData);
143 if (RT_SUCCESS(rc))
144 {
145 pIosData->pu8Buf = (uint8_t*)pvSrc;
146 pIosData->cbBuf = cbSrc;
147 pIosData->off = 0;
148 RTVFSFSSTREAM hVfsFss;
149 rc = RTZipPkzipFsStreamFromIoStream(hVfsIos, 0 /*fFlags*/, &hVfsFss);
150 RTVfsIoStrmRelease(hVfsIos);
151 if (RT_SUCCESS(rc))
152 {
153 /*
154 * Loop through all objects. Actually this wouldn't be required
155 * for .zip files but we opened it as I/O stream.
156 */
157 for (bool fFound = false; !fFound;)
158 {
159 char *pszName;
160 RTVFSOBJ hVfsObj;
161 rc = RTVfsFsStrmNext(hVfsFss, &pszName, NULL /*penmType*/, &hVfsObj);
162 if (RT_FAILURE(rc))
163 break;
164 fFound = !strcmp(pszName, pszObject);
165 if (fFound)
166 {
167 RTFSOBJINFO UnixInfo;
168 rc = RTVfsObjQueryInfo(hVfsObj, &UnixInfo, RTFSOBJATTRADD_UNIX);
169 if (RT_SUCCESS(rc))
170 {
171 size_t cb = UnixInfo.cbObject;
172 void *pv = RTMemAlloc(cb);
173 if (pv)
174 {
175 RTVFSIOSTREAM hVfsIosObj = RTVfsObjToIoStream(hVfsObj);
176 if (hVfsIos)
177 {
178 rc = RTVfsIoStrmRead(hVfsIosObj, pv, cb, true /*fBlocking*/, NULL);
179 if (RT_SUCCESS(rc))
180 {
181 *ppvDst = pv;
182 *pcbDst = cb;
183 }
184 else
185 RTMemFree(pv);
186 }
187 }
188 }
189 }
190 RTVfsObjRelease(hVfsObj);
191 RTStrFree(pszName);
192 }
193 RTVfsFsStrmRelease(hVfsFss);
194 }
195 }
196 return rc;
197}
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