p7zip/CPP/7zip/UI/ClientCodec/ClientCodec.cpp
2017-10-11 12:35:36 +02:00

371 lines
9.9 KiB
C++

// Client7z.cpp
#include "StdAfx.h"
#ifdef _WIN32
#include <initguid.h>
#else
#include "Common/MyInitGuid.h"
#endif
#include "Windows/DLL.h"
#include "../../ICoder.h"
#include "Windows/PropVariant.h"
#include "Common/MyCom.h"
using namespace NWindows;
class CFileIn : public ISequentialInStream, public CMyUnknownImp
{
FILE *file_;
size_t pos_;
public:
MY_UNKNOWN_IMP
CFileIn() : file_(0) , pos_(0) { }
~CFileIn() { this->close(); }
HRESULT open(const char *name)
{
file_ = fopen(name,"rb");
if (file_) return S_OK;
return E_FAIL;
}
void close()
{
if (file_) fclose(file_);
file_ = 0;
pos_ = 0;
}
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (file_)
{
size_t ret = fread (data, 1, size, file_);
*processedSize = ret;
pos_ += ret;
// TBD : if ret == 0, test for feof/ferror
return S_OK;
}
return E_FAIL;
}
size_t pos() { return pos_; }
};
class CFileOut : public ISequentialOutStream, public CMyUnknownImp
{
FILE *file_;
size_t pos_;
public:
MY_UNKNOWN_IMP
CFileOut() : file_(0) { }
~CFileOut() { this->close(); }
HRESULT open(const char *name)
{
file_ = fopen(name,"wb");
if (file_) return S_OK;
return E_FAIL;
}
void close()
{
if (file_) fclose(file_);
file_ = 0;
}
HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize)
{
if (file_)
{
size_t ret = fwrite(data, 1, size, file_);
*processedSize = ret;
pos_ += ret;
// TBD : if ret == 0, test for feof/ferror
return S_OK;
}
return E_FAIL;
}
size_t pos() { return pos_; }
};
//////////////////////////////////////////////////////////////////////////
// Main function
static const char *kHelpString =
"Usage: ClientCodec codec.so [c | d | i] [file_in file_out]\n"
"Examples:\n"
" ClientCodec LZMA.so i : info about the codec\n"
" ClientCodec LZMA.so e file_in file_out : encodes file_in to file_out\n"
" ClientCodec LZMA.so d file_in file_out : decodes file_in to file_out\n"
;
typedef UINT32 (WINAPI * CreateObjectFunc)(
const GUID *clsID,
const GUID *interfaceID,
void **outObject);
typedef UINT32 (WINAPI * GetNumberOfMethodsFunc)(UINT32 *numMethods);
typedef UINT32 (WINAPI * GetMethodPropertyFunc)(UINT32 index, PROPID propID, PROPVARIANT *value);
int main(int argc, char* argv[])
{
if ((argc != 3) && (argc != 5))
{
printf(kHelpString);
return 1;
}
if ((argc == 3) && (strcmp(argv[2],"i") != 0))
{
printf(kHelpString);
return 1;
}
NWindows::NDLL::CLibrary library;
if (!library.Load(argv[1]))
{
printf("Can not load library %s\n",argv[1]);
return 1;
}
CreateObjectFunc createObjectFunc = (CreateObjectFunc)library.GetProcAddress("CreateObject");
if (createObjectFunc == 0)
{
printf("Can not get CreateObject\n");
return 1;
}
GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)library.GetProcAddress("GetNumberOfMethods");
if (getNumberOfMethodsFunc == 0)
{
printf("Can not get GetNumberOfMethodsFunc\n");
return 1;
}
UINT32 numMethods = 0;
HRESULT res = getNumberOfMethodsFunc(&numMethods);
if (res != S_OK)
{
printf("Error in GetNumberOfMethods\n");
return 1;
}
GetMethodPropertyFunc getMethodPropertyFunc = (GetMethodPropertyFunc)library.GetProcAddress("GetMethodProperty");
if (getMethodPropertyFunc == 0)
{
printf("Can not get GetMethodProperty\n");
return 1;
}
if (argv[2][0] == 'i')
{
printf("%s has %d method(s)\n",argv[1],(int)numMethods);
for(UINT32 m = 0; m < numMethods ; m++)
{
printf("\tMethod %d :\n",(int)m);
NCOM::CPropVariant propVariant;
res = getMethodPropertyFunc(m,NMethodPropID::kName,&propVariant);
if (res == S_OK)
{
if (propVariant.vt == VT_BSTR)
{
printf("\t\tName : %ls\n",propVariant.bstrVal); // Unicode Name
} else {
printf("\t\tName : Error\n");
}
} else {
printf("\t\tName : Unknown\n");
}
res = getMethodPropertyFunc(m,NMethodPropID::kDecoder,&propVariant);
if ((res == S_OK) && (propVariant.vt == VT_BSTR)) printf("\t\tDecoder : YES\n");
else printf("\t\tDecoder : NO\n");
res = getMethodPropertyFunc(m,NMethodPropID::kEncoder,&propVariant);
if ((res == S_OK) && (propVariant.vt == VT_BSTR)) printf("\t\tEncoder : YES\n");
else printf("\t\tEncoder : NO\n");
}
}
int numMethod = 0; // TBD
if (argv[2][0] == 'e')
{
NCOM::CPropVariant propVariant;
res = getMethodPropertyFunc(numMethod,NMethodPropID::kEncoder,&propVariant);
if ((res == S_OK) && (propVariant.vt == VT_BSTR))
{
CMyComPtr<ICompressCoder> outCoder;
if (createObjectFunc((const GUID *)propVariant.bstrVal, &IID_ICompressCoder, (void **)&outCoder) != S_OK)
{
printf("Can not get class object\n");
return 1;
}
printf("Encoding : ...\n");
CMyComPtr<CFileIn> inStream = new CFileIn;
res = inStream->open(argv[3]);
if (res != S_OK)
{
printf("cannot open %s\n",argv[3]);
return 1;
}
CMyComPtr<CFileOut> outStream = new CFileOut;
res = outStream->open(argv[4]);
if (res != S_OK)
{
printf("cannot open %s\n",argv[4]);
return 1;
}
{
CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
outCoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
if (setCoderProperties != NULL)
{
printf("IID_ICompressSetCoderProperties : Found\n");
PROPID propID = NCoderPropID::kEndMarker;
NWindows::NCOM::CPropVariant value = true;
res = setCoderProperties->SetCoderProperties(&propID, &value, 1);
if (res = S_OK) printf("kEndMarker : ON\n");
else printf("kEndMarker : KO KO\n");
}
else
{
printf("IID_ICompressSetCoderProperties : NOT Found\n");
}
}
{
CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
outCoder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);
if (writeCoderProperties != NULL)
{
UINT32 len = 5; // TBD
UInt32 processedSize;
outStream->Write(&len, sizeof(len), &processedSize);
printf("IID_ICompressWriteCoderProperties : Found\n");
size_t pos1 = outStream->pos();
writeCoderProperties->WriteCoderProperties(outStream);
size_t pos2 = outStream->pos();
printf("SizeOfProp : %d\n",(int)(pos2-pos1));
/*
CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
outStreamSpec->Init();
writeCoderProperties->WriteCoderProperties(outStream);
size_t size = outStreamSpec->GetSize();
// encodingInfo.Properties.SetCapacity(size);
if (encodingInfo.AltCoders.Size() == 0)
encodingInfo.AltCoders.Add(CAltCoderInfo());
CAltCoderInfo &altCoderInfo = encodingInfo.AltCoders.Front();
altCoderInfo.Properties.SetCapacity(size);
memmove(altCoderInfo.Properties, outStreamSpec->GetBuffer(), size);
*/
}
else
{
printf("IID_ICompressWriteCoderProperties : NOT Found\n");
UINT32 len = 0;
UInt32 processedSize;
outStream->Write(&len, sizeof(len), &processedSize);
}
}
res = outCoder->Code(inStream,outStream,0,0,0);
inStream->close();
outStream->close();
if (res == S_OK)
{
printf("Encoding : Done\n");
} else {
printf("Encoding : Error\n");
return 1;
}
}
else
{
printf("Encoder not available\n");
return 1;
}
}
if (argv[2][0] == 'd')
{
NCOM::CPropVariant propVariant;
res = getMethodPropertyFunc(numMethod,NMethodPropID::kDecoder,&propVariant);
if ((res == S_OK) && (propVariant.vt == VT_BSTR))
{
CMyComPtr<ICompressCoder> outCoder;
if (createObjectFunc((const GUID *)propVariant.bstrVal, &IID_ICompressCoder, (void **)&outCoder) != S_OK)
{
printf("Can not get class object\n");
return 1;
}
printf("Decoding : ...\n");
CMyComPtr<CFileIn> inStream = new CFileIn;
res = inStream->open(argv[3]);
if (res != S_OK)
{
printf("cannot open %s\n",argv[3]);
return 1;
}
CMyComPtr<CFileOut> outStream = new CFileOut;
res = outStream->open(argv[4]);
if (res != S_OK)
{
printf("cannot open %s\n",argv[4]);
return 1;
}
{
UINT32 len = 0;
UInt32 processedSize;
inStream->Read(&len, sizeof(len), &processedSize);
if (len > 0)
{
Byte props[256]; // TBD
inStream->Read(props, len, &processedSize);
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
outCoder->QueryInterface(IID_ICompressSetDecoderProperties2, (void **)&setDecoderProperties);
if (setDecoderProperties)
{
setDecoderProperties->SetDecoderProperties2(props, len);
printf("IID_ICompressSetDecoderProperties2 : Found (%d)\n",(int)len);
}
}
}
// FIXME UInt64 outSize = 10511; // res = outCoder->Code(inStream,outStream,0,&outSize,0);
res = outCoder->Code(inStream,outStream,0,0,0);
inStream->close();
outStream->close();
if (res == S_OK)
{
printf("Decoding : Done\n");
} else {
printf("Decoding : Error\n");
return 1;
}
}
else
{
printf("Decoder not available\n");
return 1;
}
}
return 0;
}