// //------------------------------------------------------------------------------ size_t ReflectedPropertyStruct::GetArraySize( const void * object ) const { // sanity checks ASSERT( IsArray() ); ASSERT( GetType() == PT_STRUCT ); // get the array const size_t elementSize = GetPropertySize(); const void * arrayBase = (const void *)( (size_t)object + m_Offset ); const Array< char > * array = static_cast< const Array< char > * >( arrayBase ); // calculate the size const size_t size = ( array->End() - array->Begin() ) / elementSize; return size; }
//------------------------------------------------------------------------------ const Struct * ReflectedPropertyStruct::GetStructInArray( const void * object, size_t index ) const { // sanity checks ASSERT( IsArray() ); ASSERT( GetType() == PT_STRUCT ); ASSERT( index < GetArraySize( object ) ); // get the array const size_t elementSize = GetPropertySize(); const void * arrayBase = (const void *)( (size_t)object + m_Offset ); const Array< char > * array = static_cast< const Array< char > * >( arrayBase ); // calculate the element offset const size_t offset = ( index * elementSize ); return reinterpret_cast< Struct * >( array->Begin() + offset ); }
STDMETHODIMP ArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream** outStream, Int32 askExtractMode) { try { // Retrieve all the various properties for the file at this index. GetPropertyFilePath(index); if (askExtractMode != NArchive::NExtract::NAskMode::kExtract) { return S_OK; } GetPropertyAttributes(index); GetPropertyIsDir(index); GetPropertyModifiedTime(index); GetPropertyCreatedTime(index); GetPropertyAccessedTime(index); GetPropertySize(index); } catch (_com_error& ex) { wprintf_s(L"获取数据失败\n"); return ex.Error(); } // TODO: m_directory could be a relative path as "..\" m_absPath = FileSys::AppendPath(m_directory, m_relPath); if (m_isDir) { wprintf_s(L"DirBegin:%s\n", m_absPath.c_str()); FileSys::CreateDirectoryTree(m_absPath); *outStream = NULL; return S_OK; } if (m_callback) { if (!m_callback->OnFileBegin(m_directory, m_relPath)) { //stop decompress return E_FAIL; } //Skip file if (m_relPath.empty()) { *outStream = NULL; return S_OK; } } wprintf_s(L"FileBegin:%s\n", m_absPath.c_str()); if (m_overwriteMode == OverwriteMode::kRollBack) { TString BackupPath; if (FileSys::PathExists(m_absPath)) { BackupPath = FileSys::GetUniquePath(m_absPath); if (!FileSys::BackupFile(m_absPath, BackupPath)) return HRESULT_FROM_WIN32(GetLastError()); } RollBack_Info info; info.backup_path = BackupPath; info.original_path = m_absPath; m_rollbacks.push_back(info); } else if (FileSys::PathExists(m_absPath)) { if (m_overwriteMode == OverwriteMode::kSkipExisting) { *outStream = NULL; return S_OK; } else if (m_overwriteMode == OverwriteMode::kAutoRename) { m_absPath = FileSys::GetUniquePath(m_absPath); } else if (m_overwriteMode == OverwriteMode::kAutoRenameExisting) { TString rename_path = FileSys::GetUniquePath(m_absPath); if (!FileSys::RenameFile(m_absPath, rename_path)) { wprintf_s(L"重命名文件失败:%s-%s\n", m_absPath.c_str(), rename_path.c_str()); return HRESULT_FROM_WIN32(GetLastError()); } } else if (m_overwriteMode == OverwriteMode::kWithoutPrompt) { if (!FileSys::RemovePath(m_absPath)) { wprintf_s(L"移除路径失败:%s\n", m_absPath.c_str()); return HRESULT_FROM_WIN32(GetLastError()); } } else { wprintf_s(L"文件已存在:%s\n", m_absPath.c_str()); return ERROR_FILE_EXISTS; } } TString absDir = FileSys::GetPath(m_absPath); if (!FileSys::CreateDirectoryTree(absDir)) { wprintf_s(L"创建目录失败:%s\n", absDir.c_str()); return ERROR_CREATE_FAILED; } CMyComPtr< IStream > fileStream = FileSys::OpenFileToWrite(m_absPath); if (fileStream == NULL) { wprintf_s(L"创建文件失败:%s\n", m_absPath.c_str()); m_absPath.clear(); return HRESULT_FROM_WIN32(GetLastError()); } OutStreamWrapper* stream = new OutStreamWrapper(fileStream); if (!stream) { wprintf_s(L"内存不足\n"); return E_OUTOFMEMORY; } CMyComPtr< OutStreamWrapper > wrapperStream = stream; *outStream = wrapperStream.Detach(); return S_OK; }