Mercurial > vba-clojure
view src/win32/7zip/7zipstreams.h @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line source
1 // This file is (modified) from2 // FCEUX (2009)3 // FCE Ultra - NES/Famicom Emulator4 // Copyright (C) 2003 Xodnizel5 //6 // This program is free software; you can redistribute it and/or modify7 // it under the terms of the GNU General Public License as published by8 // the Free Software Foundation; either version 2 of the License, or9 // (at your option) any later version.10 //11 // This program is distributed in the hope that it will be useful,12 // but WITHOUT ANY WARRANTY; without even the implied warranty of13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14 // GNU General Public License for more details.15 //16 // You should have received a copy of the GNU General Public License17 // along with this program; if not, write to the Free Software18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA20 #ifndef _7ZIPSTREAMS_HEADER21 #define _7ZIPSTREAMS_HEADER23 #include "7z/CPP/Common/MyCom.h"25 class ICountedSequentialOutStream : public ISequentialOutStream26 {27 public:28 virtual UINT32 Size() const = 0;29 };31 class SeqMemoryOutStream : public ICountedSequentialOutStream, private CMyUnknownImp32 {33 UINT8* const output;34 UINT32 pos;35 const UINT32 size;36 ULONG refCount;38 HRESULT STDMETHODCALLTYPE QueryInterface(REFGUID, void**)39 {40 return E_NOINTERFACE;41 }43 HRESULT STDMETHODCALLTYPE Write(const void* data, UInt32 length, UInt32* bytesWritten)44 {45 if (data != NULL || size == 0)46 {47 //assert(length <= size - pos);49 if (length > size - pos)50 length = size - pos;52 if(data)53 memcpy(output + pos, data, length);54 pos += length;56 if (bytesWritten)57 *bytesWritten = length;59 return S_OK;60 }61 else62 {63 return E_INVALIDARG;64 }65 }67 MY_ADDREF_RELEASE69 public:71 SeqMemoryOutStream(void* d, UINT32 s) : output((UINT8*)d), pos(0), size(s), refCount(0) {}73 virtual ~SeqMemoryOutStream()74 {75 int a = 0;76 }78 UINT32 Size() const79 {80 return pos;81 }82 };84 class SeqFileOutStream : public ICountedSequentialOutStream, private CMyUnknownImp85 {86 FILE* file;87 UINT32 pos;88 ULONG refCount;90 HRESULT STDMETHODCALLTYPE QueryInterface(REFGUID, void**)91 {92 return E_NOINTERFACE;93 }95 HRESULT STDMETHODCALLTYPE Write(const void* data, UInt32 length, UInt32* bytesWritten)96 {97 if(!file)98 return E_FAIL;100 if (data != NULL)101 {102 int written = 0;103 if(data)104 written = fwrite(data, 1, length, file);106 pos += written;107 if (bytesWritten)108 *bytesWritten = written;110 return S_OK;111 }112 else113 {114 return E_INVALIDARG;115 }116 }118 MY_ADDREF_RELEASE120 public:122 SeqFileOutStream(const char* outFilename) : pos(0), refCount(0)123 {124 file = fopen(outFilename, "wb");125 }126 virtual ~SeqFileOutStream()127 {128 if(file)129 fclose(file);130 }132 UINT32 Size() const133 {134 return pos;135 }136 };139 class OutStream : public IArchiveExtractCallback, private CMyUnknownImp140 {141 ICountedSequentialOutStream* seqStream;142 const UINT32 index;143 ULONG refCount;145 HRESULT STDMETHODCALLTYPE QueryInterface(REFGUID, void**)146 {147 return E_NOINTERFACE;148 }150 HRESULT STDMETHODCALLTYPE PrepareOperation(Int32)151 {152 return S_OK;153 }155 HRESULT STDMETHODCALLTYPE SetTotal(UInt64)156 {157 return S_OK;158 }160 HRESULT STDMETHODCALLTYPE SetCompleted(const UInt64*)161 {162 return S_OK;163 }165 HRESULT STDMETHODCALLTYPE SetOperationResult(Int32)166 {167 return S_OK;168 }170 HRESULT STDMETHODCALLTYPE GetStream(UInt32 id, ISequentialOutStream** ptr, Int32 mode)171 {172 switch (mode)173 {174 case NArchive::NExtract::NAskMode::kExtract:175 case NArchive::NExtract::NAskMode::kTest:177 if (id != index || ptr == NULL)178 return S_FALSE;179 else180 *ptr = seqStream;181 // fall through182 case NArchive::NExtract::NAskMode::kSkip:183 return S_OK;185 default:186 return E_INVALIDARG;187 }188 }190 MY_ADDREF_RELEASE192 public:194 OutStream(UINT32 index, void* data, UINT32 size) : index(index), refCount(0)195 {196 seqStream = new SeqMemoryOutStream(data, size);197 seqStream->AddRef();198 }199 OutStream(UINT32 index, const char* outFilename) : index(index), refCount(0)200 {201 seqStream = new SeqFileOutStream(outFilename);202 seqStream->AddRef();203 }204 virtual ~OutStream()205 {206 //seqStream->Release(); // commented out because apparently IInArchive::Extract() calls Release one more time than it calls AddRef207 }208 UINT32 Size() const209 {210 return seqStream->Size();211 }212 };214 class InStream : public IInStream, private IStreamGetSize, private CMyUnknownImp215 {216 ULONG refCount;218 HRESULT STDMETHODCALLTYPE QueryInterface(REFGUID, void**)219 {220 return E_NOINTERFACE;221 }223 HRESULT STDMETHODCALLTYPE GetSize(UInt64* outSize)224 {225 if (outSize)226 {227 *outSize = size;228 return S_OK;229 }230 else231 {232 return E_INVALIDARG;233 }234 }236 MY_ADDREF_RELEASE238 protected:240 UINT32 size;242 public:244 explicit InStream() : refCount(0) {}245 virtual ~InStream() {}246 };249 class InFileStream : public InStream250 {251 public:253 virtual ~InFileStream()254 {255 if(file)256 fclose(file);257 }259 FILE* file;261 InFileStream(const char* fname) : file(NULL)262 {263 file = fopen(fname, "rb");264 if(file)265 {266 fseek(file, 0, SEEK_END);267 size = ftell(file);268 fseek(file, 0, SEEK_SET);269 }270 }272 HRESULT STDMETHODCALLTYPE Read(void* data, UInt32 length, UInt32* bytesRead)273 {274 if(!file)275 return E_FAIL;277 if (data != NULL || length == 0)278 {279 int read = fread(data, 1, length, file);281 if (bytesRead)282 *bytesRead = read;284 return S_OK;285 }286 else287 {288 return E_INVALIDARG;289 }290 }292 HRESULT STDMETHODCALLTYPE Seek(Int64 offset, UInt32 origin, UInt64* pos)293 {294 if(!file)295 return E_FAIL;297 if (origin < 3)298 {299 fseek(file, (long)offset, origin);300 origin = ftell(file);302 if (pos)303 *pos = origin;305 return S_OK;306 }307 else308 {309 return E_INVALIDARG;310 }312 }313 };315 #endif