<commit_before>//
//  SVZArchiveExtractCallback.cpp
//  SevenZip
//
//  Created by <NAME> on 2015. 11. 21..
//  Copyright © 2015. <NAME>. All rights reserved.
//

#include "SVZArchiveExtractCallback.h"

#include "CPP/Windows/Defs.h"
#include "CPP/Windows/FileDir.h"
#include "CPP/Windows/FileFind.h"
#include "CPP/Windows/FileName.h"
#include "CPP/Windows/PropVariant.h"
#include "CPP/Windows/PropVariantConv.h"

#include "CPP/Common/UTFConvert.h"

#include "SVZOutFileStream.h"

static const wchar_t *kEmptyFileAlias = L"[Content]";

static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) {
    NWindows::NCOM::CPropVariant prop;
    RINOK(archive->GetProperty(index, propID, &prop));
    if (prop.vt == VT_BOOL) {
        result = VARIANT_BOOLToBool(prop.boolVal);
    }
    else if (prop.vt == VT_EMPTY) {
        result = false;
    }
    else {
        return E_FAIL;
    }
    return S_OK;
}

static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result) {
    return IsArchiveItemProp(archive, index, kpidIsDir, result);
}

namespace SVZ {
    
    void ArchiveExtractCallback::InitExtractToFile(IInArchive *archiveHandler,
                                                   const FString &directoryPath) {
        NumErrors = 0;
        _archiveHandler = archiveHandler;
        _directoryPath = directoryPath;
        _extractToFile = true;
        NWindows::NFile::NName::NormalizeDirPathPrefix(_directoryPath);
    }
    
    void ArchiveExtractCallback::InitExtractToMemory(IInArchive *archiveHandler,
                                                     std::function<CMyComPtr<IOutStream>(UInt32, UInt64)> outStreamFactory) {
        NumErrors = 0;
        _archiveHandler = archiveHandler;
        _outStreamFactory = outStreamFactory;
        _extractToFile = false;
    }
    
    STDMETHODIMP ArchiveExtractCallback::SetTotal(UInt64 /* size */) {
        return S_OK;
    }
    
    STDMETHODIMP ArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */) {
        return S_OK;
    }
    
    STDMETHODIMP ArchiveExtractCallback::GetStream(UInt32 index,
                                                   ISequentialOutStream **aOutStream,
                                                   Int32 askExtractMode) {
        *aOutStream = 0;
        _outStream.Release();
        
        if (askExtractMode != NArchive::NExtract::NAskMode::kExtract) {
            return S_OK;
        }

        if (_extractToFile) {
            return ExtractToFile(index, aOutStream);
        }

        return ExtractToMemory(index, aOutStream);
    }

    HRESULT ArchiveExtractCallback::ExtractToMemory(UInt32 index, ISequentialOutStream **aOutStream) {
        NWindows::NCOM::CPropVariant prop;
        RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));
        UInt64 fileSize = prop.uhVal.QuadPart;

        CMyComPtr<IOutStream> os = _outStreamFactory(index, fileSize);
        *aOutStream = os.Detach();

        return S_OK;
    }

    HRESULT ArchiveExtractCallback::ExtractToFile(UInt32 index, ISequentialOutStream **aOutStream) {
        {
            // Get Name
            NWindows::NCOM::CPropVariant prop;
            RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));
            
            UString fullPath;
            if (prop.vt == VT_EMPTY) {
                fullPath = kEmptyFileAlias;
            }
            else {
                if (prop.vt != VT_BSTR) {
                    return E_FAIL;
                }
                fullPath = prop.bstrVal;
            }
            _filePath = fullPath;
        }

        {<commit_msg>Handled programming error<commit_after>//
//  SVZArchiveExtractCallback.cpp
//  SevenZip
//
//  Created by <NAME> on 2015. 11. 21..
//  Copyright © 2015. <NAME>. All rights reserved.
//

#include "SVZArchiveExtractCallback.h"

#include "CPP/Windows/Defs.h"
#include "CPP/Windows/FileDir.h"
#include "CPP/Windows/FileFind.h"
#include "CPP/Windows/FileName.h"
#include "CPP/Windows/PropVariant.h"
#include "CPP/Windows/PropVariantConv.h"

#include "CPP/Common/UTFConvert.h"

#include "SVZOutFileStream.h"

static const wchar_t *kEmptyFileAlias = L"[Content]";

static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) {
    NWindows::NCOM::CPropVariant prop;
    RINOK(archive->GetProperty(index, propID, &prop));
    if (prop.vt == VT_BOOL) {
        result = VARIANT_BOOLToBool(prop.boolVal);
    }
    else if (prop.vt == VT_EMPTY) {
        result = false;
    }
    else {
        return E_FAIL;
    }
    return S_OK;
}

static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result) {
    return IsArchiveItemProp(archive, index, kpidIsDir, result);
}

namespace SVZ {
    
    void ArchiveExtractCallback::InitExtractToFile(IInArchive *archiveHandler,
                                                   const FString &directoryPath) {
        NumErrors = 0;
        _archiveHandler = archiveHandler;
        _directoryPath = directoryPath;
        _extractToFile = true;
        NWindows::NFile::NName::NormalizeDirPathPrefix(_directoryPath);
    }
    
    void ArchiveExtractCallback::InitExtractToMemory(IInArchive *archiveHandler,
                                                     std::function<CMyComPtr<IOutStream>(UInt32, UInt64)> outStreamFactory) {
        NumErrors = 0;
        _archiveHandler = archiveHandler;
        _outStreamFactory = outStreamFactory;
        _extractToFile = false;
    }
    
    STDMETHODIMP ArchiveExtractCallback::SetTotal(UInt64 /* size */) {
        return S_OK;
    }
    
    STDMETHODIMP ArchiveExtractCallback::SetCompleted(const UInt64 * /* completeValue */) {
        return S_OK;
    }
    
    STDMETHODIMP ArchiveExtractCallback::GetStream(UInt32 index,
                                                   ISequentialOutStream **aOutStream,
                                                   Int32 askExtractMode) {
        *aOutStream = 0;
        _outStream.Release();
        
        if (askExtractMode != NArchive::NExtract::NAskMode::kExtract) {
            return S_OK;
        }

        if (_extractToFile) {
            return ExtractToFile(index, aOutStream);
        }

        return ExtractToMemory(index, aOutStream);
    }

    HRESULT ArchiveExtractCallback::ExtractToMemory(UInt32 index, ISequentialOutStream **aOutStream) {
        NWindows::NCOM::CPropVariant prop;
        RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));
        UInt64 fileSize = prop.uhVal.QuadPart;

        CMyComPtr<IOutStream> os = _outStreamFactory(index, fileSize);
        if (!os) {
            return E_ABORT;
        }
        *aOutStream = os.Detach();

        return S_OK;
    }

    HRESULT ArchiveExtractCallback::ExtractToFile(UInt32 index, ISequentialOutStream **aOutStream) {
        {
            // Get Name
            NWindows::NCOM::CPropVariant prop;
            RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));
            
            UString fullPath;
            if (prop.vt == VT_EMPTY) {
                fullPath = kEmptyFileAlias;
            }
            else {
                if (prop.vt != VT_BSTR) {
                    return E_FAIL;
                }
                fullPath = prop.bstrVal;
            }
            _filePath = fullPath;
        }

        {
{'fraction_non_alphanumeric': 0.09871534820824882, 'fraction_numerical': 0.010006761325219743, 'mean_word_length': 2.153944562899787, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4026154', 'n_tokens_mistral': 2232, 'n_tokens_neox': 2147, 'n_words': 404}