nim_duilib/examples/bsdiff/basic_form.cpp

247 lines
5.5 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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)
{
// 按照二进制格式读取数据
file.seekg(0, std::ios::end);
long long fileSize = file.tellg();
printf("size of firm: %lld\n", fileSize);
// 将读写位置移动到文件开头申请内存将固件内容存入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;
//会过滤出*.txt和*.dat的文件
strFilter = "dat file (*.*)|*.*";
CFileDialog TmpDlg(true, 0, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter.GetBuffer(),
CWnd::FromHandle(this->m_hWnd));
if (TmpDlg.DoModal() == IDOK)
{
//获取文件路径
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;
//会过滤出*.txt和*.dat的文件
strFilter = "dat file (*.*)|*.*";
CFileDialog TmpDlg(true, 0, 0, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter.GetBuffer(),
CWnd::FromHandle(this->m_hWnd));
if (TmpDlg.DoModal() == IDOK)
{
//获取文件路径
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("请先打开文件"));
return false;
}
if (mLabel2->GetText() == L"") {
AfxMessageBox(_T("请先打开文件"));
return false;
}
std::vector<char>* v1 = ReadFile(to_byte_string(mLabel1->GetText()));
std::vector<char>* v2 = ReadFile(to_byte_string(mLabel2->GetText()));
//会过滤出*.txt和*.dat的文件
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)
{
//获取文件路径
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()];
// 按照二进制格式读取数据
AfxMessageBox(_T("生成成功"));
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);
}