nim_duilib/examples/bsdiff/basic_form.cpp

247 lines
5.5 KiB
C++
Raw Normal View History

2024-11-02 05:53:13 +08:00
#include "stdafx.h"
#include "basic_form.h"
#include <atlstr.h>
#include <afxdlgs.h>
#include <afxwin.h>
#include <io.h>
#include <iosfwd>
#include <iostream>
#include <ios>
#include <fstream>
#include <vector>
#include <codecvt>
extern"C" {
#include "bsdiff.h"
#include "bspatch.h"
}
const std::wstring BasicForm::kClassName = L"Basic";
BasicForm::BasicForm()
{
}
BasicForm::~BasicForm()
{
}
std::wstring BasicForm::GetSkinFolder()
{
return L"basic";
}
std::wstring BasicForm::GetSkinFile()
{
return L"bsdiff.xml";
}
std::wstring BasicForm::GetWindowClassName() const
{
return kClassName;
}
static int res_write(struct bsdiff_stream* stream, const void* buffer, int size)
{
int bz2err;
//BZ2_bzWrite(&bz2err, bz2, (void*)buffer, size);
//if (bz2err != BZ_STREAM_END && bz2err != BZ_OK)
// return -1;
if (stream->size == 0) {
stream->result = new char[8192000];
stream->size = 8192000;
}
memcpy(&stream->result[stream->len], buffer, size);
stream->len += size;
return 0;
}
LRESULT BasicForm::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return WindowImplBase::OnNcHitTest(uMsg, wParam, lParam, bHandled);
}
inline std::string to_byte_string(const std::wstring& input)
{
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
return converter.to_bytes(input);
}
static int bz2_read( struct bspatch_stream* stream, void* buffer, int length)
{
int n;
int bz2err;
char* addr = (char*)stream->opaque;
memcpy(buffer, &addr[stream->res_len], length);
stream->res_len += length;
return 0;
}
std::vector<char>* ReadFile(std::string path) {
std::vector<char>* ret = nullptr;
std::ifstream file(path.c_str(), std::ios::in | std::ios::binary);
if (file)
{
// <20><><EFBFBD>ն<EFBFBD><D5B6><EFBFBD><EFBFBD>Ƹ<EFBFBD>ʽ<EFBFBD><CABD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
file.seekg(0, std::ios::end);
long long fileSize = file.tellg();
printf("size of firm: %lld\n", fileSize);
// <20><><EFBFBD><EFBFBD>дλ<D0B4><CEBB><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD>̼<EFBFBD><CCBC><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD>buffer
file.seekg(0, std::ios::beg);
char* buffer = new char[fileSize];
file.read(buffer, sizeof(char) * fileSize);
ret = new std::vector<char>(buffer, buffer + sizeof(char) * fileSize);
file.close();
}
else
{
std::cout << "Failed to open file." << std::endl;
}
return ret;
}
void BasicForm::InitWindow() {
ui::Button* btn_open1 = dynamic_cast<ui::Button*>(FindControl(L"btn_do_open1"));
ui::Button* btn_open2 = dynamic_cast<ui::Button*>(FindControl(L"btn_do_open2"));
ui::Button* btn_open3 = dynamic_cast<ui::Button*>(FindControl(L"btn_do_generate"));
mLabel1 = dynamic_cast<ui::RichEdit*>(FindControl(L"file1_dir"));
mLabel2 = dynamic_cast<ui::RichEdit*>(FindControl(L"file2_dir"));
btn_open1->AttachClick([this](ui::EventArgs*) {
CString strFilter;
CString str;
CString m_strTmpFile;
CStdioFile cfLogFile;
//<2F><><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>*.txt<78><74>*.dat<61><74><EFBFBD>ļ<EFBFBD>
strFilter = "dat file (*.*)|*.*";
CFileDialog TmpDlg(true, 0, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter.GetBuffer(),
CWnd::FromHandle(this->m_hWnd));
if (TmpDlg.DoModal() == IDOK)
{
//<2F><>ȡ<EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
m_strTmpFile = TmpDlg.GetPathName();
mLabel1->SetText(std::wstring(m_strTmpFile));
}
return true;
});
btn_open2->AttachClick([this](ui::EventArgs*) {
CString strFilter;
CString str;
CString m_strTmpFile;
CStdioFile cfLogFile;
//<2F><><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>*.txt<78><74>*.dat<61><74><EFBFBD>ļ<EFBFBD>
strFilter = "dat file (*.*)|*.*";
CFileDialog TmpDlg(true, 0, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter.GetBuffer(),
CWnd::FromHandle(this->m_hWnd));
if (TmpDlg.DoModal() == IDOK)
{
//<2F><>ȡ<EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
m_strTmpFile = TmpDlg.GetPathName();
mLabel2->SetText(std::wstring(m_strTmpFile));
}
return true;
});
btn_open3->AttachClick([this](ui::EventArgs*) {
CString strFilter;
CString str;
CString m_strTmpFile;
CStdioFile cfLogFile;
if (mLabel1->GetText() == L"") {
AfxMessageBox(_T("<EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>"));
return false;
}
if (mLabel2->GetText() == L"") {
AfxMessageBox(_T("<EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>"));
return false;
}
std::vector<char>* v1 = ReadFile(to_byte_string(mLabel1->GetText()));
std::vector<char>* v2 = ReadFile(to_byte_string(mLabel2->GetText()));
//<2F><><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>*.txt<78><74>*.dat<61><74><EFBFBD>ļ<EFBFBD>
strFilter = "dat file (*.diff)|*.diff";
CFileDialog TmpDlg(true, 0, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter.GetBuffer(),
CWnd::FromHandle(this->m_hWnd));
bsdiff_stream stream;
stream.malloc = &malloc;
stream.free = &free;
stream.write = &res_write;
stream.size = 0;
stream.len = 0;
int ret = bsdiff((uint8_t*)v1->data(), v1->size(),
(uint8_t*)v2->data(), v2->size(), &stream);
if (TmpDlg.DoModal() == IDOK)
{
//<2F><>ȡ<EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
m_strTmpFile = TmpDlg.GetPathName();
std::ofstream file(m_strTmpFile, std::ios::out | std::ios::binary);
file.write(reinterpret_cast<char*>(stream.result), stream.len);
file.flush();
file.close();
bspatch_stream rec;
rec.read = &bz2_read;
rec.opaque = (uint8_t*)stream.result;
rec.res_len = 0;
char *data = new char[v2->size()];
// <20><><EFBFBD>ն<EFBFBD><D5B6><EFBFBD><EFBFBD>Ƹ<EFBFBD>ʽ<EFBFBD><CABD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
AfxMessageBox(_T("<EFBFBD><EFBFBD><EFBFBD>ɳɹ<EFBFBD>"));
int err = bspatch((uint8_t*)v1->data(), v1->size(), (uint8_t*)data, v2->size(), &rec);
if (err < 0) {
}
m_strTmpFile = "recover.hex";
std::ofstream file2(m_strTmpFile, std::ios::out | std::ios::binary);
file2.write(data, v2->size());
file2.flush();
file2.close();
return true;
}
}
);
}
LRESULT BasicForm::OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
PostQuitMessage(0L);
return __super::OnClose(uMsg, wParam, lParam, bHandled);
}