aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/UI/Common/OpenArchive.cpp
diff options
context:
space:
mode:
authorTetsuo Osaka <tetsugit@gmail.com>2016-10-18 15:12:28 +0200
committerTetsuo Osaka <tetsugit@gmail.com>2017-04-18 10:07:58 +0200
commitf955a79a9fffb09826cf7547f70d08c3798a2f50 (patch)
tree7ba3acdf7ba22cb749ffd9e6a868630e5a8382f2 /CPP/7zip/UI/Common/OpenArchive.cpp
parent462f68aa279e25fda265a87c6d3c4da3318314f8 (diff)
downloadlzma-f955a79a9fffb09826cf7547f70d08c3798a2f50.tar.gz
Rebase LZMA SDK on 16.04 stable
This was downloaded from http://www.7-zip.org/a/lzma1604.7z The bin folder was excluded like in previous updates All files were deleted and replaced with those from the SDK. The embedded projects Tukaani, xz-embedded and android build files where not touched. The changelog since the 9.38 beta is: 16.04 2016-10-04 ------------------------- - The bug was fixed in DllSecur.c. 16.03 2016-09-28 ------------------------- - SFX modules now use some protection against DLL preloading attack. - Some bugs in 7z code were fixed. 16.02 2016-05-21 ------------------------- - The BUG in 16.00 - 16.01 was fixed: Split Handler (SplitHandler.cpp) returned incorrect total size value (kpidSize) for split archives. 16.01 2016-05-19 ------------------------- - Some internal changes to reduce the number of compiler warnings. 16.00 2016-05-10 ------------------------- - Some bugs were fixed. 15.12 2015-11-19 ------------------------- - The BUG in C version of 7z decoder was fixed: 7zDec.c : SzDecodeLzma2() 7z decoder could mistakenly report about decoding error for some 7z archives that use LZMA2 compression method. The probability to get that mistaken decoding error report was about one error per 16384 solid blocks for solid blocks larger than 16 KB (compressed size). - The BUG (in 9.26-15.11) in C version of 7z decoder was fixed: 7zArcIn.c : SzReadHeader2() 7z decoder worked incorrectly for 7z archives that contain empty solid blocks, that can be placed to 7z archive, if some file is unavailable for reading during archive creation. 15.09 beta 2015-10-16 ------------------------- - The BUG in LZMA / LZMA2 encoding code was fixed. The BUG in LzFind.c::MatchFinder_ReadBlock() function. If input data size is larger than (4 GiB - dictionary_size), the following code worked incorrectly: - LZMA : LzmaEnc_MemEncode(), LzmaEncode() : LZMA encoding functions for compressing from memory to memory. That BUG is not related to LZMA encoder version that works via streams. - LZMA2 : multi-threaded version of LZMA2 encoder worked incorrectly, if default value of chunk size (CLzma2EncProps::blockSize) is changed to value larger than (4 GiB - dictionary_size). Change-Id: I6b3974015c605fba3c0d4d897fab5a166174f441
Diffstat (limited to 'CPP/7zip/UI/Common/OpenArchive.cpp')
-rw-r--r--CPP/7zip/UI/Common/OpenArchive.cpp591
1 files changed, 462 insertions, 129 deletions
diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp
index 4632be8..968f0ca 100644
--- a/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -39,7 +39,7 @@
#endif
// increase it, if you need to support larger SFX stubs
-static const UInt64 kMaxCheckStartPosition = 1 << 22;
+static const UInt64 kMaxCheckStartPosition = 1 << 23;
/*
Open:
@@ -195,17 +195,13 @@ public:
}
void AddUnknownItem(UInt64 next);
- int FindInsertPos(const CParseItem &item);
+ int FindInsertPos(const CParseItem &item) const;
void AddItem(const CParseItem &item);
- // void Init();
- CHandler()
- {
- _maxEndOffset = 0;
- }
+ CHandler(): _maxEndOffset(0) {}
};
-int CHandler::FindInsertPos(const CParseItem &item)
+int CHandler::FindInsertPos(const CParseItem &item) const
{
unsigned left = 0, right = _items.Size();
while (left != right)
@@ -272,7 +268,7 @@ void CHandler::AddItem(const CParseItem &item)
}
/*
-static const STATPROPSTG kProps[] =
+static const CStatProp kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidSize, VT_UI8},
@@ -368,6 +364,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
+
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems = _items.Size();
@@ -429,7 +426,9 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
outStreamSpec->ReleaseStream();
RINOK(extractCallback->SetOperationResult(opRes));
}
+
return S_OK;
+
COM_TRY_END
}
@@ -458,7 +457,7 @@ HRESULT Archive_GetItemBoolProp(IInArchive *arc, UInt32 index, PROPID propID, bo
return S_OK;
}
-HRESULT Archive_IsItem_Folder(IInArchive *arc, UInt32 index, bool &result) throw()
+HRESULT Archive_IsItem_Dir(IInArchive *arc, UInt32 index, bool &result) throw()
{
return Archive_GetItemBoolProp(arc, index, kpidIsDir, result);
}
@@ -478,7 +477,7 @@ HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &result) thro
return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result);
}
-static HRESULT Archive_GetArcBoolProp(IInArchive *arc, PROPID propid, bool &result)
+static HRESULT Archive_GetArcBoolProp(IInArchive *arc, PROPID propid, bool &result) throw()
{
NCOM::CPropVariant prop;
result = false;
@@ -498,7 +497,7 @@ static HRESULT Archive_GetArcProp_UInt(IInArchive *arc, PROPID propid, UInt64 &r
switch (prop.vt)
{
case VT_UI4: result = prop.ulVal; defined = true; break;
- case VT_I4: result = prop.lVal; defined = true; break;
+ case VT_I4: result = (Int64)prop.lVal; defined = true; break;
case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; defined = true; break;
case VT_I8: result = (UInt64)prop.hVal.QuadPart; defined = true; break;
case VT_EMPTY: break;
@@ -524,16 +523,22 @@ static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &res
return S_OK;
}
+#ifndef _SFX
+
HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const
{
if (!GetRawProps)
return E_FAIL;
+ if (index == parent)
+ return S_OK;
UInt32 curIndex = index;
+
+ UString s;
+
bool prevWasAltStream = false;
+
for (;;)
{
- UString s;
-
#ifdef MY_CPU_LE
const void *p;
UInt32 size;
@@ -546,31 +551,59 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
{
NCOM::CPropVariant prop;
RINOK(Archive->GetProperty(curIndex, kpidName, &prop));
- if (prop.vt == VT_BSTR)
- s = prop.bstrVal;
+ if (prop.vt == VT_BSTR && prop.bstrVal)
+ s.SetFromBstr(prop.bstrVal);
else if (prop.vt == VT_EMPTY)
- s = L"[Content]";
+ s.Empty();
else
return E_FAIL;
}
-
- if (prevWasAltStream)
- parts[0] = s + L":" + parts[0];
- else
- parts.Insert(0, s);
UInt32 curParent = (UInt32)(Int32)-1;
UInt32 parentType = 0;
RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType));
+
+ if (parentType != NParentType::kAltStream)
+ {
+ for (;;)
+ {
+ int pos = s.ReverseFind_PathSepar();
+ if (pos < 0)
+ {
+ break;
+ }
+ parts.Insert(0, s.Ptr(pos + 1));
+ s.DeleteFrom(pos);
+ }
+ }
+
+ parts.Insert(0, s);
+
+ if (prevWasAltStream)
+ {
+ {
+ UString &s2 = parts[parts.Size() - 2];
+ s2 += L':';
+ s2 += parts.Back();
+ }
+ parts.DeleteBack();
+ }
+
if (parent == curParent)
return S_OK;
+
+ prevWasAltStream = false;
+ if (parentType == NParentType::kAltStream)
+ prevWasAltStream = true;
+
if (curParent == (UInt32)(Int32)-1)
return E_FAIL;
- prevWasAltStream = (parentType == NParentType::kAltStream);
curIndex = curParent;
}
}
+#endif
+
HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
{
#ifdef MY_CPU_LE
@@ -585,7 +618,7 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
propType == NPropDataType::kUtf16z)
{
unsigned len = size / 2 - 1;
- wchar_t *s = result.GetBuffer(len);
+ wchar_t *s = result.GetBuf(len);
for (unsigned i = 0; i < len; i++)
{
wchar_t c = GetUi16(p);
@@ -596,7 +629,8 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
#endif
*s++ = c;
}
- result.ReleaseBuffer(len);
+ *s = 0;
+ result.ReleaseBuf_SetLen(len);
if (len != 0)
return S_OK;
}
@@ -605,8 +639,10 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
else if (GetRawProps->GetRawProp(index, kpidName, &p, &size, &propType) == S_OK &&
p && propType == NPropDataType::kUtf16z)
{
+ size -= 2;
UInt32 totalSize = size;
bool isOK = false;
+
{
UInt32 index2 = index;
for (;;)
@@ -617,13 +653,16 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
break;
if (parent == (UInt32)(Int32)-1)
{
+ if (parentType != 0)
+ totalSize += 2;
isOK = true;
break;
}
index2 = parent;
UInt32 size2;
const void *p2;
- if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK)
+ if (GetRawProps->GetRawProp(index2, kpidName, &p2, &size2, &propType) != S_OK &&
+ p2 && propType == NPropDataType::kUtf16z)
break;
totalSize += size2;
}
@@ -631,9 +670,9 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
if (isOK)
{
- wchar_t *sz = result.GetBuffer(totalSize / 2);
+ wchar_t *sz = result.GetBuf_SetEnd(totalSize / 2);
UInt32 pos = totalSize - size;
- memcpy((Byte *)sz + pos, p, size - 2);
+ memcpy((Byte *)sz + pos, p, size);
UInt32 index2 = index;
for (;;)
{
@@ -642,7 +681,11 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
if (GetRawProps->GetParent(index2, &parent, &parentType) != S_OK)
break;
if (parent == (UInt32)(Int32)-1)
+ {
+ if (parentType != 0)
+ sz[pos / 2 - 1] = L':';
break;
+ }
index2 = parent;
UInt32 size2;
const void *p2;
@@ -652,7 +695,6 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
memcpy((Byte *)sz + pos, p2, size2);
sz[(pos + size2 - 2) / 2] = (parentType == 0) ? WCHAR_PATH_SEPARATOR : L':';
}
- result.ReleaseBuffer((totalSize - 2) / 2);
#ifdef _WIN32
// result.Replace(L'/', WCHAR_PATH_SEPARATOR);
#endif
@@ -666,8 +708,8 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
{
NCOM::CPropVariant prop;
RINOK(Archive->GetProperty(index, kpidPath, &prop));
- if (prop.vt == VT_BSTR)
- result = prop.bstrVal;
+ if (prop.vt == VT_BSTR && prop.bstrVal)
+ result.SetFromBstr(prop.bstrVal);
else if (prop.vt == VT_EMPTY)
result.Empty();
else
@@ -675,6 +717,16 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
}
if (result.IsEmpty())
+ return GetDefaultItemPath(index, result);
+ return S_OK;
+}
+
+HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const
+{
+ result.Empty();
+ bool isDir;
+ RINOK(Archive_IsItem_Dir(Archive, index, isDir));
+ if (!isDir)
{
result = DefaultName;
NCOM::CPropVariant prop;
@@ -703,6 +755,161 @@ HRESULT CArc::GetItemPath2(UInt32 index, UString &result) const
return S_OK;
}
+#ifdef SUPPORT_ALT_STREAMS
+
+int FindAltStreamColon_in_Path(const wchar_t *path)
+{
+ unsigned i = 0;
+ int colonPos = -1;
+ for (;; i++)
+ {
+ wchar_t c = path[i];
+ if (c == 0)
+ return colonPos;
+ if (c == ':')
+ {
+ if (colonPos < 0)
+ colonPos = i;
+ continue;
+ }
+ if (c == WCHAR_PATH_SEPARATOR)
+ colonPos = -1;
+ }
+}
+
+#endif
+
+HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
+{
+ #ifdef SUPPORT_ALT_STREAMS
+ item.IsAltStream = false;
+ item.AltStreamName.Empty();
+ item.MainPath.Empty();
+ #endif
+
+ item.IsDir = false;
+ item.Path.Empty();
+ item.ParentIndex = (UInt32)(Int32)-1;
+
+ item.PathParts.Clear();
+
+ RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir));
+ item.MainIsDir = item.IsDir;
+
+ RINOK(GetItemPath2(index, item.Path));
+
+ #ifndef _SFX
+ UInt32 mainIndex = index;
+ #endif
+
+ #ifdef SUPPORT_ALT_STREAMS
+
+ item.MainPath = item.Path;
+ if (Ask_AltStream)
+ {
+ RINOK(Archive_IsItem_AltStream(Archive, index, item.IsAltStream));
+ }
+
+ bool needFindAltStream = false;
+
+ if (item.IsAltStream)
+ {
+ needFindAltStream = true;
+ if (GetRawProps)
+ {
+ UInt32 parentType = 0;
+ UInt32 parentIndex;
+ RINOK(GetRawProps->GetParent(index, &parentIndex, &parentType));
+ if (parentType == NParentType::kAltStream)
+ {
+ NCOM::CPropVariant prop;
+ RINOK(Archive->GetProperty(index, kpidName, &prop));
+ if (prop.vt == VT_BSTR && prop.bstrVal)
+ item.AltStreamName.SetFromBstr(prop.bstrVal);
+ else if (prop.vt != VT_EMPTY)
+ return E_FAIL;
+ else
+ {
+ // item.IsAltStream = false;
+ }
+ /*
+ if (item.AltStreamName.IsEmpty())
+ item.IsAltStream = false;
+ */
+
+ needFindAltStream = false;
+ item.ParentIndex = parentIndex;
+ mainIndex = parentIndex;
+
+ if (parentIndex == (UInt32)(Int32)-1)
+ {
+ item.MainPath.Empty();
+ item.MainIsDir = true;
+ }
+ else
+ {
+ RINOK(GetItemPath2(parentIndex, item.MainPath));
+ RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir));
+ }
+ }
+ }
+ }
+
+ if (item.WriteToAltStreamIfColon || needFindAltStream)
+ {
+ /* Good handler must support GetRawProps::GetParent for alt streams./
+ So the following code currently is not used */
+ int colon = FindAltStreamColon_in_Path(item.Path);
+ if (colon >= 0)
+ {
+ item.MainPath.DeleteFrom(colon);
+ item.AltStreamName = item.Path.Ptr(colon + 1);
+ item.MainIsDir = (colon == 0 || IsPathSepar(item.Path[(unsigned)colon - 1]));
+ item.IsAltStream = true;
+ }
+ }
+
+ #endif
+
+ #ifndef _SFX
+ if (item._use_baseParentFolder_mode)
+ {
+ RINOK(GetItemPathToParent(mainIndex, item._baseParentFolder, item.PathParts));
+
+ #ifdef SUPPORT_ALT_STREAMS
+ if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty())
+ {
+ int colon;
+ {
+ UString &s = item.PathParts.Back();
+ colon = FindAltStreamColon_in_Path(s);
+ if (colon >= 0)
+ {
+ item.AltStreamName = s.Ptr(colon + 1);
+ item.MainIsDir = (colon == 0 || IsPathSepar(s[(unsigned)colon - 1]));
+ item.IsAltStream = true;
+ s.DeleteFrom(colon);
+ }
+ }
+ if (colon == 0)
+ item.PathParts.DeleteBack();
+ }
+ #endif
+
+ }
+ else
+ #endif
+ SplitPathToParts(
+ #ifdef SUPPORT_ALT_STREAMS
+ item.MainPath
+ #else
+ item.Path
+ #endif
+ , item.PathParts);
+
+ return S_OK;
+}
+
#ifndef _SFX
static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &size, bool &defined)
@@ -824,10 +1031,10 @@ static void MakeCheckOrder(CCodecs *codecs,
static bool IsExeExt(const UString &ext)
{
- return ext.IsEqualToNoCase(L"exe");
+ return ext.IsEqualTo_Ascii_NoCase("exe");
}
-static const char *k_PreArcFormats[] =
+static const char * const k_PreArcFormats[] =
{
"pe"
, "elf"
@@ -836,7 +1043,7 @@ static const char *k_PreArcFormats[] =
, "te"
};
-static bool IsNameFromList(const UString &s, const char *names[], size_t num)
+static bool IsNameFromList(const UString &s, const char * const names[], size_t num)
{
for (unsigned i = 0; i < num; i++)
if (StringsAreEqualNoCase_Ascii(s, names[i]))
@@ -852,7 +1059,7 @@ static bool IsPreArcFormat(const CArcInfoEx &ai)
return IsNameFromList(ai.Name, k_PreArcFormats, ARRAY_SIZE(k_PreArcFormats));
}
-static const char *k_Formats_with_simple_signuature[] =
+static const char * const k_Formats_with_simple_signuature[] =
{
"7z"
, "xz"
@@ -876,6 +1083,7 @@ static bool IsNewStyleSignature(const CArcInfoEx &ai)
class CArchiveOpenCallback_Offset:
public IArchiveOpenCallback,
+ public IArchiveOpenVolumeCallback,
#ifndef _NO_CRYPTO
public ICryptoGetTextPassword,
#endif
@@ -883,19 +1091,24 @@ class CArchiveOpenCallback_Offset:
{
public:
CMyComPtr<IArchiveOpenCallback> Callback;
+ CMyComPtr<IArchiveOpenVolumeCallback> OpenVolumeCallback;
UInt64 Files;
UInt64 Offset;
#ifndef _NO_CRYPTO
CMyComPtr<ICryptoGetTextPassword> GetTextPassword;
- MY_UNKNOWN_IMP2(
- IArchiveOpenCallback,
- ICryptoGetTextPassword)
- #else
- MY_UNKNOWN_IMP1(IArchiveOpenCallback)
#endif
- STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
- STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
+
+ MY_QUERYINTERFACE_BEGIN2(IArchiveOpenCallback)
+ MY_QUERYINTERFACE_ENTRY(IArchiveOpenVolumeCallback)
+ #ifndef _NO_CRYPTO
+ MY_QUERYINTERFACE_ENTRY(ICryptoGetTextPassword)
+ #endif
+ MY_QUERYINTERFACE_END
+ MY_ADDREF_RELEASE
+
+ INTERFACE_IArchiveOpenCallback(;)
+ INTERFACE_IArchiveOpenVolumeCallback(;)
#ifndef _NO_CRYPTO
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
#endif
@@ -912,12 +1125,12 @@ STDMETHODIMP CArchiveOpenCallback_Offset::CryptoGetTextPassword(BSTR *password)
}
#endif
-STDMETHODIMP CArchiveOpenCallback_Offset::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)
+STDMETHODIMP CArchiveOpenCallback_Offset::SetTotal(const UInt64 *, const UInt64 *)
{
return S_OK;
}
-STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 * /* files */, const UInt64 *bytes)
+STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 *, const UInt64 *bytes)
{
if (!Callback)
return S_OK;
@@ -927,8 +1140,25 @@ STDMETHODIMP CArchiveOpenCallback_Offset::SetCompleted(const UInt64 * /* files *
return Callback->SetCompleted(&Files, &value);
}
+STDMETHODIMP CArchiveOpenCallback_Offset::GetProperty(PROPID propID, PROPVARIANT *value)
+{
+ if (OpenVolumeCallback)
+ return OpenVolumeCallback->GetProperty(propID, value);
+ NCOM::PropVariant_Clear(value);
+ return S_OK;
+ // return E_NOTIMPL;
+}
+
+STDMETHODIMP CArchiveOpenCallback_Offset::GetStream(const wchar_t *name, IInStream **inStream)
+{
+ if (OpenVolumeCallback)
+ return OpenVolumeCallback->GetStream(name, inStream);
+ return S_FALSE;
+}
+
#endif
+
UInt32 GetOpenArcErrorFlags(const NCOM::CPropVariant &prop, bool *isDefinedProp)
{
if (isDefinedProp != NULL)
@@ -984,14 +1214,14 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR
NCOM::CPropVariant prop;
RINOK(archive->GetArchiveProperty(kpidError, &prop));
if (prop.vt != VT_EMPTY)
- ErrorInfo.ErrorMessage = (prop.vt == VT_BSTR) ? prop.bstrVal : L"Unknown error";
+ ErrorInfo.ErrorMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown error");
}
{
NCOM::CPropVariant prop;
RINOK(archive->GetArchiveProperty(kpidWarning, &prop));
if (prop.vt != VT_EMPTY)
- ErrorInfo.WarningMessage = (prop.vt == VT_BSTR) ? prop.bstrVal : L"Unknown warning";
+ ErrorInfo.WarningMessage = (prop.vt == VT_BSTR ? prop.bstrVal : L"Unknown warning");
}
if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen())
@@ -1039,30 +1269,40 @@ static PrintNumber(const char *s, int n)
HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyComPtr<IInArchive> &archive)
{
- // OutputDebugStringW(L"a1");
+ // OutputDebugStringA("a1");
// PrintNumber("formatIndex", formatIndex);
RINOK(op.codecs->CreateInArchive(formatIndex, archive));
- // OutputDebugStringW(L"a2");
+ // OutputDebugStringA("a2");
if (!archive)
return S_OK;
#ifdef EXTERNAL_CODECS
+ if (op.codecs->NeedSetLibCodecs)
{
- CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
- archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
- if (setCompressCodecsInfo)
+ const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
+ if (ai.LibIndex >= 0 ?
+ !op.codecs->Libs[ai.LibIndex].SetCodecs :
+ !op.codecs->Libs.IsEmpty())
{
- RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(op.codecs));
+ CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
+ archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo);
+ if (setCompressCodecsInfo)
+ {
+ RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(op.codecs));
+ }
}
}
#endif
- // OutputDebugStringW(ai.Name);
- // OutputDebugStringW(L"a3");
#ifndef _SFX
+
const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
+
+ // OutputDebugStringW(ai.Name);
+ // OutputDebugStringA("a3");
+
if (ai.Flags_PreArc())
{
/* we notify parsers that extract executables, that they don't need
@@ -1072,6 +1312,7 @@ HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyCom
if (allowTail)
allowTail->AllowTail(BoolToInt(true));
}
+
if (op.props)
{
/*
@@ -1087,6 +1328,7 @@ HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyCom
*/
RINOK(SetProperties(archive, *op.props));
}
+
#endif
return S_OK;
}
@@ -1130,14 +1372,14 @@ static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NAr
RINOK(archive->GetArchiveProperty(kpidName, &prop));
if (prop.vt == VT_BSTR)
{
- pi.Name = prop.bstrVal;
+ pi.Name.SetFromBstr(prop.bstrVal);
pi.Extension.Empty();
}
else
{
RINOK(archive->GetArchiveProperty(kpidExtension, &prop));
if (prop.vt == VT_BSTR)
- pi.Extension = prop.bstrVal;
+ pi.Extension.SetFromBstr(prop.bstrVal);
}
}
@@ -1145,7 +1387,7 @@ static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NAr
NCOM::CPropVariant prop;
RINOK(archive->GetArchiveProperty(kpidShortComment, &prop));
if (prop.vt == VT_BSTR)
- pi.Comment = prop.bstrVal;
+ pi.Comment.SetFromBstr(prop.bstrVal);
}
@@ -1171,7 +1413,7 @@ static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NAr
}
bool isDir = false;
- Archive_IsItem_Folder(archive, i, isDir);
+ Archive_IsItem_Dir(archive, i, isDir);
if (isDir)
pi.NumSubDirs++;
else
@@ -1336,13 +1578,13 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
IsParseArc = false;
ArcStreamOffset = 0;
- // OutputDebugStringW(L"1");
+ // OutputDebugStringA("1");
// OutputDebugStringW(Path);
const UString fileName = ExtractFileNameFromPath(Path);
UString extension;
{
- int dotPos = fileName.ReverseFind(L'.');
+ int dotPos = fileName.ReverseFind_Dot();
if (dotPos >= 0)
extension = fileName.Ptr(dotPos + 1);
}
@@ -1378,7 +1620,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
isForced = true;
orderIndices.Add(formatIndex);
numMainTypes = 1;
- isMainFormatArr[formatIndex] = true;
+ isMainFormatArr[(unsigned)formatIndex] = true;
searchMarkerInHandler = true;
}
@@ -1390,6 +1632,36 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
#endif
{
+ #ifndef _SFX
+
+ bool isZip = false;
+ bool isRar = false;
+
+ const wchar_t c = extension[0];
+ if (c == 'z' || c == 'Z' || c == 'r' || c == 'R')
+ {
+ bool isNumber = false;
+ for (unsigned k = 1;; k++)
+ {
+ const wchar_t d = extension[k];
+ if (d == 0)
+ break;
+ if (d < '0' || d > '9')
+ {
+ isNumber = false;
+ break;
+ }
+ isNumber = true;
+ }
+ if (isNumber)
+ if (c == 'z' || c == 'Z')
+ isZip = true;
+ else
+ isRar = true;
+ }
+
+ #endif
+
FOR_VECTOR (i, op.codecs->Formats)
{
const CArcInfoEx &ai = op.codecs->Formats[i];
@@ -1405,7 +1677,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
isPrearcExt = true;
#endif
- if (ai.FindExtension(extension) >= 0)
+ if (ai.FindExtension(extension) >= 0
+ #ifndef _SFX
+ || isZip && StringsAreEqualNoCase_Ascii(ai.Name, "zip")
+ || isRar && StringsAreEqualNoCase_Ascii(ai.Name, "rar")
+ #endif
+ )
{
// PrintNumber("orderIndices.Insert", i);
orderIndices.Insert(numFinded++, i);
@@ -1443,7 +1720,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
{
// signature search was here
}
- else if (extension == L"000" || extension == L"001")
+ else if (extension.IsEqualTo("000") || extension.IsEqualTo("001"))
{
int i = FindFormatForArchiveType(op.codecs, orderIndices, "rar");
if (i >= 0)
@@ -1517,6 +1794,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
#else // _SFX
numMainTypes = orderIndices.Size();
+
+ // we need correct numMainTypes for mutlivolume SFX (if some volume is missing)
+ if (numFinded != 0)
+ numMainTypes = numFinded;
#endif
}
@@ -1557,10 +1838,13 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
for (unsigned i = 0; i < numCheckTypes; i++)
{
FormatIndex = orderIndices[i];
- const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
- // OutputDebugStringW(ai.Name);
bool exactOnly = false;
+
+ #ifndef _SFX
+
+ const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
+ // OutputDebugStringW(ai.Name);
if (i >= numMainTypes)
{
if (!ai.Flags_BackwardOpen()
@@ -1569,9 +1853,13 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
continue;
exactOnly = true;
}
+
+ #endif
// Some handlers do not set total bytes. So we set it here
- RINOK(op.callback->SetTotal(NULL, &fileSize));
+ if (op.callback)
+ RINOK(op.callback->SetTotal(NULL, &fileSize));
+
if (op.stream)
{
RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
@@ -1607,7 +1895,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
#ifndef _SFX
// if it's archive, we allow another open attempt for parser
if (!mode.CanReturnParser || !isArc)
- skipFrontalFormat[FormatIndex] = true;
+ skipFrontalFormat[(unsigned)FormatIndex] = true;
#endif
if (exactOnly)
@@ -1650,7 +1938,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
#ifndef _SFX
- bool isMainFormat = isMainFormatArr[FormatIndex];
+ bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex];
const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);
bool thereIsTail = ErrorInfo.ThereIsTail;
@@ -1727,7 +2015,6 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
if (ai.FindExtension(extension) >= 0)
{
- const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
if (ai.Flags_FindSignature() && searchMarkerInHandler)
return S_FALSE;
}
@@ -1834,7 +2121,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
FormatIndex = sortedFormats[i];
const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
- RINOK(op.callback->SetTotal(NULL, &fileSize));
+ if (op.callback)
+ RINOK(op.callback->SetTotal(NULL, &fileSize));
+
RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
CMyComPtr<IInArchive> archive;
@@ -1856,7 +2145,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (result == S_FALSE)
{
- skipFrontalFormat[FormatIndex] = true;
+ skipFrontalFormat[(unsigned)FormatIndex] = true;
// FIXME: maybe we must use LenIsUnknown.
// printf(" OpenForSize Error");
continue;
@@ -1900,7 +2189,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (mode.CanReturnArc)
{
- bool isMainFormat = isMainFormatArr[FormatIndex];
+ bool isMainFormat = isMainFormatArr[(unsigned)FormatIndex];
const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);
bool openCur = false;
@@ -1938,7 +2227,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
}
- skipFrontalFormat[FormatIndex] = true;
+ skipFrontalFormat[(unsigned)FormatIndex] = true;
// if (!mode.CanReturnArc)
@@ -1976,9 +2265,6 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
{
- CArchiveOpenCallback_Offset *openCallback_Offset_Spec = new CArchiveOpenCallback_Offset;
- CMyComPtr<IArchiveOpenCallback> openCallback_Offset = openCallback_Offset_Spec;
-
const size_t kBeforeSize = 1 << 16;
const size_t kAfterSize = 1 << 20;
const size_t kBufSize = 1 << 22; // it must be more than kBeforeSize + kAfterSize
@@ -2032,7 +2318,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
thereAreHandlersForSearch = true;
UInt32 v = HASH_VAL(sig, 0);
- unsigned sigIndex = arc2sig[index] + k;
+ unsigned sigIndex = arc2sig[(unsigned)index] + k;
prevs[sigIndex] = hash[v];
hash[v] = (Byte)sigIndex;
}
@@ -2056,16 +2342,22 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
CMyComPtr<IInStream> limitedStream = limitedStreamSpec;
limitedStreamSpec->SetStream(op.stream);
- openCallback_Offset_Spec->Callback = op.callback;
-
- #ifndef _NO_CRYPTO
+ CArchiveOpenCallback_Offset *openCallback_Offset_Spec = NULL;
+ CMyComPtr<IArchiveOpenCallback> openCallback_Offset;
if (op.callback)
{
+ openCallback_Offset_Spec = new CArchiveOpenCallback_Offset;
+ openCallback_Offset = openCallback_Offset_Spec;
+ openCallback_Offset_Spec->Callback = op.callback;
+ openCallback_Offset_Spec->Callback.QueryInterface(IID_IArchiveOpenVolumeCallback, &openCallback_Offset_Spec->OpenVolumeCallback);
+ #ifndef _NO_CRYPTO
openCallback_Offset_Spec->Callback.QueryInterface(IID_ICryptoGetTextPassword, &openCallback_Offset_Spec->GetTextPassword);
+ #endif
}
- #endif
- RINOK(op.callback->SetTotal(NULL, &fileSize));
+ if (op.callback)
+ RINOK(op.callback->SetTotal(NULL, &fileSize));
+
CByteBuffer &byteBuffer = limitedStreamSpec->Buffer;
byteBuffer.Alloc(kBufSize);
@@ -2148,12 +2440,19 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
}
- if (pos >= callbackPrev + (1 << 23))
+ bool useOffsetCallback = false;
+ if (openCallback_Offset)
{
openCallback_Offset_Spec->Files = handlerSpec->_items.Size();
openCallback_Offset_Spec->Offset = pos;
- RINOK(openCallback_Offset->SetCompleted(NULL, NULL));
- callbackPrev = pos;
+
+ useOffsetCallback = (!op.openType.CanReturnArc || handlerSpec->_items.Size() > 1);
+
+ if (pos >= callbackPrev + (1 << 23))
+ {
+ RINOK(openCallback_Offset_Spec->SetCompleted(NULL, NULL));
+ callbackPrev = pos;
+ }
}
{
@@ -2323,14 +2622,21 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
UInt64 maxCheckStartPosition = 0;
- openCallback_Offset_Spec->Files = handlerSpec->_items.Size();
- openCallback_Offset_Spec->Offset = startArcPos;
+
+ if (openCallback_Offset)
+ {
+ openCallback_Offset_Spec->Files = handlerSpec->_items.Size();
+ openCallback_Offset_Spec->Offset = startArcPos;
+ }
+
// HRESULT result = archive->Open(limitedStream, &maxCheckStartPosition, openCallback_Offset);
extractCallback_To_OpenCallback_Spec->Files = 0;
extractCallback_To_OpenCallback_Spec->Offset = startArcPos;
- HRESULT result = OpenArchiveSpec(archive, true, limitedStream, &maxCheckStartPosition, openCallback_Offset, extractCallback_To_OpenCallback);
-
+ HRESULT result = OpenArchiveSpec(archive, true, limitedStream, &maxCheckStartPosition,
+ useOffsetCallback ? (IArchiveOpenCallback *)openCallback_Offset : (IArchiveOpenCallback *)op.callback,
+ extractCallback_To_OpenCallback);
+
RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result));
bool isOpen = false;
@@ -2607,11 +2913,12 @@ HRESULT CArc::OpenStream(const COpenOptions &op)
RINOK(Archive_GetArcBoolProp(Archive, kpidIsAltStream, Ask_AltStream));
RINOK(Archive_GetArcBoolProp(Archive, kpidIsAux, Ask_Aux));
RINOK(Archive_GetArcBoolProp(Archive, kpidINode, Ask_INode));
+ RINOK(Archive_GetArcBoolProp(Archive, kpidReadOnly, IsReadOnly));
const UString fileName = ExtractFileNameFromPath(Path);
UString extension;
{
- int dotPos = fileName.ReverseFind(L'.');
+ int dotPos = fileName.ReverseFind_Dot();
if (dotPos >= 0)
extension = fileName.Ptr(dotPos + 1);
}
@@ -2621,7 +2928,7 @@ HRESULT CArc::OpenStream(const COpenOptions &op)
{
const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
if (ai.Exts.Size() == 0)
- DefaultName = GetDefaultName2(fileName, L"", L"");
+ DefaultName = GetDefaultName2(fileName, UString(), UString());
else
{
int subExtIndex = ai.FindExtension(extension);
@@ -2639,10 +2946,10 @@ HRESULT CArc::OpenStream(const COpenOptions &op)
#ifdef _SFX
#ifdef _WIN32
- static const wchar_t *k_ExeExt = L".exe";
+ static const char *k_ExeExt = ".exe";
static const unsigned k_ExeExt_Len = 4;
#else
- static const wchar_t *k_ExeExt = L"";
+ static const char *k_ExeExt = "";
static const unsigned k_ExeExt_Len = 0;
#endif
@@ -2653,6 +2960,7 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
CMyComPtr<IInStream> fileStream;
CMyComPtr<ISequentialInStream> seqStream;
CInFileStream *fileStreamSpec = NULL;
+
if (op.stdInMode)
{
seqStream = new CStdInFileStream;
@@ -2692,9 +3000,10 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
|| !op.callbackSpec
|| NonOpen_ErrorInfo.IsArc_After_NonOpen())
return res;
+
{
if (filePath.Len() > k_ExeExt_Len
- && MyStringCompareNoCase(filePath.RightPtr(k_ExeExt_Len), k_ExeExt) == 0)
+ && StringsAreEqualNoCase_Ascii(filePath.RightPtr(k_ExeExt_Len), k_ExeExt))
{
const UString path2 = filePath.Left(filePath.Len() - k_ExeExt_Len);
FOR_VECTOR (i, op.codecs->Formats)
@@ -2703,9 +3012,10 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
if (ai.IsSplit())
continue;
UString path3 = path2;
- path3 += L".";
+ path3 += L'.';
path3 += ai.GetMainExt(); // "7z" for SFX.
- Path = path3 + L".001";
+ Path = path3;
+ Path.AddAscii(".001");
bool isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path));
if (!isOk)
{
@@ -2733,8 +3043,9 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
void CArchiveLink::KeepModeForNextOpen()
{
- for (int i = Arcs.Size() - 1; i >= 0; i--)
+ for (unsigned i = Arcs.Size(); i != 0;)
{
+ i--;
CMyComPtr<IArchiveKeepModeForNextOpen> keep;
Arcs[i].Archive->QueryInterface(IID_IArchiveKeepModeForNextOpen, (void **)&keep);
if (keep)
@@ -2744,8 +3055,9 @@ void CArchiveLink::KeepModeForNextOpen()
HRESULT CArchiveLink::Close()
{
- for (int i = Arcs.Size() - 1; i >= 0; i--)
+ for (unsigned i = Arcs.Size(); i != 0;)
{
+ i--;
RINOK(Arcs[i].Close());
}
IsOpen = false;
@@ -2771,20 +3083,20 @@ void CArchiveLink::Set_ErrorsText()
if (!arc.ErrorFlagsText.IsEmpty())
{
if (!ErrorsText.IsEmpty())
- ErrorsText += L'\n';
+ ErrorsText.Add_LF();
ErrorsText += GetUnicodeString(arc.ErrorFlagsText);
}
if (!arc.ErrorMessage.IsEmpty())
{
if (!ErrorsText.IsEmpty())
- ErrorsText += L'\n';
+ ErrorsText.Add_LF();
ErrorsText += arc.ErrorMessage;
}
if (!arc.WarningMessage.IsEmpty())
{
if (!ErrorsText.IsEmpty())
- ErrorsText += L'\n';
+ ErrorsText.Add_LF();
ErrorsText += arc.WarningMessage;
}
}
@@ -2909,10 +3221,14 @@ HRESULT CArchiveLink::Open(COpenOptions &op)
bool zerosTailIsAllowed;
RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed));
- CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
- op.callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
- if (setSubArchiveName)
- setSubArchiveName->SetSubArchiveName(arc2.Path);
+
+ if (op.callback)
+ {
+ CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
+ op.callback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName);
+ if (setSubArchiveName)
+ setSubArchiveName->SetSubArchiveName(arc2.Path);
+ }
arc2.SubfileIndex = mainSubfile;
@@ -2951,23 +3267,7 @@ HRESULT CArchiveLink::Open(COpenOptions &op)
return resSpec;
}
-static void SetCallback(const FString &filePath,
- IOpenCallbackUI *callbackUI,
- IArchiveOpenCallback *reOpenCallback,
- CMyComPtr<IArchiveOpenCallback> &callback)
-{
- COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
- callback = openCallbackSpec;
- openCallbackSpec->Callback = callbackUI;
- openCallbackSpec->ReOpenCallback = reOpenCallback;
-
- FString dirPrefix, fileName;
- NFile::NDir::GetFullPathAndSplit(filePath, dirPrefix, fileName);
- openCallbackSpec->Init(dirPrefix, fileName);
-}
-
-HRESULT CArchiveLink::Open2(COpenOptions &op,
- IOpenCallbackUI *callbackUI)
+HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI)
{
VolumesSize = 0;
COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
@@ -2975,6 +3275,7 @@ HRESULT CArchiveLink::Open2(COpenOptions &op,
openCallbackSpec->Callback = callbackUI;
FString prefix, name;
+
if (!op.stream && !op.stdInMode)
{
NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), prefix, name);
@@ -2987,7 +3288,13 @@ HRESULT CArchiveLink::Open2(COpenOptions &op,
op.callback = callback;
op.callbackSpec = openCallbackSpec;
- RINOK(Open(op));
+
+ HRESULT res = Open(op);
+
+ PasswordWasAsked = openCallbackSpec->PasswordWasAsked;
+ // Password = openCallbackSpec->Password;
+
+ RINOK(res);
// VolumePaths.Add(fs2us(prefix + name));
FOR_VECTOR (i, openCallbackSpec->FileNames_WasUsed)
@@ -3044,6 +3351,15 @@ HRESULT CArc::ReOpen(const COpenOptions &op)
return res;
}
+HRESULT CArchiveLink::Open3(COpenOptions &op, IOpenCallbackUI *callbackUI)
+{
+ HRESULT res = Open2(op, callbackUI);
+ if (callbackUI)
+ {
+ RINOK(callbackUI->Open_Finished());
+ }
+ return res;
+}
HRESULT CArchiveLink::ReOpen(COpenOptions &op)
{
@@ -3060,8 +3376,17 @@ HRESULT CArchiveLink::ReOpen(COpenOptions &op)
if (Arcs.Size() == 0) // ???
return Open2(op, NULL);
- CMyComPtr<IArchiveOpenCallback> openCallbackNew;
- SetCallback(us2fs(op.filePath), NULL, op.callback, openCallbackNew);
+ COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
+ CMyComPtr<IArchiveOpenCallback> openCallbackNew = openCallbackSpec;
+
+ openCallbackSpec->Callback = NULL;
+ openCallbackSpec->ReOpenCallback = op.callback;
+ {
+ FString dirPrefix, fileName;
+ NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), dirPrefix, fileName);
+ openCallbackSpec->Init(dirPrefix, fileName);
+ }
+
CInFileStream *fileStreamSpec = new CInFileStream;
CMyComPtr<IInStream> stream(fileStreamSpec);
@@ -3071,6 +3396,10 @@ HRESULT CArchiveLink::ReOpen(COpenOptions &op)
CArc &arc = Arcs[0];
HRESULT res = arc.ReOpen(op);
+
+ PasswordWasAsked = openCallbackSpec->PasswordWasAsked;
+ // Password = openCallbackSpec->Password;
+
IsOpen = (res == S_OK);
return res;
}
@@ -3136,7 +3465,9 @@ static bool ParseTypeParams(const UString &s, COpenType &type)
bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
{
- int pos2 = s.Find(':');
+ int pos2 = s.Find(L':');
+
+ {
UString name;
if (pos2 < 0)
{
@@ -3171,13 +3502,15 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
}
type.FormatIndex = index;
+
+ }
for (unsigned i = pos2; i < s.Len();)
{
- int next = s.Find(':', i);
+ int next = s.Find(L':', i);
if (next < 0)
next = s.Len();
- UString name = s.Mid(i, next - i);
+ const UString name = s.Mid(i, next - i);
if (name.IsEmpty())
return false;
if (!ParseTypeParams(name, type))
@@ -3193,7 +3526,7 @@ bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType>
types.Clear();
for (unsigned pos = 0; pos < s.Len();)
{
- int pos2 = s.Find('.', pos);
+ int pos2 = s.Find(L'.', pos);
if (pos2 < 0)
pos2 = s.Len();
UString name = s.Mid(pos, pos2 - pos);