#define UNICODE #if defined(UNICODE) && !defined(_UNICODE) #define _UNICODE #elif defined(_UNICODE) && !defined(UNICODE) #define UNICODE #endif #include #include #include #include #include #include "base64/libbase64.h" #include "md5/md5.h" #include "sha1/sha1.h" #include "url/url.h" #include "parson/parson.h" #include "resources.h" #include "timelib/timelib.h" #define MIN_WIDTH 600 #define MIN_HEIGHT 500 #define FRAME_PADDING 3 #define ROW_PADDING 10 #define TOP_ROW_HEIGHT 26 #define TOP_ITEM_WIDTH 60 #define TOP_ITEM_SPACE 6 #define BOTTOM_ROW_HEIGHT 26 #define BOTTOM_ITEM_WIDTH 80 #define BOTTOM_ITEM_SPACE 10 /* Declare Windows procedure */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); /* Make the class name into a global variable */ TCHAR szClassName[ ] = _T("CodeBlocksWindowsApp"); HINSTANCE gInst; HMENU gMenu; HWND gWindows[256] = {}; WORD gLastMenu = IDM_BASE64; WORD gLastFocus = IDC_EDIT; int gUTF8 = 1; timelib_tzinfo *gTimeZoneInfo; static BOOL RegWC(HINSTANCE inst); static void OnCreate(HWND hwnd); static void OnSizing(HWND hwnd, WPARAM fwSide, LPRECT lpRect); static void OnSize(HWND hwnd); static void OnMenuClicked(HWND hwnd, WORD id); static void OnAccelerator(HWND hwnd, WORD id); static void OnClicked(HWND hwnd, WORD id); static void ButtonOnClicked(HWND hwnd, WORD id); static char *wchar_to_utf8(const TCHAR *in, int in_len, int *out_len); static TCHAR *utf8_to_wchar(const char *in, int in_len, int *out_len); static char *wchar_to_acp(const TCHAR *in, int in_len, int *out_len); static TCHAR *acp_to_wchar(const char *in, int in_len, int *out_len); static char *nl_unix2win(const char *in, char *out); static TCHAR *base64_encode_string(const TCHAR *in, int in_len, int *out_len, int utf8); static TCHAR *base64_decode_string(const TCHAR *in, int in_len, int *out_len, int utf8); static TCHAR *url_encode_string(const TCHAR *in, int in_len, int *out_len, int utf8); static TCHAR *url_decode_string(const TCHAR *in, int in_len, int *out_len, int utf8); static TCHAR *md5_string(const TCHAR *in, int in_len, int *out_len, int utf8); static TCHAR *sha1_string(const TCHAR *in, int in_len, int *out_len, int utf8); static TCHAR *json_format(const TCHAR *in, int in_len, int *out_len, int utf8); static TCHAR *json_minify(const TCHAR *in, int in_len, int *out_len, int utf8); static TCHAR *time_convert_to_string(const TCHAR *in, int in_len, int *out_len); static TCHAR *string_convert_to_time(const TCHAR *in, int in_len, int *out_len); static timelib_tzinfo *my_date_parse_tzfile_wrapper(char *formal_tzname, const timelib_tzdb *tzdb); int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ HACCEL hAccel; int tziCode; gInst = hThisInstance; /* Register the window class, and if it fails quit the program */ if (!RegWC (hThisInstance)) return 0; gMenu = LoadMenu(hThisInstance, MAKEINTRESOURCE(IDM_MAIN)); hAccel = LoadAccelerators(hThisInstance, MAKEINTRESOURCE(IDD_ACCEL)); /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ _T("常用编解码工具"), /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ MIN_WIDTH, /* The programs width */ MIN_HEIGHT, /* and height in pixels */ HWND_DESKTOP, /* The window is a child-window to desktop */ gMenu, /* No menu */ hThisInstance, /* Program Instance handler */ NULL /* No Window Creation data */ ); gWindows[0] = hwnd; /* Make the window visible on the screen */ ShowWindow (hwnd, nCmdShow); gTimeZoneInfo = timelib_parse_tzfile("Etc/GMT-8", timelib_builtin_db(), &tziCode); /* Run the message loop. It will run until GetMessage() returns 0 */ while (GetMessage (&messages, NULL, 0, 0)) { if (TranslateAccelerator(hwnd, hAccel, &messages) == 0) { /* Translate virtual-key messages into character messages */ TranslateMessage(&messages); } /* Send message to WindowProcedure */ DispatchMessage(&messages); } /* The program return-value is 0 - The value that PostQuitMessage() gave */ return messages.wParam; } static BOOL RegWC(HINSTANCE inst) { WNDCLASSEX wincl; /* Data structure for the windowclass */ /* The Window structure */ wincl.hInstance = inst; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (inst, MAKEINTRESOURCE(IDI_APP)); wincl.hIconSm = LoadIcon (inst, MAKEINTRESOURCE(IDI_APP)); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default colour as the background of the window */ wincl.hbrBackground = (HBRUSH) COLOR_WINDOW; /* Register the window class, and if it fails quit the program */ return RegisterClassEx (&wincl); } /* This function is called by the Windows function DispatchMessage() */ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { WORD wh, wl; switch (message) /* handle the messages */ { case WM_CREATE: OnCreate(hwnd); break; case WM_SIZING: OnSizing(hwnd, wParam, (LPRECT)lParam); return TRUE; case WM_SIZE: OnSize(hwnd); break; case WM_COMMAND: wh = HIWORD(wParam); //message wl = LOWORD(wParam); //control id if (lParam == (LPARAM)NULL) { if (wh == 0) { OnMenuClicked(hwnd, wl); } else if (wh == 1) { OnAccelerator(hwnd, wl); } } else if (wh == BN_CLICKED) { OnClicked(hwnd, wl); } break; case WM_NOTIFY: break; case WM_DESTROY: PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; } static void OnCreate(HWND hwnd) { RECT rect; long topRowL, topRowT, bottomRowL, bottomRowT, bodyL, bodyT, bodyW, bodyH; HFONT font; GetClientRect(hwnd, &rect); topRowL = bottomRowL = bodyL = rect.left + FRAME_PADDING; topRowT = rect.top + FRAME_PADDING; bottomRowT = rect.bottom - FRAME_PADDING - BOTTOM_ROW_HEIGHT; bodyT = topRowT + TOP_ROW_HEIGHT + ROW_PADDING; bodyW = rect.right - rect.left - FRAME_PADDING - FRAME_PADDING; bodyH = bottomRowT - ROW_PADDING - bodyT; gWindows[IDC_LABEL] = CreateWindowEx(0, _T("STATIC"), _T("编码:"), WS_CHILD | WS_VISIBLE, topRowL, topRowT+4, TOP_ITEM_WIDTH, TOP_ROW_HEIGHT-4, hwnd, (HMENU)IDC_LABEL, gInst, NULL); gWindows[IDC_UTF8] = CreateWindowEx(0, _T("BUTTON"), _T("UTF8"), WS_CHILD | BS_RADIOBUTTON | WS_VISIBLE, topRowL + (TOP_ITEM_WIDTH + TOP_ITEM_SPACE), topRowT, TOP_ITEM_WIDTH, TOP_ROW_HEIGHT, hwnd, (HMENU)IDC_UTF8, gInst, NULL); gWindows[IDC_GBK] = CreateWindowEx(0, _T("BUTTON"), _T("GBK"), WS_CHILD | BS_RADIOBUTTON | WS_VISIBLE, topRowL + (TOP_ITEM_WIDTH + TOP_ITEM_SPACE)*2, topRowT, TOP_ITEM_WIDTH, TOP_ROW_HEIGHT, hwnd, (HMENU)IDC_GBK, gInst, NULL); gWindows[IDC_EDIT] = CreateWindowEx(0, _T("EDIT"), NULL, WS_CHILD | WS_VSCROLL | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN | ES_AUTOVSCROLL, bodyL, bodyT, bodyW, bodyH, hwnd, (HMENU)IDC_EDIT, gInst, NULL); gWindows[IDC_ENC] = CreateWindowEx(0, _T("BUTTON"), _T("编码"), WS_CHILD | WS_VISIBLE, bottomRowL, bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, hwnd, (HMENU)IDC_ENC, gInst, NULL); gWindows[IDC_DEC] = CreateWindowEx(0, _T("BUTTON"), _T("解码"), WS_CHILD | WS_VISIBLE, bottomRowL + (BOTTOM_ITEM_WIDTH + BOTTOM_ITEM_SPACE), bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, hwnd, (HMENU)IDC_DEC, gInst, NULL); gWindows[IDC_FORMAT] = CreateWindowEx(0, _T("BUTTON"), _T("格式化"), WS_CHILD, bottomRowL, bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, hwnd, (HMENU)IDC_FORMAT, gInst, NULL); gWindows[IDC_MINIFY] = CreateWindowEx(0, _T("BUTTON"), _T("压缩"), WS_CHILD, bottomRowL + (BOTTOM_ITEM_WIDTH + BOTTOM_ITEM_SPACE), bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, hwnd, (HMENU)IDC_MINIFY, gInst, NULL); gWindows[IDC_TIME2STR] = CreateWindowEx(0, _T("BUTTON"), _T("转字符串"), WS_CHILD, bottomRowL, bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, hwnd, (HMENU)IDC_TIME2STR, gInst, NULL); gWindows[IDC_STR2TIME] = CreateWindowEx(0, _T("BUTTON"), _T("转时间戳"), WS_CHILD, bottomRowL + (BOTTOM_ITEM_WIDTH + BOTTOM_ITEM_SPACE), bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, hwnd, (HMENU)IDC_STR2TIME, gInst, NULL); font = CreateFont(0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, _T("宋体")); if (font == NULL) { MessageBox(hwnd, _T("系统未安装宋体!"), _T("提示"), MB_OK); } else { SendMessage(gWindows[IDC_LABEL], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0)); SendMessage(gWindows[IDC_UTF8], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0)); SendMessage(gWindows[IDC_GBK], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0)); SendMessage(gWindows[IDC_EDIT], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0)); SendMessage(gWindows[IDC_ENC], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0)); SendMessage(gWindows[IDC_DEC], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0)); SendMessage(gWindows[IDC_FORMAT], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0)); SendMessage(gWindows[IDC_MINIFY], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0)); SendMessage(gWindows[IDC_TIME2STR], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0)); SendMessage(gWindows[IDC_STR2TIME], WM_SETFONT, (WPARAM)font, MAKELPARAM(FALSE, 0)); } CheckRadioButton(hwnd, IDC_UTF8, IDC_GBK, IDC_UTF8); SendMessage(gWindows[IDC_EDIT], EM_SETLIMITTEXT, (WPARAM)0x7FFFFFFE, 0); SetFocus(gWindows[IDC_EDIT]); } static void OnSizing(HWND hwnd, WPARAM fsSide, LPRECT lpRect) { long width, height; width = lpRect->right - lpRect->left; height = lpRect->bottom - lpRect->top; if (width < MIN_WIDTH) { if (fsSide & WMSZ_LEFT || fsSide & WMSZ_TOPLEFT || fsSide & WMSZ_BOTTOMLEFT) { lpRect->left = lpRect->right - MIN_WIDTH; } else if (fsSide & WMSZ_RIGHT || fsSide & WMSZ_TOPRIGHT || fsSide & WMSZ_BOTTOMRIGHT) { lpRect->right = lpRect->left + MIN_WIDTH; } } if (height < MIN_HEIGHT) { if (fsSide & WMSZ_TOP || fsSide & WMSZ_TOPLEFT || fsSide & WMSZ_TOPRIGHT) { lpRect->top = lpRect->bottom - MIN_HEIGHT; } else if (fsSide & WMSZ_BOTTOM || fsSide & WMSZ_BOTTOMLEFT || fsSide & WMSZ_BOTTOMRIGHT) { lpRect->bottom = lpRect->top + MIN_HEIGHT; } } } static void OnSize(HWND hwnd) { RECT rect = {}; long topRowT, bottomRowL, bottomRowT, bodyL, bodyT, bodyW, bodyH; GetClientRect(hwnd, &rect); bottomRowL = bodyL = rect.left + FRAME_PADDING; topRowT = rect.top + FRAME_PADDING; bottomRowT = rect.bottom - FRAME_PADDING - BOTTOM_ROW_HEIGHT; bodyT = topRowT + TOP_ROW_HEIGHT + ROW_PADDING; bodyW = rect.right - rect.left - FRAME_PADDING - FRAME_PADDING; bodyH = bottomRowT - ROW_PADDING - bodyT; MoveWindow(gWindows[IDC_ENC], bottomRowL, bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, TRUE); MoveWindow(gWindows[IDC_DEC], bottomRowL + (BOTTOM_ITEM_WIDTH + BOTTOM_ITEM_SPACE), bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, TRUE); MoveWindow(gWindows[IDC_FORMAT], bottomRowL, bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, TRUE); MoveWindow(gWindows[IDC_MINIFY], bottomRowL + (BOTTOM_ITEM_WIDTH + BOTTOM_ITEM_SPACE), bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, TRUE); MoveWindow(gWindows[IDC_TIME2STR], bottomRowL, bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, TRUE); MoveWindow(gWindows[IDC_STR2TIME], bottomRowL + (BOTTOM_ITEM_WIDTH + BOTTOM_ITEM_SPACE), bottomRowT, BOTTOM_ITEM_WIDTH, BOTTOM_ROW_HEIGHT, TRUE); MoveWindow(gWindows[IDC_EDIT], bodyL, bodyT, bodyW, bodyH, TRUE); } static void OnMenuClicked(HWND hwnd, WORD id) { if (id == IDM_ABOUT) { MessageBox(hwnd, _T("快捷键\r\nCtrl + A: 全选\r\nCtrl + Q: 退出\r\nCtrl + F: 切换焦点\r\nCtrl + T: 切换UTF-8\r\nCtrl + G: 切换GBK\r\n[Weicky 2019]"), _T("提示"), MB_OK); return; } SetMenuDefaultItem(gMenu, id, FALSE); EnableWindow(gWindows[IDC_UTF8], id == IDM_TIME ? FALSE : TRUE); EnableWindow(gWindows[IDC_GBK], id == IDM_JSON || id == IDM_TIME ? FALSE : TRUE); ShowWindow(gWindows[IDC_ENC], id == IDM_BASE64 || id == IDM_URL || id == IDM_MD5 || id == IDM_SHA1 ? SW_SHOW : SW_HIDE); ShowWindow(gWindows[IDC_DEC], id == IDM_BASE64 || id == IDM_URL ? SW_SHOW : SW_HIDE); ShowWindow(gWindows[IDC_FORMAT], id == IDM_JSON ? SW_SHOW : SW_HIDE); ShowWindow(gWindows[IDC_MINIFY], id == IDM_JSON ? SW_SHOW : SW_HIDE); ShowWindow(gWindows[IDC_TIME2STR], id == IDM_TIME ? SW_SHOW : SW_HIDE); ShowWindow(gWindows[IDC_STR2TIME], id == IDM_TIME ? SW_SHOW : SW_HIDE); if (id == IDM_JSON) { CheckRadioButton(hwnd, IDC_UTF8, IDC_GBK, IDC_UTF8); } if (id == IDM_TIME) { char ts[32] = ""; TCHAR *wts; int wts_len; sprintf(ts, "%ld", time(NULL)); wts = acp_to_wchar(ts, strlen(ts), &wts_len); SetWindowText(gWindows[IDC_EDIT], wts); free(wts); } DrawMenuBar(gWindows[0]); gLastMenu = id; } static void OnAccelerator(HWND hwnd, WORD id) { switch (id) { case IDD_SELECT: //ctrl + A SendMessage(gWindows[IDC_EDIT], EM_SETSEL, (WPARAM)0, (LPARAM)-1); break; case IDD_QUIT: //ctrl + Q if (MessageBox(hwnd, _T("确定要退出吗?"), _T("提示"), MB_YESNO) == IDYES) { DestroyWindow(hwnd); } break; case IDD_FOCUS: //ctrl + T while (1) { gLastFocus = gLastFocus == IDC_STR2TIME ? IDC_EDIT : gLastFocus + 1; if (gLastFocus == IDC_LABEL || gLastFocus == IDC_UTF8 || gLastFocus == IDC_GBK || IsWindowEnabled(gWindows[gLastFocus]) == FALSE || IsWindowVisible(gWindows[gLastFocus]) == FALSE) { continue; } SetFocus(gWindows[gLastFocus]); break; } break; case IDD_UTF8: if (IsWindowEnabled(gWindows[IDC_UTF8]) == TRUE) { CheckRadioButton(hwnd, IDC_UTF8, IDC_GBK, IDC_UTF8); } break; case IDD_GBK: if (IsWindowEnabled(gWindows[IDC_GBK]) == TRUE) { CheckRadioButton(hwnd, IDC_UTF8, IDC_GBK, IDC_GBK); } break; } } static void OnClicked(HWND hwnd, WORD id) { switch (id) { case IDC_UTF8: CheckRadioButton(hwnd, IDC_UTF8, IDC_GBK, IDC_UTF8); gUTF8 = 1; break; case IDC_GBK: CheckRadioButton(hwnd, IDC_UTF8, IDC_GBK, IDC_GBK); gUTF8 = 0; break; case IDC_ENC: ButtonOnClicked(hwnd, id); break; case IDC_DEC: ButtonOnClicked(hwnd, id); break; case IDC_FORMAT: ButtonOnClicked(hwnd, id); break; case IDC_MINIFY: ButtonOnClicked(hwnd, id); break; case IDC_TIME2STR: ButtonOnClicked(hwnd, id); break; case IDC_STR2TIME: ButtonOnClicked(hwnd, id); break; } } static void ButtonOnClicked(HWND hwnd, WORD id) { TCHAR *input, *output; int inputLen, outputLen; inputLen = GetWindowTextLength(gWindows[IDC_EDIT]); if (inputLen) { input = (TCHAR *)calloc(inputLen + 1, sizeof(TCHAR)); GetWindowText(gWindows[IDC_EDIT], input, inputLen + 1); switch (gLastMenu) { case IDM_BASE64: if (id == IDC_ENC) { output = base64_encode_string(input, inputLen, &outputLen, gUTF8); } else if (id == IDC_DEC) { output = base64_decode_string(input, inputLen, &outputLen, gUTF8); } else { return; } break; case IDM_URL: if (id == IDC_ENC) { output = url_encode_string(input, inputLen, &outputLen, gUTF8); } else if (id == IDC_DEC) { output = url_decode_string(input, inputLen, &outputLen, gUTF8); } else { return; } break; case IDM_MD5: output = md5_string(input, inputLen, &outputLen, gUTF8); break; case IDM_SHA1: output = sha1_string(input, inputLen, &outputLen, gUTF8); break; case IDM_JSON: if (id == IDC_FORMAT) { output = json_format(input, inputLen, &outputLen, gUTF8); } else if (id == IDC_MINIFY) { output = json_minify(input, inputLen, &outputLen, gUTF8); } else { return; } break; case IDM_TIME: if (id == IDC_TIME2STR) { output = time_convert_to_string(input, inputLen, &outputLen); } else if (id == IDC_STR2TIME) { output = string_convert_to_time(input, inputLen, &outputLen); } else { return; } break; } //输出&清理 SetWindowText(gWindows[IDC_EDIT], output); free(output); free(input); } } static char *nl_unix2win(const char *in, char *out) { char *cpy, c; cpy = out; while ((c = *in++)) { if (c == '\r' && *in == '\n') { *cpy++ = c; *cpy++ = *in++; } else if (c == '\n') { *cpy++ = '\r'; } *cpy++ = c; } return out; } static char *wchar_to_utf8(const TCHAR *in, int in_len, int *out_len) { char *out; *out_len = WideCharToMultiByte(CP_UTF8, 0, in, in_len, NULL, 0, NULL, NULL); if (*out_len == 0) { return NULL; } out = (char *)calloc(*out_len + 1, 1); WideCharToMultiByte(CP_UTF8, 0, in, in_len, out, *out_len, NULL, NULL); return out; } static TCHAR *utf8_to_wchar(const char *in, int in_len, int *out_len) { TCHAR *out; *out_len = MultiByteToWideChar(CP_UTF8, 0, in, in_len, NULL, 0); if (*out_len == 0) { return NULL; } out = (TCHAR *)calloc((*out_len + 1) * sizeof(TCHAR), 1); MultiByteToWideChar(CP_UTF8, 0, in, in_len, out, *out_len); return out; } static char *wchar_to_acp(const TCHAR *in, int in_len, int *out_len) { char *out; *out_len = WideCharToMultiByte(CP_ACP, 0, in, in_len, NULL, 0, NULL, NULL); if (*out_len == 0) { return NULL; } out = (char *)calloc(*out_len + 1, 1); WideCharToMultiByte(CP_ACP, 0, in, in_len, out, *out_len, NULL, NULL); return out; } static TCHAR *acp_to_wchar(const char *in, int in_len, int *out_len) { TCHAR *out; *out_len = MultiByteToWideChar(CP_ACP, 0, in, in_len, NULL, 0); if (*out_len == 0) { return NULL; } out = (TCHAR *)calloc((*out_len + 1) * sizeof(TCHAR), 1); MultiByteToWideChar(CP_ACP, 0, in, in_len, out, *out_len); return out; } static TCHAR *base64_encode_string(const TCHAR *in, int in_len, int *out_len, int utf8) { char *cpy, *res; int cpy_len, res_len; TCHAR *out; if (utf8) { cpy = wchar_to_utf8(in, in_len, &cpy_len); } else { cpy = wchar_to_acp(in, in_len, &cpy_len); } res_len = cpy_len * 3; res = (char *)calloc(res_len + 1, 1); base64_encode(cpy, cpy_len, res, (size_t *)&res_len, 0); free(cpy); if (utf8) { out = utf8_to_wchar(res, res_len, out_len); } else { out = acp_to_wchar(res, res_len, out_len); } free(res); return out; } static TCHAR *base64_decode_string(const TCHAR *in, int in_len, int *out_len, int utf8) { char *cpy, *res; int cpy_len, res_len; TCHAR *out; if (utf8) { cpy = wchar_to_utf8(in, in_len, &cpy_len); } else { cpy = wchar_to_acp(in, in_len, &cpy_len); } res_len = cpy_len * 3; res = (char *)calloc(res_len + 1, 1); base64_decode(cpy, cpy_len, res, (size_t *)&res_len, 0); free(cpy); if (utf8) { out = utf8_to_wchar(res, res_len, out_len); } else { out = acp_to_wchar(res, res_len, out_len); } free(res); return out; } static TCHAR *url_encode_string(const TCHAR *in, int in_len, int *out_len, int utf8) { char *cpy, *res; int cpy_len, res_len; TCHAR *out; if (utf8) { cpy = wchar_to_utf8(in, in_len, &cpy_len); } else { cpy = wchar_to_acp(in, in_len, &cpy_len); } res_len = cpy_len * 3; res = (char *)calloc(res_len + 1, 1); url_encode(cpy, cpy_len, res, (size_t *)&res_len); free(cpy); if (utf8) { out = utf8_to_wchar(res, res_len, out_len); } else { out = acp_to_wchar(res, res_len, out_len); } free(res); return out; } static TCHAR *url_decode_string(const TCHAR *in, int in_len, int *out_len, int utf8) { char *cpy, *res; int cpy_len, res_len; TCHAR *out; if (utf8) { cpy = wchar_to_utf8(in, in_len, &cpy_len); } else { cpy = wchar_to_acp(in, in_len, &cpy_len); } res_len = cpy_len * 3; res = (char *)calloc(res_len + 1, 1); url_decode(cpy, cpy_len, res, (size_t *)&res_len); free(cpy); if (utf8) { out = utf8_to_wchar(res, res_len, out_len); } else { out = acp_to_wchar(res, res_len, out_len); } free(res); return out; } static TCHAR *md5_string(const TCHAR *in, int in_len, int *out_len, int utf8) { char *cpy, *res; int cpy_len, res_len; TCHAR *out; if (utf8) { cpy = wchar_to_utf8(in, in_len, &cpy_len); } else { cpy = wchar_to_acp(in, in_len, &cpy_len); } res_len = 32; res = (char *)calloc(res_len + 1, 1); md5(cpy, cpy_len, res); free(cpy); if (utf8) { out = utf8_to_wchar(res, res_len, out_len); } else { out = acp_to_wchar(res, res_len, out_len); } free(res); return out; } static TCHAR *sha1_string(const TCHAR *in, int in_len, int *out_len, int utf8) { char *cpy, *res; int cpy_len, res_len; TCHAR *out; if (utf8) { cpy = wchar_to_utf8(in, in_len, &cpy_len); } else { cpy = wchar_to_acp(in, in_len, &cpy_len); } res_len = 40; res = (char *)calloc(res_len + 1, 1); sha1(cpy, cpy_len, res); free(cpy); if (utf8) { out = utf8_to_wchar(res, res_len, out_len); } else { out = acp_to_wchar(res, res_len, out_len); } free(res); return out; } static TCHAR *json_format(const TCHAR *in, int in_len, int *out_len, int utf8) { char *cpy, *json, *json_cpy; int cpy_len; JSON_Value *obj; TCHAR *out; if (utf8) { cpy = wchar_to_utf8(in, in_len, &cpy_len); } else { cpy = wchar_to_acp(in, in_len, &cpy_len); } obj = json_parse_string_with_comments(cpy); free(cpy); if (obj == NULL) { *out_len = 5; out = (TCHAR *)calloc(*out_len, sizeof(TCHAR)); wcscpy(out, _T("null")); } else { json = json_serialize_to_string_pretty(obj); json_value_free(obj); json_cpy = (char *)calloc(strlen(json) * 2 + 1, 1); nl_unix2win(json, json_cpy); json_free_serialized_string(json); out = utf8_to_wchar(json_cpy, strlen(json_cpy), out_len); free(json_cpy); } return out; } static TCHAR *json_minify(const TCHAR *in, int in_len, int *out_len, int utf8) { char *cpy, *json, *json_cpy; int cpy_len; JSON_Value *obj; TCHAR *out; if (utf8) { cpy = wchar_to_utf8(in, in_len, &cpy_len); } else { cpy = wchar_to_acp(in, in_len, &cpy_len); } obj = json_parse_string_with_comments(cpy); free(cpy); if (obj == NULL) { *out_len = 5; out = (TCHAR *)calloc(*out_len, sizeof(TCHAR)); wcscpy(out, _T("null")); } else { json = json_serialize_to_string(obj); json_value_free(obj); json_cpy = (char *)calloc(strlen(json) * 2 + 1, 1); nl_unix2win(json, json_cpy); json_free_serialized_string(json); out = utf8_to_wchar(json_cpy, strlen(json_cpy), out_len); free(json_cpy); } return out; } static TCHAR *time_convert_to_string(const TCHAR *in, int in_len, int *out_len) { char *cpy, res[32] = ""; int cpy_len; time_t ts; TCHAR *out; timelib_time *t; //wchar*转int cpy = wchar_to_acp(in, in_len, &cpy_len); ts = (time_t)atoi(cpy); free(cpy); //int转timelib_time(struct) t = timelib_time_ctor(); t->tz_info = gTimeZoneInfo; t->zone_type = TIMELIB_ZONETYPE_ID; timelib_unixtime2local(t, ts); //timelib_time转char* sprintf(res, "%ld-%02ld-%02ld %02ld:%02ld:%02ld", (long)t->y, (long)t->m, (long)t->d, (long)t->h, (long)t->i, (long)t->s); timelib_time_dtor(t); //char*转wchar* out = acp_to_wchar(res, strlen(res), out_len); return out; } static TCHAR *string_convert_to_time(const TCHAR *in, int in_len, int *out_len) { char *cpy, res[32] = ""; int cpy_len, error1, error2; int64_t ts; TCHAR *out; timelib_time *t, *now; timelib_error_container *error; //wchar*转char* cpy = wchar_to_acp(in, in_len, &cpy_len); ts = (time_t)atoi(cpy); //char*转timelib_time(struct)再转int64_t now = timelib_time_ctor(); now->tz_info = gTimeZoneInfo; now->zone_type = TIMELIB_ZONETYPE_ID; timelib_unixtime2local(now, time(NULL)); t = timelib_strtotime(cpy, strlen(cpy), &error, timelib_builtin_db(), (timelib_tz_get_wrapper)my_date_parse_tzfile_wrapper); error1 = error->error_count; timelib_error_container_dtor(error); timelib_fill_holes(t, now, TIMELIB_NO_CLONE); timelib_update_ts(t, gTimeZoneInfo); ts = (int64_t)timelib_date_to_int(t, &error2); timelib_time_dtor(now); timelib_time_dtor(t); free(cpy); //将int64_t转为char* if (error1 || error2) { *out_len = in_len; return in; } else { sprintf(res, "%ld", (long)ts); } //将char*转为TCHAR* out = acp_to_wchar(res, strlen(res), out_len); return out; } static timelib_tzinfo *my_date_parse_tzfile_wrapper(char *formal_tzname, const timelib_tzdb *tzdb) { return gTimeZoneInfo; }