mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-15 17:30:53 +08:00
753 lines
17 KiB
C++
753 lines
17 KiB
C++
// FileDirDlg.cpp : 实现文件
|
||
//
|
||
|
||
#include "stdafx.h"
|
||
#include "lib_acl.h" // 注意:lib_acl.h 必须放在 stdafx.h 的后面,否则编译会出错:(
|
||
#include "stdlib/avl.h"
|
||
#include "FileDir.h"
|
||
#include "FileDirDlg.h"
|
||
#include "ScanDir.h"
|
||
#include ".\filedirdlg.h"
|
||
#ifdef _DEBUG
|
||
#define new DEBUG_NEW
|
||
#endif
|
||
|
||
#ifdef WIN32
|
||
#define snprintf _snprintf
|
||
#endif
|
||
|
||
#include <direct.h>
|
||
#define __S_ISTYPE(mode, mask) (((mode) & _S_IFMT) == (mask))
|
||
#ifndef S_ISDIR
|
||
# define S_ISDIR(mode) __S_ISTYPE((mode), _S_IFDIR)
|
||
#endif
|
||
|
||
typedef struct MY_TYPE
|
||
{
|
||
char name[256];
|
||
char value[256];
|
||
avl_node_t node;
|
||
} MY_TYPE;
|
||
|
||
|
||
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
|
||
|
||
class CAboutDlg : public CDialog
|
||
{
|
||
public:
|
||
CAboutDlg();
|
||
|
||
// 对话框数据
|
||
enum { IDD = IDD_ABOUTBOX };
|
||
|
||
protected:
|
||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
|
||
|
||
// 实现
|
||
protected:
|
||
DECLARE_MESSAGE_MAP()
|
||
};
|
||
|
||
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
|
||
{
|
||
}
|
||
|
||
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
|
||
{
|
||
CDialog::DoDataExchange(pDX);
|
||
}
|
||
|
||
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
|
||
END_MESSAGE_MAP()
|
||
|
||
|
||
// CFileDirDlg 对话框
|
||
|
||
CFileDirDlg::CFileDirDlg(CWnd* pParent /*=NULL*/)
|
||
: CDialog(CFileDirDlg::IDD, pParent)
|
||
, m_dirPath(_T(""))
|
||
, m_nested(TRUE)
|
||
, m_pScan(NULL)
|
||
, m_avlName(_T(""))
|
||
, m_avlValue(_T(""))
|
||
, m_outName(FALSE)
|
||
{
|
||
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
||
|
||
avl_create(&m_avlTree, compare_fn, sizeof(MY_TYPE), offsetof(MY_TYPE, node));
|
||
}
|
||
|
||
void CFileDirDlg::DoDataExchange(CDataExchange* pDX)
|
||
{
|
||
CDialog::DoDataExchange(pDX);
|
||
DDX_Text(pDX, IDC_EDIT_PATH, m_dirPath);
|
||
DDX_Check(pDX, IDC_CHECK_NETSTED, m_nested);
|
||
DDX_Text(pDX, IDC_EDIT_AVL_NAME, m_avlName);
|
||
DDX_Control(pDX, IDC_EDIT_AV_RESULT, m_debugWin);
|
||
DDX_Text(pDX, IDC_EDIT_AVL_VALUE, m_avlValue);
|
||
DDX_Check(pDX, IDC_CHECK_OUT_NAME, m_outName);
|
||
}
|
||
|
||
BEGIN_MESSAGE_MAP(CFileDirDlg, CDialog)
|
||
ON_WM_SYSCOMMAND()
|
||
ON_WM_PAINT()
|
||
ON_WM_QUERYDRAGICON()
|
||
//}}AFX_MSG_MAP
|
||
ON_WM_TIMER()
|
||
ON_EN_CHANGE(IDC_EDIT_PATH, OnEnChangeEditPath)
|
||
ON_BN_CLICKED(IDC_CHECK_NETSTED, OnBnClickedCheckNetsted)
|
||
ON_BN_CLICKED(IDC_BUTTON_SCAN, OnBnClickedButtonScan)
|
||
ON_BN_CLICKED(IDC_BUTTON_DELETE, OnBnClickedButtonDelete)
|
||
ON_BN_CLICKED(IDC_BUTTON_AVL_ADD, OnBnClickedButtonAvlAdd)
|
||
ON_BN_CLICKED(IDC_BUTTON_AVL_FIND, OnBnClickedButtonAvlFind)
|
||
ON_BN_CLICKED(IDC_BUTTON_WALK, OnBnClickedButtonWalk)
|
||
ON_EN_CHANGE(IDC_EDIT_AVL_NAME, OnEnChangeEditAvlName)
|
||
ON_BN_CLICKED(IDC_BUTTON_TEST, OnBnClickedButtonTest)
|
||
ON_EN_CHANGE(IDC_EDIT_AVL_VALUE, OnEnChangeEditAvlValue)
|
||
ON_BN_CLICKED(IDC_BUTTON_AVL_ADD_BAT, OnBnClickedButtonAvlAddBat)
|
||
ON_BN_CLICKED(IDC_BUTTON_AVL_DEL, OnBnClickedButtonAvlDel)
|
||
ON_BN_CLICKED(IDC_BUTTON_CLEAR, OnBnClickedButtonClear)
|
||
ON_BN_CLICKED(IDC_CHECK_OUT_NAME, OnBnClickedCheckOutName)
|
||
ON_BN_CLICKED(IDC_SVN_UPDATE, OnBnClickedSvnUpdate)
|
||
END_MESSAGE_MAP()
|
||
|
||
|
||
// CFileDirDlg 消息处理程序
|
||
|
||
BOOL CFileDirDlg::OnInitDialog()
|
||
{
|
||
CDialog::OnInitDialog();
|
||
|
||
// 将\“关于...\”菜单项添加到系统菜单中。
|
||
|
||
// IDM_ABOUTBOX 必须在系统命令范围内。
|
||
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
|
||
ASSERT(IDM_ABOUTBOX < 0xF000);
|
||
|
||
CMenu* pSysMenu = GetSystemMenu(FALSE);
|
||
if (pSysMenu != NULL)
|
||
{
|
||
CString strAboutMenu;
|
||
strAboutMenu.LoadString(IDS_ABOUTBOX);
|
||
if (!strAboutMenu.IsEmpty())
|
||
{
|
||
pSysMenu->AppendMenu(MF_SEPARATOR);
|
||
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
|
||
}
|
||
}
|
||
|
||
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
|
||
// 执行此操作
|
||
SetIcon(m_hIcon, TRUE); // 设置大图标
|
||
SetIcon(m_hIcon, FALSE); // 设置小图标
|
||
|
||
// TODO: 在此添加额外的初始化代码
|
||
|
||
CheckDlgButton(IDC_CHECK_NETSTED, BST_CHECKED);
|
||
m_debugWin.SetLimitText(81920);
|
||
acl_msg_open("svn.log", "svn_update");
|
||
|
||
return TRUE; // 除非设置了控件的焦点,否则返回 TRUE
|
||
}
|
||
|
||
void CFileDirDlg::OnSysCommand(UINT nID, LPARAM lParam)
|
||
{
|
||
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
|
||
{
|
||
CAboutDlg dlgAbout;
|
||
dlgAbout.DoModal();
|
||
}
|
||
else
|
||
{
|
||
CDialog::OnSysCommand(nID, lParam);
|
||
}
|
||
}
|
||
|
||
// 如果向对话框添加最小化按钮,则需要下面的代码
|
||
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
|
||
// 这将由框架自动完成。
|
||
|
||
void CFileDirDlg::OnPaint()
|
||
{
|
||
if (IsIconic())
|
||
{
|
||
CPaintDC dc(this); // 用于绘制的设备上下文
|
||
|
||
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
|
||
|
||
// 使图标在工作矩形中居中
|
||
int cxIcon = GetSystemMetrics(SM_CXICON);
|
||
int cyIcon = GetSystemMetrics(SM_CYICON);
|
||
CRect rect;
|
||
GetClientRect(&rect);
|
||
int x = (rect.Width() - cxIcon + 1) / 2;
|
||
int y = (rect.Height() - cyIcon + 1) / 2;
|
||
|
||
// 绘制图标
|
||
dc.DrawIcon(x, y, m_hIcon);
|
||
}
|
||
else
|
||
{
|
||
CDialog::OnPaint();
|
||
}
|
||
}
|
||
|
||
//当用户拖动最小化窗口时系统调用此函数取得光标显示。
|
||
HCURSOR CFileDirDlg::OnQueryDragIcon()
|
||
{
|
||
return static_cast<HCURSOR>(m_hIcon);
|
||
}
|
||
|
||
int CFileDirDlg::GetDirPath(void)
|
||
{
|
||
CString msg;
|
||
|
||
if (m_dirPath.GetLength() == 0) {
|
||
MessageBox(_T("Please input the dir path ..."), _T("Error"));
|
||
return (-1);
|
||
}
|
||
|
||
struct stat sbuf;
|
||
if (stat(m_dirPath.GetString(), &sbuf) < 0) {
|
||
msg.Format("%s no exist!", m_dirPath.GetString());
|
||
MessageBox(msg, "Error");
|
||
return (-1);
|
||
} else if (!S_ISDIR(sbuf.st_mode)) {
|
||
msg.Format("%s is not a directory!", m_dirPath.GetString());
|
||
MessageBox(msg, "Error");
|
||
return (-1);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
void CFileDirDlg::OnTimer(UINT nIDEvent)
|
||
{
|
||
// TODO: 在此添加消息处理程序代码和/或调用默认值
|
||
|
||
CDialog::OnTimer(nIDEvent);
|
||
ScanDir();
|
||
}
|
||
|
||
void CFileDirDlg::OnEnChangeEditPath()
|
||
{
|
||
// TODO: 如果该控件是 RICHEDIT 控件,则它将不会
|
||
// 发送该通知,除非重写 CDialog::OnInitDialog()
|
||
// 函数并调用 CRichEditCtrl().SetEventMask(),
|
||
// 同时将 ENM_CHANGE 标志“或”运算到掩码中。
|
||
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
UpdateData(TRUE);
|
||
}
|
||
|
||
int CFileDirDlg::ScanCallback(ACL_SCAN_DIR * scan, void * ctx)
|
||
{
|
||
CFileDirDlg *pfdd = (CFileDirDlg *) ctx;
|
||
const char *ptr;
|
||
|
||
if (pfdd->m_outName) {
|
||
ptr = acl_scan_dir_file(scan);
|
||
if (ptr && *ptr) {
|
||
CString msg;
|
||
struct acl_stat sbuf;
|
||
|
||
acl_scan_stat(scan, &sbuf);
|
||
msg.Format(">>>file(%s), size=%I64d\r\n", ptr,
|
||
(acl_int64) sbuf.st_size);
|
||
pfdd->DebugWinAppend(msg);
|
||
}
|
||
}
|
||
|
||
if ((acl_scan_dir_nfiles(pfdd->m_pScan)
|
||
+ acl_scan_dir_ndirs(pfdd->m_pScan)) % 100 == 0) {
|
||
pfdd->UpdateInfo();
|
||
pfdd->SetTimer(TIMER_EVENT_USER_100, 10, NULL);
|
||
return (-1); // 暂时停止扫描
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
void CFileDirDlg::ScanDir(void)
|
||
{
|
||
if (acl_scan_dir_end(m_pScan)) {
|
||
ScanClose();
|
||
return;
|
||
}
|
||
|
||
if (acl_scan_dir_size2(m_pScan) < 0) {
|
||
ScanClose();
|
||
return;
|
||
}
|
||
UpdateInfo();
|
||
}
|
||
|
||
// 更新显示信息
|
||
void CFileDirDlg::UpdateInfo(void)
|
||
{
|
||
if (m_pScan == NULL)
|
||
return;
|
||
|
||
CString msg;
|
||
|
||
msg.Format(_T("%I64u MB"), acl_scan_dir_nsize(m_pScan) / MB);
|
||
GetDlgItem(IDC_EDIT_SIZE)->SetWindowText(msg);
|
||
|
||
msg.Format(_T("%d 个"), acl_scan_dir_nfiles(m_pScan));
|
||
GetDlgItem(IDC_EDIT_NFILE)->SetWindowText(msg);
|
||
|
||
msg.Format(_T("%d 个"), acl_scan_dir_ndirs(m_pScan));
|
||
GetDlgItem(IDC_EDIT_NDIR)->SetWindowText(msg);
|
||
}
|
||
|
||
void CFileDirDlg::ScanClose(void)
|
||
{
|
||
KillTimer(TIMER_EVENT_USER_100);
|
||
UpdateInfo();
|
||
acl_scan_dir_close(m_pScan); // 关闭扫描目录对象
|
||
m_pScan = NULL;
|
||
}
|
||
|
||
void CFileDirDlg::OnBnClickedCheckNetsted()
|
||
{
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
UpdateData(TRUE);
|
||
}
|
||
|
||
void CFileDirDlg::OnBnClickedButtonScan()
|
||
{
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
CString msg;
|
||
|
||
if (GetDirPath() < 0)
|
||
return;
|
||
|
||
m_pScan = acl_scan_dir_open(m_dirPath.GetString(), m_nested);
|
||
if (m_pScan == NULL) {
|
||
msg.Format("open dir %s error", m_dirPath.GetString());
|
||
MessageBox(msg, "Error");
|
||
return;
|
||
}
|
||
|
||
// 设置回调函数及回调参数
|
||
acl_scan_dir_ctl(m_pScan, ACL_SCAN_CTL_FN, this->ScanCallback,
|
||
ACL_SCAN_CTL_CTX, this, ACL_SCAN_CTL_END);
|
||
|
||
ScanDir();
|
||
}
|
||
|
||
void CFileDirDlg::OnBnClickedButtonDelete()
|
||
{
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
CString msg;
|
||
|
||
if (GetDirPath() < 0)
|
||
return;
|
||
|
||
msg.Format("Are you sure to delete %s ?", m_dirPath.GetString());
|
||
if (MessageBox(msg, "Warning", MB_YESNO) != IDYES)
|
||
return;
|
||
|
||
CScanDir scan(m_dirPath.GetString(), m_nested);
|
||
|
||
if (scan.BeginRemove() < 0) {
|
||
msg.Format("%s remove error", m_dirPath.GetString());
|
||
MessageBox(msg, "Error");
|
||
return;
|
||
}
|
||
|
||
__int64 size = scan.TotalSize();
|
||
|
||
msg.Format(_T("%I64u MB"), size / MB);
|
||
GetDlgItem(IDC_EDIT_SIZE)->SetWindowText(msg);
|
||
|
||
int n = scan.FileCount();
|
||
msg.Format(_T("%d 个"), n);
|
||
GetDlgItem(IDC_EDIT_NFILE)->SetWindowText(msg);
|
||
|
||
n = scan.DirCount();
|
||
msg.Format(_T("%d 个"), n);
|
||
GetDlgItem(IDC_EDIT_NDIR)->SetWindowText(msg);
|
||
}
|
||
|
||
void CFileDirDlg::OnBnClickedButtonAvlAdd()
|
||
{
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
MY_TYPE *pm, m;
|
||
|
||
if (m_avlName.GetLength() == 0) {
|
||
MessageBox("Please input searching name!", "error");
|
||
GetDlgItem(IDC_EDIT_AVL_NAME)->SetFocus();
|
||
return;
|
||
}
|
||
if (m_avlValue.GetLength() == 0) {
|
||
MessageBox("Please input value!", "error");
|
||
GetDlgItem(IDC_EDIT_AVL_VALUE)->SetFocus();
|
||
return;
|
||
}
|
||
|
||
snprintf(m.name, sizeof(m.name), "%s", m_avlName.GetString());
|
||
pm = (MY_TYPE*) avl_find(&m_avlTree, &m, NULL);
|
||
if (pm != NULL) {
|
||
CString msg;
|
||
|
||
msg.Format("key(%s) already exist, which value is %s",
|
||
m_avlName.GetString(), pm->value);
|
||
MessageBox(msg, "error");
|
||
return;
|
||
}
|
||
|
||
pm = (MY_TYPE*) acl_mycalloc(1, sizeof(MY_TYPE));
|
||
snprintf(pm->name, sizeof(pm->name), "%s", m_avlName.GetString());
|
||
snprintf(pm->value, sizeof(pm->value), "%s", m_avlValue.GetString());
|
||
avl_add(&m_avlTree, pm);
|
||
MessageBox("Add ok!", "ok");
|
||
// m_avlName.Empty();
|
||
m_avlValue.Empty();
|
||
UpdateData(FALSE);
|
||
}
|
||
|
||
void CFileDirDlg::OnBnClickedButtonAvlFind()
|
||
{
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
MY_TYPE m, *ptr;
|
||
CString msg;
|
||
|
||
if (m_avlName.GetLength() == 0) {
|
||
MessageBox("Please input searching name", "error");
|
||
GetDlgItem(IDC_EDIT_AVL_NAME)->SetFocus();
|
||
return;
|
||
}
|
||
|
||
snprintf(m.name, sizeof(m.name), m_avlName.GetString());
|
||
|
||
ptr = (MY_TYPE*) avl_find(&m_avlTree, &m, NULL);
|
||
if (ptr) {
|
||
m_avlValue.Format("%s", ptr->value);
|
||
} else {
|
||
m_avlValue.Empty();
|
||
msg.Format("not find it, name=%s", m.name);
|
||
MessageBox(msg);
|
||
}
|
||
|
||
UpdateData(FALSE);
|
||
}
|
||
|
||
int CFileDirDlg::compare_fn(const void* v1, const void* v2)
|
||
{
|
||
MY_TYPE *m1 = (MY_TYPE*) v1, *m2 = (MY_TYPE*) v2;
|
||
|
||
return (strcmp(m1->name, m2->name));
|
||
}
|
||
|
||
void CFileDirDlg::OnBnClickedButtonWalk()
|
||
{
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
MY_TYPE *next;
|
||
CString msg;
|
||
int n = 0;
|
||
|
||
next = (MY_TYPE*) avl_first(&m_avlTree);
|
||
while (next) {
|
||
msg.Format(">>name(%s), value(%s)\r\n", next->name, next->value);
|
||
DebugWinAppend(msg);
|
||
next = (MY_TYPE*) AVL_NEXT(&m_avlTree, next);
|
||
n++;
|
||
}
|
||
|
||
msg.Format(">>ok, total count is %d\r\n", n);
|
||
DebugWinAppend(msg);
|
||
}
|
||
|
||
void CFileDirDlg::OnEnChangeEditAvlName()
|
||
{
|
||
// TODO: 如果该控件是 RICHEDIT 控件,则它将不会
|
||
// 发送该通知,除非重写 CDialog::OnInitDialog()
|
||
// 函数并调用 CRichEditCtrl().SetEventMask(),
|
||
// 同时将 ENM_CHANGE 标志“或”运算到掩码中。
|
||
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
UpdateData(TRUE);
|
||
}
|
||
|
||
void CFileDirDlg::OnBnClickedButtonTest()
|
||
{
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
avl_node_t *node = (avl_node_t*) acl_mycalloc(1, sizeof(avl_node_t)), *pnode;
|
||
avl_index_t where;
|
||
|
||
where = AVL_MKINDEX(node, 1);
|
||
pnode = AVL_INDEX2NODE(where);
|
||
|
||
CString msg;
|
||
|
||
msg.Format("addr=%x, %x, %d", pnode, node, pnode);
|
||
if (pnode == node) {
|
||
MessageBox("ok, ==");
|
||
MessageBox(msg);
|
||
} else {
|
||
MessageBox("no");
|
||
}
|
||
}
|
||
|
||
void CFileDirDlg::OnEnChangeEditAvlValue()
|
||
{
|
||
// TODO: 如果该控件是 RICHEDIT 控件,则它将不会
|
||
// 发送该通知,除非重写 CDialog::OnInitDialog()
|
||
// 函数并调用 CRichEditCtrl().SetEventMask(),
|
||
// 同时将 ENM_CHANGE 标志“或”运算到掩码中。
|
||
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
UpdateData(TRUE);
|
||
}
|
||
|
||
void CFileDirDlg::OnBnClickedButtonAvlAddBat()
|
||
{
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
MY_TYPE *pm, m;
|
||
int i, n = 0;
|
||
CString msg;
|
||
|
||
for (i = 0; i < 100; i++) {
|
||
snprintf(m.name, sizeof(m.name), "%d", i);
|
||
pm = (MY_TYPE*) avl_find(&m_avlTree, &m, NULL);
|
||
if (pm != NULL) {
|
||
msg.Format(">>key(%s) already exist, value(%s)\r\n",
|
||
pm->name, pm->value);
|
||
DebugWinAppend(msg);
|
||
continue;
|
||
}
|
||
|
||
pm = (MY_TYPE*) acl_mycalloc(1, sizeof(MY_TYPE));
|
||
snprintf(pm->name, sizeof(pm->name), "%d", i);
|
||
snprintf(pm->value, sizeof(pm->value), "value(%d)", i);
|
||
avl_add(&m_avlTree, pm);
|
||
msg.Format(">>add one, key(%s), value(%s)\r\n", pm->name, pm->value);
|
||
DebugWinAppend(msg);
|
||
n++;
|
||
}
|
||
|
||
msg.Format(">>ok, %d records were added\r\n", n);
|
||
DebugWinAppend(msg);
|
||
}
|
||
|
||
void CFileDirDlg::OnBnClickedButtonAvlDel()
|
||
{
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
MY_TYPE m, *pm;
|
||
|
||
if (m_avlName.GetLength() == 0) {
|
||
MessageBox("Please input searching name!", "error");
|
||
GetDlgItem(IDC_EDIT_AVL_NAME)->SetFocus();
|
||
return;
|
||
}
|
||
|
||
snprintf(m.name, sizeof(m.name), "%s", m_avlName.GetString());
|
||
pm = (MY_TYPE*) avl_find(&m_avlTree, &m, NULL);
|
||
if (!pm) {
|
||
MessageBox("not find", "ok");
|
||
} else {
|
||
avl_remove(&m_avlTree, pm);
|
||
MessageBox("Delete ok!", "ok");
|
||
}
|
||
m_avlName.Empty();
|
||
m_avlValue.Empty();
|
||
UpdateData(FALSE);
|
||
}
|
||
|
||
void CFileDirDlg::OnBnClickedButtonClear()
|
||
{
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
m_avlName.Empty();
|
||
m_avlValue.Empty();
|
||
UpdateData(FALSE);
|
||
m_debugWin.SetSel(0, m_debugWin.GetWindowTextLength());
|
||
m_debugWin.ReplaceSel("");
|
||
}
|
||
|
||
void CFileDirDlg::DebugWinAppend(CString& msg)
|
||
{
|
||
m_debugWin.SetSel(m_debugWin.GetWindowTextLength(),
|
||
m_debugWin.GetWindowTextLength());
|
||
m_debugWin.ReplaceSel(msg.GetString());
|
||
}
|
||
|
||
void CFileDirDlg::OnBnClickedCheckOutName()
|
||
{
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
UpdateData(TRUE);
|
||
}
|
||
|
||
void CFileDirDlg::OnBnClickedSvnUpdate()
|
||
{
|
||
// TODO: 在此添加控件通知处理程序代码
|
||
CString msg;
|
||
|
||
if (GetDirPath() < 0)
|
||
return;
|
||
|
||
m_pScan = acl_scan_dir_open(m_dirPath.GetString(), m_nested);
|
||
if (m_pScan == NULL) {
|
||
msg.Format("open dir %s error", m_dirPath.GetString());
|
||
MessageBox(msg, "Error");
|
||
return;
|
||
}
|
||
|
||
// 设置回调函数及回调参数
|
||
acl_scan_dir_ctl(m_pScan, ACL_SCAN_CTL_FN, ScanSvnCallback,
|
||
ACL_SCAN_CTL_CTX, this, ACL_SCAN_CTL_END);
|
||
|
||
ScanSvnDir();
|
||
}
|
||
|
||
int CFileDirDlg::ScanSvnCallback(ACL_SCAN_DIR * scan, void * ctx)
|
||
{
|
||
CFileDirDlg *pfdd = (CFileDirDlg *) ctx;
|
||
|
||
if ((acl_scan_dir_nfiles(pfdd->m_pScan)
|
||
+ acl_scan_dir_ndirs(pfdd->m_pScan)) % 100 == 0)
|
||
{
|
||
pfdd->UpdateInfo();
|
||
pfdd->SetTimer(TIMER_EVENT_USER_100, 10, NULL);
|
||
return (-1); // 暂时停止扫描
|
||
}
|
||
|
||
if (!pfdd->m_outName)
|
||
return 0;
|
||
|
||
const char* filename = acl_scan_dir_file(scan);
|
||
const char* path = acl_scan_dir_path(scan);
|
||
if (!filename || strcasecmp(filename, "entries") || !path)
|
||
return 0;
|
||
|
||
CString filepath;
|
||
filepath.Format("%s/%s", path, filename);
|
||
|
||
if (acl_strrncasecmp(filepath.GetString(),
|
||
".svn/entries", sizeof(".svn/entries") - 1) != 0)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
CString msg;
|
||
struct acl_stat sbuf;
|
||
|
||
acl_assert(path);
|
||
acl_scan_stat(scan, &sbuf);
|
||
msg.Format(">>>file(%s/%s), size=%I64d\r\n",
|
||
path, filename, (acl_int64) sbuf.st_size);
|
||
pfdd->DebugWinAppend(msg);
|
||
return 0;
|
||
}
|
||
|
||
void CFileDirDlg::ScanSvnDir(void)
|
||
{
|
||
if (acl_scan_dir_end(m_pScan)) {
|
||
ScanClose();
|
||
return;
|
||
}
|
||
|
||
if (acl_scan_dir_size2(m_pScan) < 0) {
|
||
ScanClose();
|
||
return;
|
||
}
|
||
UpdateInfo();
|
||
}
|
||
|
||
BOOL CFileDirDlg::UpdateSvn(const char* filepath)
|
||
{
|
||
ssize_t file_size;
|
||
char* buf = acl_vstream_loadfile2(filepath, &file_size);
|
||
if (buf == NULL)
|
||
{
|
||
acl_msg_error("loadfile(%s) error(%s)",
|
||
filepath, acl_last_serror());
|
||
return FALSE;
|
||
}
|
||
|
||
ACL_VSTREAM* fp = acl_vstream_fopen(filepath,
|
||
O_WRONLY | O_BINARY | O_TRUNC, 0700, 4096);
|
||
if (fp == NULL)
|
||
{
|
||
acl_myfree(buf);
|
||
acl_msg_error("fopen(%s) error(%s)",
|
||
filepath, acl_last_serror());
|
||
return FALSE;
|
||
}
|
||
|
||
ACL_VSTRING* vbuf = acl_vstring_alloc(2048);
|
||
const char* ptr = buf;
|
||
const char* old_svn = "svn://192.168.1.231";
|
||
size_t old_npre = strlen(old_svn);
|
||
const char* new_svn = "svn://122.49.0.188";
|
||
size_t new_npre = strlen(new_svn);
|
||
|
||
#define STR acl_vstring_str
|
||
#define LEN ACL_VSTRING_LEN
|
||
|
||
int i = 0;
|
||
while (TRUE)
|
||
{
|
||
// 只需要修改前 10 数据即可
|
||
if (i++ > 10)
|
||
break;
|
||
|
||
// 从缓冲区中获得一行数据
|
||
const ACL_VSTRING* vp = acl_buffer_gets(vbuf, &ptr, strlen(ptr));
|
||
if (vp == NULL)
|
||
break;
|
||
|
||
// 比较前缀是否相等
|
||
if (strncasecmp(old_svn, STR(vp), old_npre) != 0)
|
||
{
|
||
if (acl_vstream_writen(fp, STR(vp), LEN(vp)) == ACL_VSTREAM_EOF)
|
||
{
|
||
acl_msg_error("%s(%d): write error(%s)",
|
||
__FUNCTION__, __LINE__,
|
||
acl_last_serror());
|
||
goto end;
|
||
}
|
||
ACL_VSTRING_RESET(vbuf);
|
||
continue;
|
||
}
|
||
|
||
// 写入新的前缀
|
||
if (acl_vstream_writen(fp, new_svn, new_npre) == ACL_VSTREAM_EOF)
|
||
{
|
||
acl_msg_error("%s(%d): write error(%s)",
|
||
__FUNCTION__, __LINE__, acl_last_serror());
|
||
goto end;
|
||
}
|
||
|
||
const char* pleft = STR(vp) + old_npre;
|
||
if (*pleft == 0)
|
||
{
|
||
ACL_VSTRING_RESET(vbuf);
|
||
continue;
|
||
}
|
||
|
||
// 写入该行数据中剩余部分
|
||
if (acl_vstream_writen(fp, pleft, strlen(pleft)) == ACL_VSTREAM_EOF)
|
||
{
|
||
acl_msg_error("%s(%d): write error(%s)",
|
||
__FUNCTION__, __LINE__, acl_last_serror());
|
||
goto end;
|
||
}
|
||
ACL_VSTRING_RESET(vbuf);
|
||
}
|
||
|
||
ssize_t nleft = (ssize_t) (file_size - (ptr - buf));
|
||
if (*ptr && nleft > 0)
|
||
{
|
||
if (acl_vstream_writen(fp, ptr, nleft) == ACL_VSTREAM_EOF)
|
||
acl_msg_error("%s(%d): write nleft(%d) error(%s)",
|
||
__FUNCTION__, __LINE__,
|
||
(int) nleft, acl_last_serror());
|
||
}
|
||
|
||
end:
|
||
acl_vstring_free(vbuf);
|
||
acl_vstream_fclose(fp);
|
||
acl_myfree(buf);
|
||
return TRUE;
|
||
} |