diff options
author | dartraiden <wowemuh@gmail.com> | 2023-01-02 21:10:29 +0300 |
---|---|---|
committer | dartraiden <wowemuh@gmail.com> | 2023-01-02 21:10:29 +0300 |
commit | 1979fd80424d16b2e489f9b57d01d9c7811d25a2 (patch) | |
tree | 960d42c5fe4a51f0fe2850bea91256e226bce221 /include | |
parent | adfbbb217d4f4a05acf198755f219a5223d31c27 (diff) |
Update copyrights
Diffstat (limited to 'include')
54 files changed, 7086 insertions, 7086 deletions
diff --git a/include/chat_resource.h b/include/chat_resource.h index 8f4a2c1c56..fc31071881 100644 --- a/include/chat_resource.h +++ b/include/chat_resource.h @@ -1,36 +1,36 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-08 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#define IDC_SRMM_COLOR 3001 -#define IDC_SRMM_BKGCOLOR 3002 -#define IDC_SRMM_BOLD 3003 -#define IDC_SRMM_ITALICS 3004 -#define IDC_SRMM_UNDERLINE 3005 -#define IDC_SRMM_FILTER 3006 -#define IDC_SRMM_CHANMGR 3007 -#define IDC_SRMM_SHOWNICKLIST 3008 -#define IDC_SRMM_HISTORY 3009 -#define IDC_SRMM_NICKLIST 3010 -#define IDC_SRMM_LOG 3011 -#define IDC_SRMM_MESSAGE 3012 +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-08 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#define IDC_SRMM_COLOR 3001
+#define IDC_SRMM_BKGCOLOR 3002
+#define IDC_SRMM_BOLD 3003
+#define IDC_SRMM_ITALICS 3004
+#define IDC_SRMM_UNDERLINE 3005
+#define IDC_SRMM_FILTER 3006
+#define IDC_SRMM_CHANMGR 3007
+#define IDC_SRMM_SHOWNICKLIST 3008
+#define IDC_SRMM_HISTORY 3009
+#define IDC_SRMM_NICKLIST 3010
+#define IDC_SRMM_LOG 3011
+#define IDC_SRMM_MESSAGE 3012
diff --git a/include/delphi/m_crypto.inc b/include/delphi/m_crypto.inc index 83dbb60d5a..cccc5baea0 100644 --- a/include/delphi/m_crypto.inc +++ b/include/delphi/m_crypto.inc @@ -1,7 +1,7 @@ {
Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_avatars.h b/include/m_avatars.h index 72e8fe9d82..f27a4baf9d 100644 --- a/include/m_avatars.h +++ b/include/m_avatars.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-12 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_awaymsg.h b/include/m_awaymsg.h index becbb9107a..ce54edd711 100644 --- a/include/m_awaymsg.h +++ b/include/m_awaymsg.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_button.h b/include/m_button.h index 3e647ca1ad..222feafc86 100644 --- a/include/m_button.h +++ b/include/m_button.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_button_int.h b/include/m_button_int.h index 4b6996c961..8dd4a7dbe5 100644 --- a/include/m_button_int.h +++ b/include/m_button_int.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_chat_int.h b/include/m_chat_int.h index 31e2163d4e..135be0f7f8 100644 --- a/include/m_chat_int.h +++ b/include/m_chat_int.h @@ -2,7 +2,7 @@ Chat module interface for Miranda NG
-Copyright (c) 2014-22 George Hazan
+Copyright (c) 2014-23 George Hazan
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/include/m_clc.h b/include/m_clc.h index 3fbb1096cc..23c139cd76 100644 --- a/include/m_clc.h +++ b/include/m_clc.h @@ -1,282 +1,282 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-08 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef M_CLC_H__ -#define M_CLC_H__ 1 - -#define CLISTCONTROL_CLASS "CListControl" -#define CLISTCONTROL_CLASSW L"CListControl" - -//styles -#define CLS_MANUALUPDATE 0x0001 //todo -#define CLS_SHOWHIDDEN 0x0002 -#define CLS_HIDEOFFLINE 0x0004 //hides all offline users -#define CLS_CHECKBOXES 0x0008 -#define CLS_MULTICOLUMN 0x0010 //not true multi-column, just for ignore/vis options -#define CLS_HIDEEMPTYGROUPS 0x0020 //note: this flag will be spontaneously removed if the 'new subgroup' menu item is clicked, for obvious reasons -#define CLS_USEGROUPS 0x0040 -#define CLS_NOHIDEOFFLINE 0x0080 //overrides CLS_HIDEOFFLINE and the per-group hideoffline setting -#define CLS_GREYALTERNATE 0x0100 //make every other line slightly grey -#define CLS_GROUPCHECKBOXES 0x0200 //put checkboxes on groups too (managed by CLC) -#define CLS_CONTACTLIST 0x0400 //this control will be the main contact list (v. 0.3.4.3+ 2004/11/02) - -#define CLS_EX_DISABLEDRAGDROP 0x00000001 -#define CLS_EX_EDITLABELS 0x00000002 -#define CLS_EX_SHOWSELALWAYS 0x00000004 -#define CLS_EX_TRACKSELECT 0x00000008 -#define CLS_EX_SHOWGROUPCOUNTS 0x00000010 -#define CLS_EX_DIVIDERONOFF 0x00000020 -#define CLS_EX_HIDECOUNTSWHENEMPTY 0x00000040 -#define CLS_EX_NOTRANSLUCENTSEL 0x00000080 -#define CLS_EX_LINEWITHGROUPS 0x00000100 -#define CLS_EX_QUICKSEARCHVISONLY 0x00000200 -#define CLS_EX_SORTGROUPSALPHA 0x00000400 -#define CLS_EX_NOSMOOTHSCROLLING 0x00000800 - -#define CLM_FIRST 0x1000 //this is the same as LVM_FIRST -#define CLM_LAST 0x1100 - -//messages, compare with equivalent TVM_s in the MSDN -#define CLM_ADDCONTACT (CLM_FIRST+0) //wParam = hContact -#define CLM_ADDGROUP (CLM_FIRST+1) //wParam = hGroup -#define CLM_AUTOREBUILD (CLM_FIRST+2) -#define CLM_DELETEITEM (CLM_FIRST+3) //wParam = hItem -#define CLM_EDITLABEL (CLM_FIRST+4) //wParam = hItem -#define CLM_ENDEDITLABELNOW (CLM_FIRST+5) //wParam = cancel, 0 to save -#define CLM_ENSUREVISIBLE (CLM_FIRST+6) //wParam = hItem, lParam = partialOk -#define CLE_TOGGLE -1 -#define CLE_COLLAPSE 0 -#define CLE_EXPAND 1 -#define CLE_INVALID 0xFFFF -#define CLM_EXPAND (CLM_FIRST+7) //wParam = hItem, lParam = CLE_ -#define CLM_FINDCONTACT (CLM_FIRST+8) //wParam = hContact, returns an hItem -#define CLM_FINDGROUP (CLM_FIRST+9) //wParam = hGroup, returns an hItem -#define CLM_GETBKCOLOR (CLM_FIRST+10) //returns a COLORREF -#define CLM_GETCHECKMARK (CLM_FIRST+11) //wParam = hItem, returns 1 or 0 -#define CLM_GETCOUNT (CLM_FIRST+12) //returns the total number of items -#define CLM_GETEDITCONTROL (CLM_FIRST+13) //returns the HWND, or NULL -#define CLM_GETEXPAND (CLM_FIRST+14) //wParam = hItem, returns a CLE_, CLE_INVALID if not a group -#define CLM_GETEXTRACOLUMNS (CLM_FIRST+15) //returns number of extra columns -#define CLM_GETEXTRAIMAGE (CLM_FIRST+16) //wParam = hItem, lParam = MAKELPARAM(iColumn (0 based),0), returns iImage or EMPTY_EXTRA_ICON -#define CLM_GETEXTRAIMAGELIST (CLM_FIRST+17) //returns HIMAGELIST -#define CLM_GETFONT (CLM_FIRST+18) //wParam = fontId, see clm_setfont. returns hFont. -#define CLM_GETINDENT (CLM_FIRST+19) //wParam = new group indent -#define CLM_GETISEARCHSTRING (CLM_FIRST+20) //lParam = (char*)pszStr, max 120 bytes, returns number of chars in string -#define CLM_GETITEMTEXT (CLM_FIRST+21) //wParam = hItem, lParam = (wchar_t*)pszStr, max 120 bytes -#define CLM_GETSCROLLTIME (CLM_FIRST+22) //returns time in ms -#define CLM_GETSELECTION (CLM_FIRST+23) //returns hItem -#define CLM_SETEXTRASPACE (CLM_FIRST+24) //wParam=extra space between icons - -#define CLCHT_ABOVE 0x0001 //above client area -#define CLCHT_BELOW 0x0002 //below client area -#define CLCHT_TOLEFT 0x0004 //left of client area -#define CLCHT_TORIGHT 0x0008 //right of client area -#define CLCHT_NOWHERE 0x0010 //in client area, not on an item -#define CLCHT_ONITEMICON 0x0020 -#define CLCHT_ONITEMCHECK 0x0040 -#define CLCHT_ONITEMLABEL 0x0080 -#define CLCHT_ONITEMINDENT 0x0100 //to the left of an item icon -#define CLCHT_ONITEMEXTRA 0x0200 //on an extra icon, HIBYTE(HIWORD()) says which -#define CLCHT_ONITEM 0x03E0 -#define CLCHT_INLEFTMARGIN 0x0400 -#define CLCHT_BELOWITEMS 0x0800 //in client area but below last item -#define CLM_HITTEST (CLM_FIRST+25) //lParam = MAKELPARAM(x,y) (relative to control), wParam = (PDWORD)&hitTest (see encoding of HitTest() in clc.h, can be NULL) returns hItem or NULL -#define CLM_SELECTITEM (CLM_FIRST+26) //wParam = hItem -#define CLB_TOPLEFT 0 -#define CLB_STRETCHV 1 -#define CLB_STRETCHH 2 //and tile vertically -#define CLB_STRETCH 3 -#define CLBM_TYPE 0x00FF -#define CLBF_TILEH 0x1000 -#define CLBF_TILEV 0x2000 -#define CLBF_PROPORTIONAL 0x4000 -#define CLBF_SCROLL 0x8000 - -#define CLM_SETBKCOLOR (CLM_FIRST+28) //wParam = a COLORREF, default is GetSysColor(COLOR_3DFACE) -#define CLM_SETCHECKMARK (CLM_FIRST+29) //wParam = hItem, lParam = 1 or 0 -#define CLM_SETEXTRACOLUMNS (CLM_FIRST+30) //wParam = number of extra columns (zero to EXTRA_ICON_COUNT from clc.h, currently 16) -#define CLM_SETEXTRAIMAGE (CLM_FIRST+31) //wParam = hItem, lParam = MAKELPARAM(iColumn (0 based),iImage). iImage = EMPTY_EXTRA_ICON is a blank -#define CLM_SETEXTRAIMAGELIST (CLM_FIRST+32) //lParam = HIMAGELIST - -#define FONTID_CONTACTS 0 -#define FONTID_INVIS 1 -#define FONTID_OFFLINE 2 -#define FONTID_NOTONLIST 3 -#define FONTID_GROUPS 4 -#define FONTID_GROUPCOUNTS 5 -#define FONTID_DIVIDERS 6 -#define FONTID_OFFINVIS 7 -#define FONTID_STATUSMSG 8 -#define FONTID_GROUPSCLOSED 9 -#define FONTID_CONTACTSHOVER 10 -#define FONTID_MAX 18 - -#define CLM_SETFONT (CLM_FIRST+33) //wParam = hFont, lParam = MAKELPARAM(fRedraw,fontId) -#define CLM_SETITEMTEXT (CLM_FIRST+35) //wParam = hItem, lParam = (char*)pszNewText -#define CLM_SETSCROLLTIME (CLM_FIRST+36) //wParam = time in ms, default 200 - -#define CLM_SETHIDEEMPTYGROUPS (CLM_FIRST+38) //wParam = TRUE/FALSE -#define GREYF_UNFOCUS 0x80000000 -#define MODEF_OFFLINE 0x40000000 -//and use the PF2_ #defines from m_protosvc.h - -#define CLM_GETHIDEOFFLINEROOT (CLM_FIRST+40) //returns TRUE/FALSE -#define CLM_SETHIDEOFFLINEROOT (CLM_FIRST+41) //wParam = TRUE/FALSE -#define CLM_SETUSEGROUPS (CLM_FIRST+42) //wParam = TRUE/FALSE -#define CLM_SETOFFLINEMODES (CLM_FIRST+43) //for 'hide offline', wParam = PF2_ flags and MODEF_OFFLINE -#define CLM_GETEXSTYLE (CLM_FIRST+44) //returns CLS_EX_ flags -#define CLM_SETEXSTYLE (CLM_FIRST+45) //wParam = CLS_EX_ flags - -typedef struct { - int cbSize; - const wchar_t *pszText; - HANDLE hParentGroup; - uint32_t flags; - HICON hIcon; //todo -} CLCINFOITEM; -#define CLCIIF_BELOWGROUPS 1 //put it between groups and contacts, default is at top -#define CLCIIF_BELOWCONTACTS 2 //put it at the bottom -#define CLCIIF_CHECKBOX 0x40 //give this item a check box -#define CLCIIF_GROUPFONT 0x80 //draw the item using FONTID_GROUPS - -#define CLM_ADDINFOITEMA (CLM_FIRST+48) //lParam = &cii, returns hItem -#define CLM_ADDINFOITEMW (CLM_FIRST+53) //lParam = &cii, returns hItem -#if defined(_UNICODE) - #define CLM_ADDINFOITEM CLM_ADDINFOITEMW -#else - #define CLM_ADDINFOITEM CLM_ADDINFOITEMA -#endif - - //the order of info items is never changed, so make sure you add them in the - // order you want them to remain -#define CLCIT_INVALID -1 -#define CLCIT_GROUP 0 -#define CLCIT_CONTACT 1 -#define CLCIT_DIVIDER 2 -#define CLCIT_INFO 3 -#define CLM_GETITEMTYPE (CLM_FIRST+49) //wParam = hItem, returns a CLCIT_ -#define CLGN_ROOT 0 -#define CLGN_CHILD 1 -#define CLGN_PARENT 2 -#define CLGN_NEXT 3 -#define CLGN_PREVIOUS 4 -#define CLGN_NEXTCONTACT 5 -#define CLGN_PREVIOUSCONTACT 6 -#define CLGN_NEXTGROUP 7 -#define CLGN_PREVIOUSGROUP 8 - -#define CLM_GETNEXTITEM (CLM_FIRST+50) //wParam = flag, lParam = hItem, returns an hItem -#define CLM_GETTEXTCOLOR (CLM_FIRST+51) //wParam = FONTID_, returns COLORREF -#define CLM_SETTEXTCOLOR (CLM_FIRST+52) //wParam = FONTID_, lParam = COLORREF - -//notifications (most are omitted because the control processes everything) -#define CLNF_ISGROUP 1 -#define CLNF_ISINFO 2 -#ifdef _MSC_VER -typedef struct { - NMHDR hdr; - HANDLE hItem; - int action; - int iColumn; //-1 if not on an extra column - uint32_t flags; - POINT pt; -} NMCLISTCONTROL; -#endif -#define CLN_FIRST (0U-100U) -#define CLN_EXPANDED (CLN_FIRST-0) //hItem = hGroup, action = CLE_* -#define CLN_LISTREBUILT (CLN_FIRST-1) -#define CLN_ITEMCHECKED (CLN_FIRST-2) //todo //hItem, action, flags valid -#define CLN_DRAGGING (CLN_FIRST-3) //hItem, pt, flags valid. only sent when cursor outside window, return nonzero if processed -#define CLN_DROPPED (CLN_FIRST-4) //hItem, pt, flags valid. only sent when cursor outside window, return nonzero if processed -#define CLN_LISTSIZECHANGE (CLN_FIRST-5) //pt.y valid. the vertical height of the visible items in the list has changed. -#define CLN_OPTIONSCHANGED (CLN_FIRST-6) //nothing valid. If you set some extended options they have been overwritten and should be re-set -#define CLN_DRAGSTOP (CLN_FIRST-7) //hItem, flags valid. sent when cursor goes back in to the window having been outside, return nonzero if processed -#define CLN_NEWCONTACT (CLN_FIRST-8) //hItem, flags valid. sent when a new contact is added without a full list rebuild -#define CLN_CONTACTMOVED (CLN_FIRST-9) //hItem, flags valid. sent when contact is moved without a full list rebuild -#define CLN_CHECKCHANGED (CLN_FIRST-10) //hItem, flags valid. sent when any check mark is changed, but only for one change if there are many -//NM_CLICK //hItem, iColumn, pt, flags valid -//NM_KEYDOWN //NMKEY structure, only sent when key is not already processed, return nonzero to prevent further processing - -// clist window tree messages -#define M_CREATECLC (WM_USER+1) -#define M_SETALLEXTRAICONS (WM_USER+2) - -//an infotip for an item should be shown now -//wParam = 0 -//lParam = (LPARAM)(CLCINFOTIP*)&it -//Return nonzero if you process this, because it makes no sense for more than -//one plugin to grab it. -//It is up to the plugin to decide the best place to put the infotip. Normally -//it's a few pixels below and to the right of the cursor -//This event is called after the mouse has been stationary over a contact for -//(by default) 200ms, but see below. -//Everything is in screen coordinates. -typedef struct { - int cbSize; - int isTreeFocused; //so the plugin can provide an option - int isGroup; //0 if it's a contact, 1 if it's a group - HANDLE hItem; //handle to group or contact - POINT ptCursor; - RECT rcItem; -} CLCINFOTIP; -#define ME_CLC_SHOWINFOTIP "CLC/ShowInfoTip" - -typedef struct { - int cbSize; - int isTreeFocused; //so the plugin can provide an option - HANDLE hItem; //handle to group or contact - POINT ptCursor; - RECT rcItem; - int extraIndex; - HWND hwnd; -} CLCEXTRAINFOTIP; -#define ME_CLC_SHOWEXTRAINFOTIP "CLC/ShowExtraInfoTip" - -//it's time to destroy an infotip -//wParam = 0 -//lParam = (LPARAM)(CLCINFOTIP*)&it -//Only cbSize, isGroup and hItem are set -//Return nonzero if you process this. -//This is sent when the mouse moves off a contact when clc/showinfotip has -//previously been called. -//If you don't want this behaviour, you should have grabbed the mouse capture -//yourself and made your own arrangements. -#define ME_CLC_HIDEINFOTIP "CLC/HideInfoTip" - -//set the hover time before the infotip hooks are called -//wParam = newTime -//lParam = 0 -//Returns 0 on success or nonzero on failure -//The value of this setting is applied to all current CLC windows, and saved -//to be applied to all future windows, including after restarts. -//newTime is in ms. -//The default is 750ms. -#define MS_CLC_SETINFOTIPHOVERTIME "CLC/SetInfoTipHoverTime" - -//get the hover time before the infotip hooks are called -//wParam = lParam = 0 -//Returns the time in ms -#define MS_CLC_GETINFOTIPHOVERTIME "CLC/GetInfoTipHoverTime" - -#endif // M_CLC_H__ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-08 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_CLC_H__
+#define M_CLC_H__ 1
+
+#define CLISTCONTROL_CLASS "CListControl"
+#define CLISTCONTROL_CLASSW L"CListControl"
+
+//styles
+#define CLS_MANUALUPDATE 0x0001 //todo
+#define CLS_SHOWHIDDEN 0x0002
+#define CLS_HIDEOFFLINE 0x0004 //hides all offline users
+#define CLS_CHECKBOXES 0x0008
+#define CLS_MULTICOLUMN 0x0010 //not true multi-column, just for ignore/vis options
+#define CLS_HIDEEMPTYGROUPS 0x0020 //note: this flag will be spontaneously removed if the 'new subgroup' menu item is clicked, for obvious reasons
+#define CLS_USEGROUPS 0x0040
+#define CLS_NOHIDEOFFLINE 0x0080 //overrides CLS_HIDEOFFLINE and the per-group hideoffline setting
+#define CLS_GREYALTERNATE 0x0100 //make every other line slightly grey
+#define CLS_GROUPCHECKBOXES 0x0200 //put checkboxes on groups too (managed by CLC)
+#define CLS_CONTACTLIST 0x0400 //this control will be the main contact list (v. 0.3.4.3+ 2004/11/02)
+
+#define CLS_EX_DISABLEDRAGDROP 0x00000001
+#define CLS_EX_EDITLABELS 0x00000002
+#define CLS_EX_SHOWSELALWAYS 0x00000004
+#define CLS_EX_TRACKSELECT 0x00000008
+#define CLS_EX_SHOWGROUPCOUNTS 0x00000010
+#define CLS_EX_DIVIDERONOFF 0x00000020
+#define CLS_EX_HIDECOUNTSWHENEMPTY 0x00000040
+#define CLS_EX_NOTRANSLUCENTSEL 0x00000080
+#define CLS_EX_LINEWITHGROUPS 0x00000100
+#define CLS_EX_QUICKSEARCHVISONLY 0x00000200
+#define CLS_EX_SORTGROUPSALPHA 0x00000400
+#define CLS_EX_NOSMOOTHSCROLLING 0x00000800
+
+#define CLM_FIRST 0x1000 //this is the same as LVM_FIRST
+#define CLM_LAST 0x1100
+
+//messages, compare with equivalent TVM_s in the MSDN
+#define CLM_ADDCONTACT (CLM_FIRST+0) //wParam = hContact
+#define CLM_ADDGROUP (CLM_FIRST+1) //wParam = hGroup
+#define CLM_AUTOREBUILD (CLM_FIRST+2)
+#define CLM_DELETEITEM (CLM_FIRST+3) //wParam = hItem
+#define CLM_EDITLABEL (CLM_FIRST+4) //wParam = hItem
+#define CLM_ENDEDITLABELNOW (CLM_FIRST+5) //wParam = cancel, 0 to save
+#define CLM_ENSUREVISIBLE (CLM_FIRST+6) //wParam = hItem, lParam = partialOk
+#define CLE_TOGGLE -1
+#define CLE_COLLAPSE 0
+#define CLE_EXPAND 1
+#define CLE_INVALID 0xFFFF
+#define CLM_EXPAND (CLM_FIRST+7) //wParam = hItem, lParam = CLE_
+#define CLM_FINDCONTACT (CLM_FIRST+8) //wParam = hContact, returns an hItem
+#define CLM_FINDGROUP (CLM_FIRST+9) //wParam = hGroup, returns an hItem
+#define CLM_GETBKCOLOR (CLM_FIRST+10) //returns a COLORREF
+#define CLM_GETCHECKMARK (CLM_FIRST+11) //wParam = hItem, returns 1 or 0
+#define CLM_GETCOUNT (CLM_FIRST+12) //returns the total number of items
+#define CLM_GETEDITCONTROL (CLM_FIRST+13) //returns the HWND, or NULL
+#define CLM_GETEXPAND (CLM_FIRST+14) //wParam = hItem, returns a CLE_, CLE_INVALID if not a group
+#define CLM_GETEXTRACOLUMNS (CLM_FIRST+15) //returns number of extra columns
+#define CLM_GETEXTRAIMAGE (CLM_FIRST+16) //wParam = hItem, lParam = MAKELPARAM(iColumn (0 based),0), returns iImage or EMPTY_EXTRA_ICON
+#define CLM_GETEXTRAIMAGELIST (CLM_FIRST+17) //returns HIMAGELIST
+#define CLM_GETFONT (CLM_FIRST+18) //wParam = fontId, see clm_setfont. returns hFont.
+#define CLM_GETINDENT (CLM_FIRST+19) //wParam = new group indent
+#define CLM_GETISEARCHSTRING (CLM_FIRST+20) //lParam = (char*)pszStr, max 120 bytes, returns number of chars in string
+#define CLM_GETITEMTEXT (CLM_FIRST+21) //wParam = hItem, lParam = (wchar_t*)pszStr, max 120 bytes
+#define CLM_GETSCROLLTIME (CLM_FIRST+22) //returns time in ms
+#define CLM_GETSELECTION (CLM_FIRST+23) //returns hItem
+#define CLM_SETEXTRASPACE (CLM_FIRST+24) //wParam=extra space between icons
+
+#define CLCHT_ABOVE 0x0001 //above client area
+#define CLCHT_BELOW 0x0002 //below client area
+#define CLCHT_TOLEFT 0x0004 //left of client area
+#define CLCHT_TORIGHT 0x0008 //right of client area
+#define CLCHT_NOWHERE 0x0010 //in client area, not on an item
+#define CLCHT_ONITEMICON 0x0020
+#define CLCHT_ONITEMCHECK 0x0040
+#define CLCHT_ONITEMLABEL 0x0080
+#define CLCHT_ONITEMINDENT 0x0100 //to the left of an item icon
+#define CLCHT_ONITEMEXTRA 0x0200 //on an extra icon, HIBYTE(HIWORD()) says which
+#define CLCHT_ONITEM 0x03E0
+#define CLCHT_INLEFTMARGIN 0x0400
+#define CLCHT_BELOWITEMS 0x0800 //in client area but below last item
+#define CLM_HITTEST (CLM_FIRST+25) //lParam = MAKELPARAM(x,y) (relative to control), wParam = (PDWORD)&hitTest (see encoding of HitTest() in clc.h, can be NULL) returns hItem or NULL
+#define CLM_SELECTITEM (CLM_FIRST+26) //wParam = hItem
+#define CLB_TOPLEFT 0
+#define CLB_STRETCHV 1
+#define CLB_STRETCHH 2 //and tile vertically
+#define CLB_STRETCH 3
+#define CLBM_TYPE 0x00FF
+#define CLBF_TILEH 0x1000
+#define CLBF_TILEV 0x2000
+#define CLBF_PROPORTIONAL 0x4000
+#define CLBF_SCROLL 0x8000
+
+#define CLM_SETBKCOLOR (CLM_FIRST+28) //wParam = a COLORREF, default is GetSysColor(COLOR_3DFACE)
+#define CLM_SETCHECKMARK (CLM_FIRST+29) //wParam = hItem, lParam = 1 or 0
+#define CLM_SETEXTRACOLUMNS (CLM_FIRST+30) //wParam = number of extra columns (zero to EXTRA_ICON_COUNT from clc.h, currently 16)
+#define CLM_SETEXTRAIMAGE (CLM_FIRST+31) //wParam = hItem, lParam = MAKELPARAM(iColumn (0 based),iImage). iImage = EMPTY_EXTRA_ICON is a blank
+#define CLM_SETEXTRAIMAGELIST (CLM_FIRST+32) //lParam = HIMAGELIST
+
+#define FONTID_CONTACTS 0
+#define FONTID_INVIS 1
+#define FONTID_OFFLINE 2
+#define FONTID_NOTONLIST 3
+#define FONTID_GROUPS 4
+#define FONTID_GROUPCOUNTS 5
+#define FONTID_DIVIDERS 6
+#define FONTID_OFFINVIS 7
+#define FONTID_STATUSMSG 8
+#define FONTID_GROUPSCLOSED 9
+#define FONTID_CONTACTSHOVER 10
+#define FONTID_MAX 18
+
+#define CLM_SETFONT (CLM_FIRST+33) //wParam = hFont, lParam = MAKELPARAM(fRedraw,fontId)
+#define CLM_SETITEMTEXT (CLM_FIRST+35) //wParam = hItem, lParam = (char*)pszNewText
+#define CLM_SETSCROLLTIME (CLM_FIRST+36) //wParam = time in ms, default 200
+
+#define CLM_SETHIDEEMPTYGROUPS (CLM_FIRST+38) //wParam = TRUE/FALSE
+#define GREYF_UNFOCUS 0x80000000
+#define MODEF_OFFLINE 0x40000000
+//and use the PF2_ #defines from m_protosvc.h
+
+#define CLM_GETHIDEOFFLINEROOT (CLM_FIRST+40) //returns TRUE/FALSE
+#define CLM_SETHIDEOFFLINEROOT (CLM_FIRST+41) //wParam = TRUE/FALSE
+#define CLM_SETUSEGROUPS (CLM_FIRST+42) //wParam = TRUE/FALSE
+#define CLM_SETOFFLINEMODES (CLM_FIRST+43) //for 'hide offline', wParam = PF2_ flags and MODEF_OFFLINE
+#define CLM_GETEXSTYLE (CLM_FIRST+44) //returns CLS_EX_ flags
+#define CLM_SETEXSTYLE (CLM_FIRST+45) //wParam = CLS_EX_ flags
+
+typedef struct {
+ int cbSize;
+ const wchar_t *pszText;
+ HANDLE hParentGroup;
+ uint32_t flags;
+ HICON hIcon; //todo
+} CLCINFOITEM;
+#define CLCIIF_BELOWGROUPS 1 //put it between groups and contacts, default is at top
+#define CLCIIF_BELOWCONTACTS 2 //put it at the bottom
+#define CLCIIF_CHECKBOX 0x40 //give this item a check box
+#define CLCIIF_GROUPFONT 0x80 //draw the item using FONTID_GROUPS
+
+#define CLM_ADDINFOITEMA (CLM_FIRST+48) //lParam = &cii, returns hItem
+#define CLM_ADDINFOITEMW (CLM_FIRST+53) //lParam = &cii, returns hItem
+#if defined(_UNICODE)
+ #define CLM_ADDINFOITEM CLM_ADDINFOITEMW
+#else
+ #define CLM_ADDINFOITEM CLM_ADDINFOITEMA
+#endif
+
+ //the order of info items is never changed, so make sure you add them in the
+ // order you want them to remain
+#define CLCIT_INVALID -1
+#define CLCIT_GROUP 0
+#define CLCIT_CONTACT 1
+#define CLCIT_DIVIDER 2
+#define CLCIT_INFO 3
+#define CLM_GETITEMTYPE (CLM_FIRST+49) //wParam = hItem, returns a CLCIT_
+#define CLGN_ROOT 0
+#define CLGN_CHILD 1
+#define CLGN_PARENT 2
+#define CLGN_NEXT 3
+#define CLGN_PREVIOUS 4
+#define CLGN_NEXTCONTACT 5
+#define CLGN_PREVIOUSCONTACT 6
+#define CLGN_NEXTGROUP 7
+#define CLGN_PREVIOUSGROUP 8
+
+#define CLM_GETNEXTITEM (CLM_FIRST+50) //wParam = flag, lParam = hItem, returns an hItem
+#define CLM_GETTEXTCOLOR (CLM_FIRST+51) //wParam = FONTID_, returns COLORREF
+#define CLM_SETTEXTCOLOR (CLM_FIRST+52) //wParam = FONTID_, lParam = COLORREF
+
+//notifications (most are omitted because the control processes everything)
+#define CLNF_ISGROUP 1
+#define CLNF_ISINFO 2
+#ifdef _MSC_VER
+typedef struct {
+ NMHDR hdr;
+ HANDLE hItem;
+ int action;
+ int iColumn; //-1 if not on an extra column
+ uint32_t flags;
+ POINT pt;
+} NMCLISTCONTROL;
+#endif
+#define CLN_FIRST (0U-100U)
+#define CLN_EXPANDED (CLN_FIRST-0) //hItem = hGroup, action = CLE_*
+#define CLN_LISTREBUILT (CLN_FIRST-1)
+#define CLN_ITEMCHECKED (CLN_FIRST-2) //todo //hItem, action, flags valid
+#define CLN_DRAGGING (CLN_FIRST-3) //hItem, pt, flags valid. only sent when cursor outside window, return nonzero if processed
+#define CLN_DROPPED (CLN_FIRST-4) //hItem, pt, flags valid. only sent when cursor outside window, return nonzero if processed
+#define CLN_LISTSIZECHANGE (CLN_FIRST-5) //pt.y valid. the vertical height of the visible items in the list has changed.
+#define CLN_OPTIONSCHANGED (CLN_FIRST-6) //nothing valid. If you set some extended options they have been overwritten and should be re-set
+#define CLN_DRAGSTOP (CLN_FIRST-7) //hItem, flags valid. sent when cursor goes back in to the window having been outside, return nonzero if processed
+#define CLN_NEWCONTACT (CLN_FIRST-8) //hItem, flags valid. sent when a new contact is added without a full list rebuild
+#define CLN_CONTACTMOVED (CLN_FIRST-9) //hItem, flags valid. sent when contact is moved without a full list rebuild
+#define CLN_CHECKCHANGED (CLN_FIRST-10) //hItem, flags valid. sent when any check mark is changed, but only for one change if there are many
+//NM_CLICK //hItem, iColumn, pt, flags valid
+//NM_KEYDOWN //NMKEY structure, only sent when key is not already processed, return nonzero to prevent further processing
+
+// clist window tree messages
+#define M_CREATECLC (WM_USER+1)
+#define M_SETALLEXTRAICONS (WM_USER+2)
+
+//an infotip for an item should be shown now
+//wParam = 0
+//lParam = (LPARAM)(CLCINFOTIP*)&it
+//Return nonzero if you process this, because it makes no sense for more than
+//one plugin to grab it.
+//It is up to the plugin to decide the best place to put the infotip. Normally
+//it's a few pixels below and to the right of the cursor
+//This event is called after the mouse has been stationary over a contact for
+//(by default) 200ms, but see below.
+//Everything is in screen coordinates.
+typedef struct {
+ int cbSize;
+ int isTreeFocused; //so the plugin can provide an option
+ int isGroup; //0 if it's a contact, 1 if it's a group
+ HANDLE hItem; //handle to group or contact
+ POINT ptCursor;
+ RECT rcItem;
+} CLCINFOTIP;
+#define ME_CLC_SHOWINFOTIP "CLC/ShowInfoTip"
+
+typedef struct {
+ int cbSize;
+ int isTreeFocused; //so the plugin can provide an option
+ HANDLE hItem; //handle to group or contact
+ POINT ptCursor;
+ RECT rcItem;
+ int extraIndex;
+ HWND hwnd;
+} CLCEXTRAINFOTIP;
+#define ME_CLC_SHOWEXTRAINFOTIP "CLC/ShowExtraInfoTip"
+
+//it's time to destroy an infotip
+//wParam = 0
+//lParam = (LPARAM)(CLCINFOTIP*)&it
+//Only cbSize, isGroup and hItem are set
+//Return nonzero if you process this.
+//This is sent when the mouse moves off a contact when clc/showinfotip has
+//previously been called.
+//If you don't want this behaviour, you should have grabbed the mouse capture
+//yourself and made your own arrangements.
+#define ME_CLC_HIDEINFOTIP "CLC/HideInfoTip"
+
+//set the hover time before the infotip hooks are called
+//wParam = newTime
+//lParam = 0
+//Returns 0 on success or nonzero on failure
+//The value of this setting is applied to all current CLC windows, and saved
+//to be applied to all future windows, including after restarts.
+//newTime is in ms.
+//The default is 750ms.
+#define MS_CLC_SETINFOTIPHOVERTIME "CLC/SetInfoTipHoverTime"
+
+//get the hover time before the infotip hooks are called
+//wParam = lParam = 0
+//Returns the time in ms
+#define MS_CLC_GETINFOTIPHOVERTIME "CLC/GetInfoTipHoverTime"
+
+#endif // M_CLC_H__
diff --git a/include/m_clist.h b/include/m_clist.h index 6967401e0e..3eb05692cc 100644 --- a/include/m_clist.h +++ b/include/m_clist.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_clistint.h b/include/m_clistint.h index 55e9f5c26e..f2d8c70467 100644 --- a/include/m_clistint.h +++ b/include/m_clistint.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_cluiframes.h b/include/m_cluiframes.h index b7e9ae2836..0944c2632c 100644 --- a/include/m_cluiframes.h +++ b/include/m_cluiframes.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-02 Richard Hughes, Roland Rabien & Tristan Van de Vreede
This program is free software; you can redistribute it and/or
diff --git a/include/m_contacts.h b/include/m_contacts.h index 49e2f98566..3cea1e17d6 100644 --- a/include/m_contacts.h +++ b/include/m_contacts.h @@ -1,7 +1,7 @@ /*
Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/include/m_core.h b/include/m_core.h index 9d00b7463f..6f2b88f631 100644 --- a/include/m_core.h +++ b/include/m_core.h @@ -1,673 +1,673 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-08 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef M_CORE_H__ -#define M_CORE_H__ 1 - -#ifdef _MSC_VER - #include <sal.h> -#endif - -#include <stdarg.h> -#include <stdint.h> -#include <stdlib.h> - -#ifndef M_TYPES_H__ - #include <m_types.h> -#endif - -#ifdef MIR_CORE_EXPORTS - #define MIR_CORE_EXPORT MIR_EXPORT -#else - #define MIR_CORE_EXPORT MIR_IMPORT -#endif - -#define MIR_CORE_DLL(T) MIR_CORE_EXPORT T MIR_SYSCALL -#define MIR_C_CORE_DLL(T) MIR_CORE_EXPORT T MIR_CDECL - -#ifdef MIR_APP_EXPORTS - #define MIR_APP_EXPORT MIR_EXPORT - typedef struct NetlibUser* HNETLIBUSER; - typedef struct NetlibConnection* HNETLIBCONN; - typedef struct NetlibBoundPort* HNETLIBBIND; -#else - #define MIR_APP_EXPORT MIR_IMPORT - DECLARE_HANDLE(HNETLIBUSER); - DECLARE_HANDLE(HNETLIBCONN); - DECLARE_HANDLE(HNETLIBBIND); -#endif - -typedef struct TMO_IntMenuItem* HGENMENU; - -class CMPluginBase; -typedef const CMPluginBase* HPLUGIN; - -#define MIR_APP_DLL(T) MIR_APP_EXPORT T MIR_SYSCALL - -#pragma warning(disable:4201 4127 4312 4706) - -#if defined(__cplusplus) -extern "C" -{ -#endif - -/////////////////////////////////////////////////////////////////////////////// -// command line support - -MIR_CORE_DLL(void) CmdLine_Parse(const wchar_t *ptszCmdLine); -MIR_CORE_DLL(const wchar_t*) CmdLine_GetOption(const wchar_t *ptszParameter); - -/////////////////////////////////////////////////////////////////////////////// -// database functions - -typedef uint32_t MCONTACT; -#define INVALID_CONTACT_ID (MCONTACT(-1)) - -typedef uint32_t MEVENT; - -/////////////////////////////////////////////////////////////////////////////// -// events, hooks & services - -#define MAXMODULELABELLENGTH 64 - -typedef int (*MIRANDAHOOK)(WPARAM, LPARAM); -typedef int (*MIRANDAHOOKPARAM)(WPARAM, LPARAM, LPARAM); -typedef int (*MIRANDAHOOKOBJ)(void*, WPARAM, LPARAM); -typedef int (*MIRANDAHOOKOBJPARAM)(void*, WPARAM, LPARAM, LPARAM); - -typedef INT_PTR (*MIRANDASERVICE)(WPARAM, LPARAM); -typedef INT_PTR (*MIRANDASERVICEPARAM)(WPARAM, LPARAM, LPARAM); -typedef INT_PTR (*MIRANDASERVICEOBJ)(void*, WPARAM, LPARAM); -typedef INT_PTR (*MIRANDASERVICEOBJPARAM)(void*, WPARAM, LPARAM, LPARAM); - -#ifdef _WIN64 - #define CALLSERVICE_NOTFOUND ((INT_PTR)0x8000000000000000) -#else - #define CALLSERVICE_NOTFOUND ((int)0x80000000) -#endif - -MIR_CORE_DLL(HANDLE) CreateHookableEvent(const char *name); -MIR_CORE_DLL(int) DestroyHookableEvent(HANDLE hEvent); -MIR_CORE_DLL(int) SetHookDefaultForHookableEvent(HANDLE hEvent, MIRANDAHOOK pfnHook); -MIR_CORE_DLL(int) CallPluginEventHook(HINSTANCE hInst, const char *pszEvent, WPARAM wParam = 0, LPARAM lParam = 0); -MIR_CORE_DLL(int) CallObjectEventHook(void *pObject, HANDLE hEvent, WPARAM wParam = 0, LPARAM lParam = 0); -MIR_CORE_DLL(int) NotifyEventHooks(HANDLE hEvent, WPARAM wParam = 0, LPARAM lParam = 0); -MIR_CORE_DLL(int) NotifyFastHook(HANDLE hEvent, WPARAM wParam = 0, LPARAM lParam = 0); - -MIR_CORE_DLL(HANDLE) HookEvent(const char *name, MIRANDAHOOK hookProc); -MIR_CORE_DLL(HANDLE) HookEventParam(const char *name, MIRANDAHOOKPARAM hookProc, LPARAM lParam = 0); -MIR_CORE_DLL(HANDLE) HookEventObj(const char *name, MIRANDAHOOKOBJ hookProc, void* object); -MIR_CORE_DLL(HANDLE) HookEventObjParam(const char *name, MIRANDAHOOKOBJPARAM hookProc, void* object, LPARAM lParam); -MIR_CORE_DLL(HANDLE) HookEventMessage(const char *name, HWND hwnd, UINT message); - -// executes the event handler if event is missing -MIR_CORE_DLL(HANDLE) HookTemporaryEvent(const char *name, MIRANDAHOOK hookProc); - -MIR_CORE_DLL(int) UnhookEvent(HANDLE hHook); -MIR_CORE_DLL(void) KillObjectEventHooks(void* pObject); -MIR_CORE_DLL(void) KillModuleEventHooks(HINSTANCE pModule); - -MIR_CORE_DLL(HANDLE) CreateServiceFunction(const char *name, MIRANDASERVICE serviceProc); -MIR_CORE_DLL(HANDLE) CreateServiceFunctionParam(const char *name, MIRANDASERVICEPARAM serviceProc, LPARAM lParam); -MIR_CORE_DLL(HANDLE) CreateServiceFunctionObj(const char *name, MIRANDASERVICEOBJ serviceProc, void* object); -MIR_CORE_DLL(HANDLE) CreateServiceFunctionObjParam(const char *name, MIRANDASERVICEOBJPARAM serviceProc, void* object, LPARAM lParam); -MIR_CORE_DLL(HANDLE) CreateProtoServiceFunction(const char *szModule, const char *szService, MIRANDASERVICE serviceProc); -MIR_CORE_DLL(int) DestroyServiceFunction(HANDLE hService); -MIR_CORE_DLL(bool) ServiceExists(const char *name); - -MIR_CORE_DLL(INT_PTR) CallService(const char *name, WPARAM wParam = 0, LPARAM lParam = 0); -MIR_CORE_DLL(INT_PTR) CallServiceSync(const char *name, WPARAM wParam = 0, LPARAM lParam = 0); - -MIR_CORE_DLL(INT_PTR) CallFunctionSync(INT_PTR(MIR_SYSCALL *func)(void *), void *arg); -MIR_CORE_DLL(int) CallFunctionAsync(void (MIR_SYSCALL *func)(void *), void *arg); -MIR_CORE_DLL(void) KillModuleServices(HINSTANCE hInst); -MIR_CORE_DLL(void) KillObjectServices(void* pObject); - -MIR_APP_DLL(int) ProtoServiceExists(const char *szModule, const char *szService); -MIR_APP_DLL(INT_PTR) CallProtoService(const char *szModule, const char *szService, WPARAM wParam = 0, LPARAM lParam = 0); - -/////////////////////////////////////////////////////////////////////////////// -// exceptions - -typedef uint32_t (MIR_CDECL *pfnExceptionFilter)(uint32_t code, EXCEPTION_POINTERS *info); - -MIR_CORE_DLL(pfnExceptionFilter) GetExceptionFilter(void); -MIR_CORE_DLL(pfnExceptionFilter) SetExceptionFilter(pfnExceptionFilter pMirandaExceptFilter); - -/////////////////////////////////////////////////////////////////////////////// -// icons support - -struct IconItem -{ - char *szDescr, *szName; - int defIconID, size; - HANDLE hIcolib; -}; - -struct IconItemT -{ - wchar_t *tszDescr; - char *szName; - int defIconID, size; - HANDLE hIcolib; -}; - -MIR_CORE_DLL(void) Icon_Register(HINSTANCE hInst, const char *szSection, IconItem *pIcons, size_t iCount, const char *prefix, HPLUGIN pPlugin); -MIR_CORE_DLL(void) Icon_RegisterT(HINSTANCE hInst, const wchar_t *szSection, IconItemT *pIcons, size_t iCount, const char *prefix, HPLUGIN pPlugin); - -/////////////////////////////////////////////////////////////////////////////// -// language packs support - -MIR_CORE_DLL(unsigned int) mir_hash(const void *key, unsigned int len); - -#pragma optimize("gt", on) -__forceinline unsigned int mir_hashstr(const char *key) -{ - if (key == nullptr) return 0; - else { - unsigned int len = (unsigned int)strlen((const char*)key); - return mir_hash(key, len); -} } - -__forceinline unsigned int mir_hashstrW(const wchar_t *key) -{ - if (key == nullptr) return 0; - else { - unsigned int len = (unsigned int)wcslen((const wchar_t*)key); - return mir_hash(key, len * sizeof(wchar_t)); -} } -#pragma optimize("", on) - -#define mir_hashstrT mir_hashstrW - -/////////////////////////////////////////////////////////////////////////////// -// lists - -typedef int (*FSortFunc)(void*, void*); // sort function prototype - -// Assumes first 32 bit value of the data is the numeric key -// and uses it to perform sort/search operations, this results -// in much better performance as no compare function calls needed -// Incredibly useful for Hash Tables -#define NumericKeySort (FSortFunc)(void*) -1 -#define HandleKeySort (FSortFunc)(void*) -2 -#define PtrKeySort (FSortFunc)(void*) -3 - -typedef struct -{ - void** items; - int realCount; - int limit; - int increment; - - FSortFunc sortFunc; -} - SortedList; - -MIR_CORE_DLL(SortedList*) List_Create(int p_limit, int p_increment); -MIR_CORE_DLL(void) List_Destroy(SortedList* p_list); -MIR_CORE_DLL(void*) List_Find(SortedList* p_list, void* p_value); -MIR_CORE_DLL(int) List_GetIndex(SortedList* p_list, void* p_value, int* p_index); -MIR_CORE_DLL(int) List_IndexOf(SortedList* p_list, void* p_value); -MIR_CORE_DLL(int) List_Insert(SortedList* p_list, void* p_value, int p_index); -MIR_CORE_DLL(int) List_InsertPtr(SortedList* list, void* p); -MIR_CORE_DLL(int) List_Remove(SortedList* p_list, int index); -MIR_CORE_DLL(int) List_RemovePtr(SortedList* list, void* p); -MIR_CORE_DLL(void) List_Copy(SortedList* s, SortedList* d, size_t itemSize); -MIR_CORE_DLL(void) List_ObjCopy(SortedList* s, SortedList* d, size_t itemSize); - -/////////////////////////////////////////////////////////////////////////////// -// logging functions - -MIR_CORE_DLL(HANDLE) mir_createLog(const char *pszName, const wchar_t *ptszDescr, const wchar_t *ptszFile, unsigned options); -MIR_CORE_DLL(void) mir_closeLog(HANDLE hLogger); - -MIR_C_CORE_DLL(int) mir_writeLogA(HANDLE hLogger, const char *format, ...); -MIR_C_CORE_DLL(int) mir_writeLogW(HANDLE hLogger, const wchar_t *format, ...); - -MIR_CORE_DLL(int) mir_writeLogVA(HANDLE hLogger, const char *format, va_list args); -MIR_CORE_DLL(int) mir_writeLogVW(HANDLE hLogger, const wchar_t *format, va_list args); - -/////////////////////////////////////////////////////////////////////////////// -// md5 functions - -typedef struct mir_md5_state_s { - uint32_t count[2]; /* message length in bits, lsw first */ - uint32_t abcd[4]; /* digest buffer */ - uint8_t buf[64]; /* accumulate block */ -} mir_md5_state_t; - -MIR_CORE_DLL(void) mir_md5_init(mir_md5_state_t *pms); -MIR_CORE_DLL(void) mir_md5_append(mir_md5_state_t *pms, const uint8_t *data, size_t nbytes); -MIR_CORE_DLL(void) mir_md5_finish(mir_md5_state_t *pms, uint8_t digest[16]); -MIR_CORE_DLL(void) mir_md5_hash(const uint8_t *data, size_t len, uint8_t digest[16]); - -/////////////////////////////////////////////////////////////////////////////// -// memory functions - -MIR_C_CORE_DLL(void*) mir_alloc(size_t); -MIR_C_CORE_DLL(void*) mir_calloc(size_t); -MIR_C_CORE_DLL(void*) mir_realloc(void* ptr, size_t); -MIR_C_CORE_DLL(void) mir_free(void* ptr); - -MIR_CORE_DLL(size_t) mir_strlen(const char *p); -MIR_CORE_DLL(size_t) mir_wstrlen(const wchar_t *p); - -MIR_CORE_DLL(char*) mir_strcpy(char *dest, const char *src); -MIR_CORE_DLL(wchar_t*) mir_wstrcpy(wchar_t *dest, const wchar_t *src); - -MIR_CORE_DLL(char*) mir_strncpy(char *dest, const char *src, size_t len); -MIR_CORE_DLL(wchar_t*) mir_wstrncpy(wchar_t *dest, const wchar_t *src, size_t len); - -MIR_CORE_DLL(char*) mir_strcat(char *dest, const char *src); -MIR_CORE_DLL(wchar_t*) mir_wstrcat(wchar_t *dest, const wchar_t *src); - -MIR_CORE_DLL(char*) mir_strncat(char *dest, const char *src, size_t len); -MIR_CORE_DLL(wchar_t*) mir_wstrncat(wchar_t *dest, const wchar_t *src, size_t len); - -MIR_CORE_DLL(int) mir_strcmp(const char *p1, const char *p2); -MIR_CORE_DLL(int) mir_strncmp(const char *p1, const char *p2, size_t n); -MIR_CORE_DLL(int) mir_wstrcmp(const wchar_t *p1, const wchar_t *p2); -MIR_CORE_DLL(int) mir_wstrncmp(const wchar_t *p1, const wchar_t *p2, size_t n); - -MIR_CORE_DLL(int) mir_strcmpi(const char *p1, const char *p2); -MIR_CORE_DLL(int) mir_strncmpi(const char *p1, const char *p2, size_t n); -MIR_CORE_DLL(int) mir_wstrcmpi(const wchar_t *p1, const wchar_t *p2); -MIR_CORE_DLL(int) mir_wstrncmpi(const wchar_t *p1, const wchar_t *p2, size_t n); - -MIR_CORE_DLL(char*) mir_strdup(const char* str); -MIR_CORE_DLL(wchar_t*) mir_wstrdup(const wchar_t* str); - -MIR_CORE_DLL(char*) mir_strndup(const char* str, size_t len); -MIR_CORE_DLL(wchar_t*) mir_wstrndup(const wchar_t *str, size_t len); - -MIR_CORE_DLL(const wchar_t*) mir_wstrstri(const wchar_t *s1, const wchar_t *s2); - -/////////////////////////////////////////////////////////////////////////////// -// print functions - -MIR_CORE_DLL(int) mir_snprintf(_Pre_notnull_ _Always_(_Post_z_) char *buffer, size_t count, _Printf_format_string_ const char* fmt, ...); -MIR_CORE_DLL(int) mir_snwprintf(_Pre_notnull_ _Always_(_Post_z_) wchar_t *buffer, size_t count, _Printf_format_string_ const wchar_t* fmt, ...); -MIR_CORE_DLL(int) mir_vsnprintf(_Pre_notnull_ _Always_(_Post_z_) char *buffer, size_t count, _Printf_format_string_ const char* fmt, va_list va); -MIR_CORE_DLL(int) mir_vsnwprintf(_Pre_notnull_ _Always_(_Post_z_) wchar_t *buffer, size_t count, _Printf_format_string_ const wchar_t* fmt, va_list va); - -/////////////////////////////////////////////////////////////////////////////// -// protocol functions - -struct PROTO_INTERFACE; - -MIR_APP_DLL(INT_PTR) ProtoBroadcastAck(const char *szModule, MCONTACT hContact, int type, int result, HANDLE hProcess, LPARAM lParam = 0); -MIR_APP_DLL(void) ProtoBroadcastAsync(const char *szModule, MCONTACT hContact, int type, int result, HANDLE hProcess, LPARAM lParam = 0); - -// avatar support functions - -// returns image extension by a PA_* constant or empty string for PA_FORMAT_UNKNOWN -MIR_APP_DLL(const wchar_t*) ProtoGetAvatarExtension(int format); - -// detects image format by extension -MIR_APP_DLL(int) ProtoGetAvatarFormat(const wchar_t *ptszFileName); - -// detects image format by its contents -MIR_APP_DLL(int) ProtoGetAvatarFileFormat(const wchar_t *ptszFileName); - -// returns the mime type according to a picture type (PA_*) passed -MIR_APP_DLL(const char*) ProtoGetAvatarMimeType(int iFileType); - -// returns the picture type (PA_*) according to a mime type passed -MIR_APP_DLL(int) ProtoGetAvatarFormatByMimeType(const char *pwszMimeType); - -// returns the image format and extension by the first bytes of picture -// ptszExtension might be NULL -#if defined( __cplusplus ) - MIR_APP_DLL(int) ProtoGetBufferFormat(const void *buf, const wchar_t **ptszExtension = nullptr); -#else - MIR_APP_DLL(int) ProtoGetBufferFormat(const void *buf, const wchar_t **ptszExtension); -#endif - -/////////////////////////////////////////////////////////////////////////////// -// sha1 functions - -#define MIR_SHA1_HASH_SIZE 20 -#define MIR_SHA_BLOCKSIZE 64 - -struct mir_sha1_ctx -{ - uint32_t H[5]; - uint32_t W[80]; - int lenW; - uint32_t sizeHi, sizeLo; -}; - -MIR_CORE_DLL(void) mir_sha1_init(mir_sha1_ctx *ctx); -MIR_CORE_DLL(void) mir_sha1_append(mir_sha1_ctx *ctx, const uint8_t *dataIn, size_t len); -MIR_CORE_DLL(void) mir_sha1_finish(mir_sha1_ctx *ctx, uint8_t hashout[MIR_SHA1_HASH_SIZE]); -MIR_CORE_DLL(void) mir_sha1_hash(uint8_t *dataIn, size_t len, uint8_t hashout[MIR_SHA1_HASH_SIZE]); - -/////////////////////////////////////////////////////////////////////////////// -// sha256 functions - -#define MIR_SHA256_HASH_SIZE 32 - -struct SHA256_CONTEXT -{ - uint32_t h0, h1, h2, h3, h4, h5, h6, h7; - uint32_t nblocks; - uint8_t buf[MIR_SHA_BLOCKSIZE]; - int count; -}; - -MIR_CORE_DLL(void) mir_sha256_init(SHA256_CONTEXT *ctx); -MIR_CORE_DLL(void) mir_sha256_write(SHA256_CONTEXT *ctx, const void *dataIn, size_t len); -MIR_CORE_DLL(void) mir_sha256_final(SHA256_CONTEXT *ctx, uint8_t hashout[MIR_SHA256_HASH_SIZE]); -MIR_CORE_DLL(void) mir_sha256_hash(const void *dataIn, size_t len, uint8_t hashout[MIR_SHA256_HASH_SIZE]); - -/////////////////////////////////////////////////////////////////////////////// -// strings - -MIR_CORE_DLL(void*) mir_base64_decode(const char *input, size_t *outputLen); -MIR_CORE_DLL(char*) mir_base64_encode(const void *input, size_t inputLen); -MIR_CORE_DLL(char*) mir_base64_encodebuf(const void *input, size_t inputLen, char *output, size_t outLen); - -__forceinline size_t mir_base64_encode_bufsize(size_t inputLen) -{ - return 4 * ((inputLen + 2) / 3) + 1; -} - -MIR_CORE_DLL(char*) rtrim(char *str); -MIR_CORE_DLL(wchar_t*) rtrimw(wchar_t *str); - -MIR_CORE_DLL(char*) ltrim(char *str); // returns pointer to the beginning of string -MIR_CORE_DLL(wchar_t*) ltrimw(wchar_t *str); - -MIR_CORE_DLL(char*) ltrimp(char *str); // returns pointer to the trimmed portion of string -MIR_CORE_DLL(wchar_t*) ltrimpw(wchar_t *str); - -MIR_CORE_DLL(char*) strdel(char *str, size_t len); -MIR_CORE_DLL(wchar_t*) strdelw(wchar_t *str, size_t len); - -MIR_CORE_DLL(int) wildcmp(const char *name, const char *mask); -MIR_CORE_DLL(int) wildcmpw(const wchar_t *name, const wchar_t *mask); - -MIR_CORE_DLL(int) wildcmpi(const char *name, const char *mask); -MIR_CORE_DLL(int) wildcmpiw(const wchar_t *name, const wchar_t *mask); - -MIR_CORE_DLL(char*) bin2hex(const void *pData, size_t len, char *dest); -MIR_CORE_DLL(wchar_t*) bin2hexW(const void *pData, size_t len, wchar_t *dest); - -MIR_CORE_DLL(bool) hex2bin(const char *pSrc, void *pData, size_t len); -MIR_CORE_DLL(bool) hex2binW(const wchar_t *pSrc, void *pData, size_t len); - -__forceinline char* lrtrim(char *str) { return ltrim(rtrim(str)); }; -__forceinline char* lrtrimp(char *str) { return ltrimp(rtrim(str)); }; - -#if defined( __cplusplus ) - MIR_CORE_DLL(char*) replaceStr(char* &dest, const char *src); - MIR_CORE_DLL(wchar_t*) replaceStrW(wchar_t* &dest, const wchar_t *src); -#else - MIR_CORE_DLL(char*) replaceStr(char **dest, const char *src); - MIR_CORE_DLL(wchar_t*) replaceStrW(wchar_t **dest, const wchar_t *src); -#endif - -#ifndef _MSC_VER - MIR_CORE_DLL(char*) strlwr(char *str); - MIR_CORE_DLL(char*) strupr(char *str); - MIR_CORE_DLL(char*) strrev(char *str); -#endif - -/////////////////////////////////////////////////////////////////////////////// -// text conversion functions - -union MAllStrings -{ - char *a; // utf8 or ansi strings - wchar_t *w; // strings of WCHARs -}; - -union MAllCStrings -{ - const char *a; // utf8 or ansi strings - const wchar_t *w; // strings of WCHARs -}; - -union MAllStringArray -{ - char **a; // array of utf8 or ansi strings - wchar_t **w; // array of strings of WCHARs -}; - -union MAllCStringArray -{ - const char **a; // array of utf8 or ansi strings - const wchar_t **w; // array of strings of WCHARs -}; - -MIR_CORE_DLL(wchar_t*) mir_a2u_cp(const char* src, int codepage); -MIR_CORE_DLL(wchar_t*) mir_a2u(const char* src); -MIR_CORE_DLL(char*) mir_u2a_cp(const wchar_t* src, int codepage); -MIR_CORE_DLL(char*) mir_u2a(const wchar_t* src); - -/////////////////////////////////////////////////////////////////////////////// -// threads - -typedef void (MIR_CDECL *pThreadFunc)(void *param); -typedef unsigned (MIR_SYSCALL *pThreadFuncEx)(void *param); -typedef unsigned (MIR_CDECL *pThreadFuncOwner)(void *owner, void *param); - -#if defined( __cplusplus ) - MIR_CORE_DLL(INT_PTR) Thread_Push(HINSTANCE hInst, void* pOwner = nullptr); -#else - MIR_CORE_DLL(INT_PTR) Thread_Push(HINSTANCE hInst, void* pOwner); -#endif -MIR_CORE_DLL(INT_PTR) Thread_Pop(void); -MIR_CORE_DLL(void) Thread_Wait(void); - -#if defined( __cplusplus ) -MIR_CORE_DLL(HANDLE) mir_forkthread(pThreadFunc aFunc, void *arg = nullptr); -MIR_CORE_DLL(HANDLE) mir_forkthreadex(pThreadFuncEx aFunc, void *arg = nullptr, unsigned *pThreadID = nullptr); -MIR_CORE_DLL(HANDLE) mir_forkthreadowner(pThreadFuncOwner aFunc, void *owner, void *arg = nullptr, unsigned *pThreadID = nullptr); -#else -MIR_CORE_DLL(HANDLE) mir_forkthread(pThreadFunc aFunc, void *arg); -MIR_CORE_DLL(HANDLE) mir_forkthreadex(pThreadFuncEx aFunc, void *arg, unsigned *pThreadID); -MIR_CORE_DLL(HANDLE) mir_forkthreadowner(pThreadFuncOwner aFunc, void *owner, void *arg, unsigned *pThreadID); -#endif - -MIR_CORE_DLL(void) Thread_SetName(const char *szThreadName); - -MIR_CORE_DLL(void) KillObjectThreads(void* pObject); - -/////////////////////////////////////////////////////////////////////////////// -// utf8 interface - -MIR_CORE_DLL(BOOL) Utf8CheckString(const char* str); -MIR_CORE_DLL(int) Utf8toUcs2(const char *src, size_t srclen, wchar_t *dst, size_t dstlen); // returns 0 on error - -MIR_CORE_DLL(char*) mir_utf8decode(char* str, wchar_t** ucs2); -MIR_CORE_DLL(char*) mir_utf8decodecp(char* str, int codepage, wchar_t** ucs2); -MIR_CORE_DLL(wchar_t*) mir_utf8decodeW(const char* str); - -MIR_CORE_DLL(char*) mir_utf8encode(const char* str); -MIR_CORE_DLL(char*) mir_utf8encodecp(const char* src, int codepage); -MIR_CORE_DLL(char*) mir_utf8encodeW(const wchar_t* str); - -MIR_CORE_DLL(int) mir_utf8lenW(const wchar_t *src); - -__forceinline char* mir_utf8decodeA(const char* src) -{ - char *tmp = mir_strdup(src); - mir_utf8decode(tmp, nullptr); - return tmp; -} - -/////////////////////////////////////////////////////////////////////////////// -// Window subclassing - -#ifdef _MSC_VER - -MIR_CORE_DLL(void) mir_subclassWindow(HWND hWnd, WNDPROC wndProc); -MIR_CORE_DLL(void) mir_subclassWindowFull(HWND hWnd, WNDPROC wndProc, WNDPROC oldWndProc); -MIR_CORE_DLL(LRESULT) mir_callNextSubclass(HWND hWnd, WNDPROC wndProc, UINT uMsg, WPARAM wParam, LPARAM lParam); -MIR_CORE_DLL(void) mir_unsubclassWindow(HWND hWnd, WNDPROC wndProc); - -MIR_CORE_DLL(void) KillModuleSubclassing(HMODULE hInst); - -/////////////////////////////////////////////////////////////////////////////// -// Windows utilities - -MIR_CORE_DLL(BOOL) IsWinVerVistaPlus(); -MIR_CORE_DLL(BOOL) IsWinVer7Plus(); -MIR_CORE_DLL(BOOL) IsWinVer8Plus(); -MIR_CORE_DLL(BOOL) IsWinVer81Plus(); -MIR_CORE_DLL(BOOL) IsWinVer10Plus(); - -MIR_CORE_DLL(BOOL) IsFullScreen(); -MIR_CORE_DLL(BOOL) IsWorkstationLocked(); -MIR_CORE_DLL(BOOL) IsScreenSaverRunning(); -MIR_CORE_DLL(BOOL) IsTerminalDisconnected(); - -#endif // _MSC_VER - -// returns OS version in version of Windows NT xx.xx -MIR_CORE_DLL(BOOL) OS_GetShortString(char *buf, size_t bufSize); - -// returns full OS version -MIR_CORE_DLL(BOOL) OS_GetDisplayString(char *buf, size_t bufSize); - -/////////////////////////////////////////////////////////////////////////////// - -MIR_CORE_DLL(void) UnloadCoreModule(void); - -#if defined(__cplusplus) -} - -/////////////////////////////////////////////////////////////////////////////// -// The UUID structure below is used to for plugin UUID's and module type definitions - -struct MUUID -{ - unsigned long a; - unsigned short b; - unsigned short c; - unsigned char d[8]; -}; - -__forceinline bool operator==(const MUUID& p1, const MUUID& p2) -{ - return memcmp(&p1, &p2, sizeof(MUUID)) == 0; -} -__forceinline bool operator!=(const MUUID& p1, const MUUID& p2) -{ - return memcmp(&p1, &p2, sizeof(MUUID)) != 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// C++ templates - -template <typename T> -HANDLE mir_forkThread(void(MIR_CDECL *pFunc)(T* param), T *arg) -{ - return mir_forkthread((pThreadFunc)pFunc, arg); -} - -template <size_t _Size> -inline int mir_snprintf(_Pre_notnull_ _Always_(_Post_z_) char(&buffer)[_Size], _In_z_ _Printf_format_string_ const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - int ret = mir_vsnprintf(buffer, _Size, fmt, args); - va_end(args); - return ret; -} - -template <size_t _Size> -inline int mir_snwprintf(_Pre_notnull_ _Always_(_Post_z_) wchar_t(&buffer)[_Size], _In_z_ _Printf_format_string_ const wchar_t* fmt, ...) -{ - va_list args; - va_start(args, fmt); - int ret = mir_vsnwprintf(buffer, _Size, fmt, args); - va_end(args); - return ret; -} - -template <size_t _Size> -inline int mir_vsnprintf(_Pre_notnull_ _Always_(_Post_z_) char(&buffer)[_Size], _In_z_ _Printf_format_string_ const char* fmt, va_list va) -{ - return mir_vsnprintf(buffer, _Size, fmt, va); -} - -template <size_t _Size> -inline int mir_vsnwprintf(_Pre_notnull_ _Always_(_Post_z_) wchar_t(&buffer)[_Size], _In_z_ _Printf_format_string_ const wchar_t* fmt, va_list va) -{ - return mir_vsnwprintf(buffer, _Size, fmt, va); -} - -MIR_CORE_DLL(char *) mir_base64_encode(const class MBinBuffer &buf); - -#endif - -#ifdef _MSC_VER - #ifndef MIR_CORE_EXPORTS - #pragma comment(lib, "mir_core.lib") - #endif - - #ifndef MIR_APP_EXPORTS - #pragma comment(lib, "mir_app.lib") - #endif -#else - MIR_CORE_DLL(FILE*) _wfopen(const wchar_t *pwszFileName, const wchar_t *pwszMode); - MIR_CORE_DLL(int) _wchdir(const wchar_t *pwszPath); - - template <size_t _Size> - inline wchar_t* wcsncpy_s(wchar_t(&buffer)[_Size], const wchar_t *src, size_t len) - { - return wcsncpy(buffer, src, (len == _TRUNCATE) ? _Size : len); - } - - inline wchar_t* wcsncpy_s(wchar_t *dst, size_t dstLen, const wchar_t *src, size_t len) - { - return wcsncpy(dst, src, (len == _TRUNCATE) ? dstLen : len); - } - - inline wchar_t* wcsncat_s(wchar_t *dst, size_t dstLen, const wchar_t *src, size_t len) - { - return wcsncat(dst, src, (len == _TRUNCATE) ? dstLen : len); - } - - template <size_t _Size> - inline char* strncpy_s(char(&buffer)[_Size], const char *src, size_t len) - { - return strncpy(buffer, src, (len == _TRUNCATE) ? _Size : len); - } - - inline char* strncpy_s(char *dst, size_t dstLen, const char *src, size_t len) - { - return strncpy(dst, src, (len == _TRUNCATE) ? dstLen : len); - } - - inline char* strncat_s(char *dst, size_t dstLen, const char *src, size_t len) - { - return strncat(dst, src, (len == _TRUNCATE) ? dstLen : len); - } -#endif - -#endif // M_CORE_H +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-08 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_CORE_H__
+#define M_CORE_H__ 1
+
+#ifdef _MSC_VER
+ #include <sal.h>
+#endif
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifndef M_TYPES_H__
+ #include <m_types.h>
+#endif
+
+#ifdef MIR_CORE_EXPORTS
+ #define MIR_CORE_EXPORT MIR_EXPORT
+#else
+ #define MIR_CORE_EXPORT MIR_IMPORT
+#endif
+
+#define MIR_CORE_DLL(T) MIR_CORE_EXPORT T MIR_SYSCALL
+#define MIR_C_CORE_DLL(T) MIR_CORE_EXPORT T MIR_CDECL
+
+#ifdef MIR_APP_EXPORTS
+ #define MIR_APP_EXPORT MIR_EXPORT
+ typedef struct NetlibUser* HNETLIBUSER;
+ typedef struct NetlibConnection* HNETLIBCONN;
+ typedef struct NetlibBoundPort* HNETLIBBIND;
+#else
+ #define MIR_APP_EXPORT MIR_IMPORT
+ DECLARE_HANDLE(HNETLIBUSER);
+ DECLARE_HANDLE(HNETLIBCONN);
+ DECLARE_HANDLE(HNETLIBBIND);
+#endif
+
+typedef struct TMO_IntMenuItem* HGENMENU;
+
+class CMPluginBase;
+typedef const CMPluginBase* HPLUGIN;
+
+#define MIR_APP_DLL(T) MIR_APP_EXPORT T MIR_SYSCALL
+
+#pragma warning(disable:4201 4127 4312 4706)
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// command line support
+
+MIR_CORE_DLL(void) CmdLine_Parse(const wchar_t *ptszCmdLine);
+MIR_CORE_DLL(const wchar_t*) CmdLine_GetOption(const wchar_t *ptszParameter);
+
+///////////////////////////////////////////////////////////////////////////////
+// database functions
+
+typedef uint32_t MCONTACT;
+#define INVALID_CONTACT_ID (MCONTACT(-1))
+
+typedef uint32_t MEVENT;
+
+///////////////////////////////////////////////////////////////////////////////
+// events, hooks & services
+
+#define MAXMODULELABELLENGTH 64
+
+typedef int (*MIRANDAHOOK)(WPARAM, LPARAM);
+typedef int (*MIRANDAHOOKPARAM)(WPARAM, LPARAM, LPARAM);
+typedef int (*MIRANDAHOOKOBJ)(void*, WPARAM, LPARAM);
+typedef int (*MIRANDAHOOKOBJPARAM)(void*, WPARAM, LPARAM, LPARAM);
+
+typedef INT_PTR (*MIRANDASERVICE)(WPARAM, LPARAM);
+typedef INT_PTR (*MIRANDASERVICEPARAM)(WPARAM, LPARAM, LPARAM);
+typedef INT_PTR (*MIRANDASERVICEOBJ)(void*, WPARAM, LPARAM);
+typedef INT_PTR (*MIRANDASERVICEOBJPARAM)(void*, WPARAM, LPARAM, LPARAM);
+
+#ifdef _WIN64
+ #define CALLSERVICE_NOTFOUND ((INT_PTR)0x8000000000000000)
+#else
+ #define CALLSERVICE_NOTFOUND ((int)0x80000000)
+#endif
+
+MIR_CORE_DLL(HANDLE) CreateHookableEvent(const char *name);
+MIR_CORE_DLL(int) DestroyHookableEvent(HANDLE hEvent);
+MIR_CORE_DLL(int) SetHookDefaultForHookableEvent(HANDLE hEvent, MIRANDAHOOK pfnHook);
+MIR_CORE_DLL(int) CallPluginEventHook(HINSTANCE hInst, const char *pszEvent, WPARAM wParam = 0, LPARAM lParam = 0);
+MIR_CORE_DLL(int) CallObjectEventHook(void *pObject, HANDLE hEvent, WPARAM wParam = 0, LPARAM lParam = 0);
+MIR_CORE_DLL(int) NotifyEventHooks(HANDLE hEvent, WPARAM wParam = 0, LPARAM lParam = 0);
+MIR_CORE_DLL(int) NotifyFastHook(HANDLE hEvent, WPARAM wParam = 0, LPARAM lParam = 0);
+
+MIR_CORE_DLL(HANDLE) HookEvent(const char *name, MIRANDAHOOK hookProc);
+MIR_CORE_DLL(HANDLE) HookEventParam(const char *name, MIRANDAHOOKPARAM hookProc, LPARAM lParam = 0);
+MIR_CORE_DLL(HANDLE) HookEventObj(const char *name, MIRANDAHOOKOBJ hookProc, void* object);
+MIR_CORE_DLL(HANDLE) HookEventObjParam(const char *name, MIRANDAHOOKOBJPARAM hookProc, void* object, LPARAM lParam);
+MIR_CORE_DLL(HANDLE) HookEventMessage(const char *name, HWND hwnd, UINT message);
+
+// executes the event handler if event is missing
+MIR_CORE_DLL(HANDLE) HookTemporaryEvent(const char *name, MIRANDAHOOK hookProc);
+
+MIR_CORE_DLL(int) UnhookEvent(HANDLE hHook);
+MIR_CORE_DLL(void) KillObjectEventHooks(void* pObject);
+MIR_CORE_DLL(void) KillModuleEventHooks(HINSTANCE pModule);
+
+MIR_CORE_DLL(HANDLE) CreateServiceFunction(const char *name, MIRANDASERVICE serviceProc);
+MIR_CORE_DLL(HANDLE) CreateServiceFunctionParam(const char *name, MIRANDASERVICEPARAM serviceProc, LPARAM lParam);
+MIR_CORE_DLL(HANDLE) CreateServiceFunctionObj(const char *name, MIRANDASERVICEOBJ serviceProc, void* object);
+MIR_CORE_DLL(HANDLE) CreateServiceFunctionObjParam(const char *name, MIRANDASERVICEOBJPARAM serviceProc, void* object, LPARAM lParam);
+MIR_CORE_DLL(HANDLE) CreateProtoServiceFunction(const char *szModule, const char *szService, MIRANDASERVICE serviceProc);
+MIR_CORE_DLL(int) DestroyServiceFunction(HANDLE hService);
+MIR_CORE_DLL(bool) ServiceExists(const char *name);
+
+MIR_CORE_DLL(INT_PTR) CallService(const char *name, WPARAM wParam = 0, LPARAM lParam = 0);
+MIR_CORE_DLL(INT_PTR) CallServiceSync(const char *name, WPARAM wParam = 0, LPARAM lParam = 0);
+
+MIR_CORE_DLL(INT_PTR) CallFunctionSync(INT_PTR(MIR_SYSCALL *func)(void *), void *arg);
+MIR_CORE_DLL(int) CallFunctionAsync(void (MIR_SYSCALL *func)(void *), void *arg);
+MIR_CORE_DLL(void) KillModuleServices(HINSTANCE hInst);
+MIR_CORE_DLL(void) KillObjectServices(void* pObject);
+
+MIR_APP_DLL(int) ProtoServiceExists(const char *szModule, const char *szService);
+MIR_APP_DLL(INT_PTR) CallProtoService(const char *szModule, const char *szService, WPARAM wParam = 0, LPARAM lParam = 0);
+
+///////////////////////////////////////////////////////////////////////////////
+// exceptions
+
+typedef uint32_t (MIR_CDECL *pfnExceptionFilter)(uint32_t code, EXCEPTION_POINTERS *info);
+
+MIR_CORE_DLL(pfnExceptionFilter) GetExceptionFilter(void);
+MIR_CORE_DLL(pfnExceptionFilter) SetExceptionFilter(pfnExceptionFilter pMirandaExceptFilter);
+
+///////////////////////////////////////////////////////////////////////////////
+// icons support
+
+struct IconItem
+{
+ char *szDescr, *szName;
+ int defIconID, size;
+ HANDLE hIcolib;
+};
+
+struct IconItemT
+{
+ wchar_t *tszDescr;
+ char *szName;
+ int defIconID, size;
+ HANDLE hIcolib;
+};
+
+MIR_CORE_DLL(void) Icon_Register(HINSTANCE hInst, const char *szSection, IconItem *pIcons, size_t iCount, const char *prefix, HPLUGIN pPlugin);
+MIR_CORE_DLL(void) Icon_RegisterT(HINSTANCE hInst, const wchar_t *szSection, IconItemT *pIcons, size_t iCount, const char *prefix, HPLUGIN pPlugin);
+
+///////////////////////////////////////////////////////////////////////////////
+// language packs support
+
+MIR_CORE_DLL(unsigned int) mir_hash(const void *key, unsigned int len);
+
+#pragma optimize("gt", on)
+__forceinline unsigned int mir_hashstr(const char *key)
+{
+ if (key == nullptr) return 0;
+ else {
+ unsigned int len = (unsigned int)strlen((const char*)key);
+ return mir_hash(key, len);
+} }
+
+__forceinline unsigned int mir_hashstrW(const wchar_t *key)
+{
+ if (key == nullptr) return 0;
+ else {
+ unsigned int len = (unsigned int)wcslen((const wchar_t*)key);
+ return mir_hash(key, len * sizeof(wchar_t));
+} }
+#pragma optimize("", on)
+
+#define mir_hashstrT mir_hashstrW
+
+///////////////////////////////////////////////////////////////////////////////
+// lists
+
+typedef int (*FSortFunc)(void*, void*); // sort function prototype
+
+// Assumes first 32 bit value of the data is the numeric key
+// and uses it to perform sort/search operations, this results
+// in much better performance as no compare function calls needed
+// Incredibly useful for Hash Tables
+#define NumericKeySort (FSortFunc)(void*) -1
+#define HandleKeySort (FSortFunc)(void*) -2
+#define PtrKeySort (FSortFunc)(void*) -3
+
+typedef struct
+{
+ void** items;
+ int realCount;
+ int limit;
+ int increment;
+
+ FSortFunc sortFunc;
+}
+ SortedList;
+
+MIR_CORE_DLL(SortedList*) List_Create(int p_limit, int p_increment);
+MIR_CORE_DLL(void) List_Destroy(SortedList* p_list);
+MIR_CORE_DLL(void*) List_Find(SortedList* p_list, void* p_value);
+MIR_CORE_DLL(int) List_GetIndex(SortedList* p_list, void* p_value, int* p_index);
+MIR_CORE_DLL(int) List_IndexOf(SortedList* p_list, void* p_value);
+MIR_CORE_DLL(int) List_Insert(SortedList* p_list, void* p_value, int p_index);
+MIR_CORE_DLL(int) List_InsertPtr(SortedList* list, void* p);
+MIR_CORE_DLL(int) List_Remove(SortedList* p_list, int index);
+MIR_CORE_DLL(int) List_RemovePtr(SortedList* list, void* p);
+MIR_CORE_DLL(void) List_Copy(SortedList* s, SortedList* d, size_t itemSize);
+MIR_CORE_DLL(void) List_ObjCopy(SortedList* s, SortedList* d, size_t itemSize);
+
+///////////////////////////////////////////////////////////////////////////////
+// logging functions
+
+MIR_CORE_DLL(HANDLE) mir_createLog(const char *pszName, const wchar_t *ptszDescr, const wchar_t *ptszFile, unsigned options);
+MIR_CORE_DLL(void) mir_closeLog(HANDLE hLogger);
+
+MIR_C_CORE_DLL(int) mir_writeLogA(HANDLE hLogger, const char *format, ...);
+MIR_C_CORE_DLL(int) mir_writeLogW(HANDLE hLogger, const wchar_t *format, ...);
+
+MIR_CORE_DLL(int) mir_writeLogVA(HANDLE hLogger, const char *format, va_list args);
+MIR_CORE_DLL(int) mir_writeLogVW(HANDLE hLogger, const wchar_t *format, va_list args);
+
+///////////////////////////////////////////////////////////////////////////////
+// md5 functions
+
+typedef struct mir_md5_state_s {
+ uint32_t count[2]; /* message length in bits, lsw first */
+ uint32_t abcd[4]; /* digest buffer */
+ uint8_t buf[64]; /* accumulate block */
+} mir_md5_state_t;
+
+MIR_CORE_DLL(void) mir_md5_init(mir_md5_state_t *pms);
+MIR_CORE_DLL(void) mir_md5_append(mir_md5_state_t *pms, const uint8_t *data, size_t nbytes);
+MIR_CORE_DLL(void) mir_md5_finish(mir_md5_state_t *pms, uint8_t digest[16]);
+MIR_CORE_DLL(void) mir_md5_hash(const uint8_t *data, size_t len, uint8_t digest[16]);
+
+///////////////////////////////////////////////////////////////////////////////
+// memory functions
+
+MIR_C_CORE_DLL(void*) mir_alloc(size_t);
+MIR_C_CORE_DLL(void*) mir_calloc(size_t);
+MIR_C_CORE_DLL(void*) mir_realloc(void* ptr, size_t);
+MIR_C_CORE_DLL(void) mir_free(void* ptr);
+
+MIR_CORE_DLL(size_t) mir_strlen(const char *p);
+MIR_CORE_DLL(size_t) mir_wstrlen(const wchar_t *p);
+
+MIR_CORE_DLL(char*) mir_strcpy(char *dest, const char *src);
+MIR_CORE_DLL(wchar_t*) mir_wstrcpy(wchar_t *dest, const wchar_t *src);
+
+MIR_CORE_DLL(char*) mir_strncpy(char *dest, const char *src, size_t len);
+MIR_CORE_DLL(wchar_t*) mir_wstrncpy(wchar_t *dest, const wchar_t *src, size_t len);
+
+MIR_CORE_DLL(char*) mir_strcat(char *dest, const char *src);
+MIR_CORE_DLL(wchar_t*) mir_wstrcat(wchar_t *dest, const wchar_t *src);
+
+MIR_CORE_DLL(char*) mir_strncat(char *dest, const char *src, size_t len);
+MIR_CORE_DLL(wchar_t*) mir_wstrncat(wchar_t *dest, const wchar_t *src, size_t len);
+
+MIR_CORE_DLL(int) mir_strcmp(const char *p1, const char *p2);
+MIR_CORE_DLL(int) mir_strncmp(const char *p1, const char *p2, size_t n);
+MIR_CORE_DLL(int) mir_wstrcmp(const wchar_t *p1, const wchar_t *p2);
+MIR_CORE_DLL(int) mir_wstrncmp(const wchar_t *p1, const wchar_t *p2, size_t n);
+
+MIR_CORE_DLL(int) mir_strcmpi(const char *p1, const char *p2);
+MIR_CORE_DLL(int) mir_strncmpi(const char *p1, const char *p2, size_t n);
+MIR_CORE_DLL(int) mir_wstrcmpi(const wchar_t *p1, const wchar_t *p2);
+MIR_CORE_DLL(int) mir_wstrncmpi(const wchar_t *p1, const wchar_t *p2, size_t n);
+
+MIR_CORE_DLL(char*) mir_strdup(const char* str);
+MIR_CORE_DLL(wchar_t*) mir_wstrdup(const wchar_t* str);
+
+MIR_CORE_DLL(char*) mir_strndup(const char* str, size_t len);
+MIR_CORE_DLL(wchar_t*) mir_wstrndup(const wchar_t *str, size_t len);
+
+MIR_CORE_DLL(const wchar_t*) mir_wstrstri(const wchar_t *s1, const wchar_t *s2);
+
+///////////////////////////////////////////////////////////////////////////////
+// print functions
+
+MIR_CORE_DLL(int) mir_snprintf(_Pre_notnull_ _Always_(_Post_z_) char *buffer, size_t count, _Printf_format_string_ const char* fmt, ...);
+MIR_CORE_DLL(int) mir_snwprintf(_Pre_notnull_ _Always_(_Post_z_) wchar_t *buffer, size_t count, _Printf_format_string_ const wchar_t* fmt, ...);
+MIR_CORE_DLL(int) mir_vsnprintf(_Pre_notnull_ _Always_(_Post_z_) char *buffer, size_t count, _Printf_format_string_ const char* fmt, va_list va);
+MIR_CORE_DLL(int) mir_vsnwprintf(_Pre_notnull_ _Always_(_Post_z_) wchar_t *buffer, size_t count, _Printf_format_string_ const wchar_t* fmt, va_list va);
+
+///////////////////////////////////////////////////////////////////////////////
+// protocol functions
+
+struct PROTO_INTERFACE;
+
+MIR_APP_DLL(INT_PTR) ProtoBroadcastAck(const char *szModule, MCONTACT hContact, int type, int result, HANDLE hProcess, LPARAM lParam = 0);
+MIR_APP_DLL(void) ProtoBroadcastAsync(const char *szModule, MCONTACT hContact, int type, int result, HANDLE hProcess, LPARAM lParam = 0);
+
+// avatar support functions
+
+// returns image extension by a PA_* constant or empty string for PA_FORMAT_UNKNOWN
+MIR_APP_DLL(const wchar_t*) ProtoGetAvatarExtension(int format);
+
+// detects image format by extension
+MIR_APP_DLL(int) ProtoGetAvatarFormat(const wchar_t *ptszFileName);
+
+// detects image format by its contents
+MIR_APP_DLL(int) ProtoGetAvatarFileFormat(const wchar_t *ptszFileName);
+
+// returns the mime type according to a picture type (PA_*) passed
+MIR_APP_DLL(const char*) ProtoGetAvatarMimeType(int iFileType);
+
+// returns the picture type (PA_*) according to a mime type passed
+MIR_APP_DLL(int) ProtoGetAvatarFormatByMimeType(const char *pwszMimeType);
+
+// returns the image format and extension by the first bytes of picture
+// ptszExtension might be NULL
+#if defined( __cplusplus )
+ MIR_APP_DLL(int) ProtoGetBufferFormat(const void *buf, const wchar_t **ptszExtension = nullptr);
+#else
+ MIR_APP_DLL(int) ProtoGetBufferFormat(const void *buf, const wchar_t **ptszExtension);
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// sha1 functions
+
+#define MIR_SHA1_HASH_SIZE 20
+#define MIR_SHA_BLOCKSIZE 64
+
+struct mir_sha1_ctx
+{
+ uint32_t H[5];
+ uint32_t W[80];
+ int lenW;
+ uint32_t sizeHi, sizeLo;
+};
+
+MIR_CORE_DLL(void) mir_sha1_init(mir_sha1_ctx *ctx);
+MIR_CORE_DLL(void) mir_sha1_append(mir_sha1_ctx *ctx, const uint8_t *dataIn, size_t len);
+MIR_CORE_DLL(void) mir_sha1_finish(mir_sha1_ctx *ctx, uint8_t hashout[MIR_SHA1_HASH_SIZE]);
+MIR_CORE_DLL(void) mir_sha1_hash(uint8_t *dataIn, size_t len, uint8_t hashout[MIR_SHA1_HASH_SIZE]);
+
+///////////////////////////////////////////////////////////////////////////////
+// sha256 functions
+
+#define MIR_SHA256_HASH_SIZE 32
+
+struct SHA256_CONTEXT
+{
+ uint32_t h0, h1, h2, h3, h4, h5, h6, h7;
+ uint32_t nblocks;
+ uint8_t buf[MIR_SHA_BLOCKSIZE];
+ int count;
+};
+
+MIR_CORE_DLL(void) mir_sha256_init(SHA256_CONTEXT *ctx);
+MIR_CORE_DLL(void) mir_sha256_write(SHA256_CONTEXT *ctx, const void *dataIn, size_t len);
+MIR_CORE_DLL(void) mir_sha256_final(SHA256_CONTEXT *ctx, uint8_t hashout[MIR_SHA256_HASH_SIZE]);
+MIR_CORE_DLL(void) mir_sha256_hash(const void *dataIn, size_t len, uint8_t hashout[MIR_SHA256_HASH_SIZE]);
+
+///////////////////////////////////////////////////////////////////////////////
+// strings
+
+MIR_CORE_DLL(void*) mir_base64_decode(const char *input, size_t *outputLen);
+MIR_CORE_DLL(char*) mir_base64_encode(const void *input, size_t inputLen);
+MIR_CORE_DLL(char*) mir_base64_encodebuf(const void *input, size_t inputLen, char *output, size_t outLen);
+
+__forceinline size_t mir_base64_encode_bufsize(size_t inputLen)
+{
+ return 4 * ((inputLen + 2) / 3) + 1;
+}
+
+MIR_CORE_DLL(char*) rtrim(char *str);
+MIR_CORE_DLL(wchar_t*) rtrimw(wchar_t *str);
+
+MIR_CORE_DLL(char*) ltrim(char *str); // returns pointer to the beginning of string
+MIR_CORE_DLL(wchar_t*) ltrimw(wchar_t *str);
+
+MIR_CORE_DLL(char*) ltrimp(char *str); // returns pointer to the trimmed portion of string
+MIR_CORE_DLL(wchar_t*) ltrimpw(wchar_t *str);
+
+MIR_CORE_DLL(char*) strdel(char *str, size_t len);
+MIR_CORE_DLL(wchar_t*) strdelw(wchar_t *str, size_t len);
+
+MIR_CORE_DLL(int) wildcmp(const char *name, const char *mask);
+MIR_CORE_DLL(int) wildcmpw(const wchar_t *name, const wchar_t *mask);
+
+MIR_CORE_DLL(int) wildcmpi(const char *name, const char *mask);
+MIR_CORE_DLL(int) wildcmpiw(const wchar_t *name, const wchar_t *mask);
+
+MIR_CORE_DLL(char*) bin2hex(const void *pData, size_t len, char *dest);
+MIR_CORE_DLL(wchar_t*) bin2hexW(const void *pData, size_t len, wchar_t *dest);
+
+MIR_CORE_DLL(bool) hex2bin(const char *pSrc, void *pData, size_t len);
+MIR_CORE_DLL(bool) hex2binW(const wchar_t *pSrc, void *pData, size_t len);
+
+__forceinline char* lrtrim(char *str) { return ltrim(rtrim(str)); };
+__forceinline char* lrtrimp(char *str) { return ltrimp(rtrim(str)); };
+
+#if defined( __cplusplus )
+ MIR_CORE_DLL(char*) replaceStr(char* &dest, const char *src);
+ MIR_CORE_DLL(wchar_t*) replaceStrW(wchar_t* &dest, const wchar_t *src);
+#else
+ MIR_CORE_DLL(char*) replaceStr(char **dest, const char *src);
+ MIR_CORE_DLL(wchar_t*) replaceStrW(wchar_t **dest, const wchar_t *src);
+#endif
+
+#ifndef _MSC_VER
+ MIR_CORE_DLL(char*) strlwr(char *str);
+ MIR_CORE_DLL(char*) strupr(char *str);
+ MIR_CORE_DLL(char*) strrev(char *str);
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// text conversion functions
+
+union MAllStrings
+{
+ char *a; // utf8 or ansi strings
+ wchar_t *w; // strings of WCHARs
+};
+
+union MAllCStrings
+{
+ const char *a; // utf8 or ansi strings
+ const wchar_t *w; // strings of WCHARs
+};
+
+union MAllStringArray
+{
+ char **a; // array of utf8 or ansi strings
+ wchar_t **w; // array of strings of WCHARs
+};
+
+union MAllCStringArray
+{
+ const char **a; // array of utf8 or ansi strings
+ const wchar_t **w; // array of strings of WCHARs
+};
+
+MIR_CORE_DLL(wchar_t*) mir_a2u_cp(const char* src, int codepage);
+MIR_CORE_DLL(wchar_t*) mir_a2u(const char* src);
+MIR_CORE_DLL(char*) mir_u2a_cp(const wchar_t* src, int codepage);
+MIR_CORE_DLL(char*) mir_u2a(const wchar_t* src);
+
+///////////////////////////////////////////////////////////////////////////////
+// threads
+
+typedef void (MIR_CDECL *pThreadFunc)(void *param);
+typedef unsigned (MIR_SYSCALL *pThreadFuncEx)(void *param);
+typedef unsigned (MIR_CDECL *pThreadFuncOwner)(void *owner, void *param);
+
+#if defined( __cplusplus )
+ MIR_CORE_DLL(INT_PTR) Thread_Push(HINSTANCE hInst, void* pOwner = nullptr);
+#else
+ MIR_CORE_DLL(INT_PTR) Thread_Push(HINSTANCE hInst, void* pOwner);
+#endif
+MIR_CORE_DLL(INT_PTR) Thread_Pop(void);
+MIR_CORE_DLL(void) Thread_Wait(void);
+
+#if defined( __cplusplus )
+MIR_CORE_DLL(HANDLE) mir_forkthread(pThreadFunc aFunc, void *arg = nullptr);
+MIR_CORE_DLL(HANDLE) mir_forkthreadex(pThreadFuncEx aFunc, void *arg = nullptr, unsigned *pThreadID = nullptr);
+MIR_CORE_DLL(HANDLE) mir_forkthreadowner(pThreadFuncOwner aFunc, void *owner, void *arg = nullptr, unsigned *pThreadID = nullptr);
+#else
+MIR_CORE_DLL(HANDLE) mir_forkthread(pThreadFunc aFunc, void *arg);
+MIR_CORE_DLL(HANDLE) mir_forkthreadex(pThreadFuncEx aFunc, void *arg, unsigned *pThreadID);
+MIR_CORE_DLL(HANDLE) mir_forkthreadowner(pThreadFuncOwner aFunc, void *owner, void *arg, unsigned *pThreadID);
+#endif
+
+MIR_CORE_DLL(void) Thread_SetName(const char *szThreadName);
+
+MIR_CORE_DLL(void) KillObjectThreads(void* pObject);
+
+///////////////////////////////////////////////////////////////////////////////
+// utf8 interface
+
+MIR_CORE_DLL(BOOL) Utf8CheckString(const char* str);
+MIR_CORE_DLL(int) Utf8toUcs2(const char *src, size_t srclen, wchar_t *dst, size_t dstlen); // returns 0 on error
+
+MIR_CORE_DLL(char*) mir_utf8decode(char* str, wchar_t** ucs2);
+MIR_CORE_DLL(char*) mir_utf8decodecp(char* str, int codepage, wchar_t** ucs2);
+MIR_CORE_DLL(wchar_t*) mir_utf8decodeW(const char* str);
+
+MIR_CORE_DLL(char*) mir_utf8encode(const char* str);
+MIR_CORE_DLL(char*) mir_utf8encodecp(const char* src, int codepage);
+MIR_CORE_DLL(char*) mir_utf8encodeW(const wchar_t* str);
+
+MIR_CORE_DLL(int) mir_utf8lenW(const wchar_t *src);
+
+__forceinline char* mir_utf8decodeA(const char* src)
+{
+ char *tmp = mir_strdup(src);
+ mir_utf8decode(tmp, nullptr);
+ return tmp;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Window subclassing
+
+#ifdef _MSC_VER
+
+MIR_CORE_DLL(void) mir_subclassWindow(HWND hWnd, WNDPROC wndProc);
+MIR_CORE_DLL(void) mir_subclassWindowFull(HWND hWnd, WNDPROC wndProc, WNDPROC oldWndProc);
+MIR_CORE_DLL(LRESULT) mir_callNextSubclass(HWND hWnd, WNDPROC wndProc, UINT uMsg, WPARAM wParam, LPARAM lParam);
+MIR_CORE_DLL(void) mir_unsubclassWindow(HWND hWnd, WNDPROC wndProc);
+
+MIR_CORE_DLL(void) KillModuleSubclassing(HMODULE hInst);
+
+///////////////////////////////////////////////////////////////////////////////
+// Windows utilities
+
+MIR_CORE_DLL(BOOL) IsWinVerVistaPlus();
+MIR_CORE_DLL(BOOL) IsWinVer7Plus();
+MIR_CORE_DLL(BOOL) IsWinVer8Plus();
+MIR_CORE_DLL(BOOL) IsWinVer81Plus();
+MIR_CORE_DLL(BOOL) IsWinVer10Plus();
+
+MIR_CORE_DLL(BOOL) IsFullScreen();
+MIR_CORE_DLL(BOOL) IsWorkstationLocked();
+MIR_CORE_DLL(BOOL) IsScreenSaverRunning();
+MIR_CORE_DLL(BOOL) IsTerminalDisconnected();
+
+#endif // _MSC_VER
+
+// returns OS version in version of Windows NT xx.xx
+MIR_CORE_DLL(BOOL) OS_GetShortString(char *buf, size_t bufSize);
+
+// returns full OS version
+MIR_CORE_DLL(BOOL) OS_GetDisplayString(char *buf, size_t bufSize);
+
+///////////////////////////////////////////////////////////////////////////////
+
+MIR_CORE_DLL(void) UnloadCoreModule(void);
+
+#if defined(__cplusplus)
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// The UUID structure below is used to for plugin UUID's and module type definitions
+
+struct MUUID
+{
+ unsigned long a;
+ unsigned short b;
+ unsigned short c;
+ unsigned char d[8];
+};
+
+__forceinline bool operator==(const MUUID& p1, const MUUID& p2)
+{
+ return memcmp(&p1, &p2, sizeof(MUUID)) == 0;
+}
+__forceinline bool operator!=(const MUUID& p1, const MUUID& p2)
+{
+ return memcmp(&p1, &p2, sizeof(MUUID)) != 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// C++ templates
+
+template <typename T>
+HANDLE mir_forkThread(void(MIR_CDECL *pFunc)(T* param), T *arg)
+{
+ return mir_forkthread((pThreadFunc)pFunc, arg);
+}
+
+template <size_t _Size>
+inline int mir_snprintf(_Pre_notnull_ _Always_(_Post_z_) char(&buffer)[_Size], _In_z_ _Printf_format_string_ const char* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ int ret = mir_vsnprintf(buffer, _Size, fmt, args);
+ va_end(args);
+ return ret;
+}
+
+template <size_t _Size>
+inline int mir_snwprintf(_Pre_notnull_ _Always_(_Post_z_) wchar_t(&buffer)[_Size], _In_z_ _Printf_format_string_ const wchar_t* fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ int ret = mir_vsnwprintf(buffer, _Size, fmt, args);
+ va_end(args);
+ return ret;
+}
+
+template <size_t _Size>
+inline int mir_vsnprintf(_Pre_notnull_ _Always_(_Post_z_) char(&buffer)[_Size], _In_z_ _Printf_format_string_ const char* fmt, va_list va)
+{
+ return mir_vsnprintf(buffer, _Size, fmt, va);
+}
+
+template <size_t _Size>
+inline int mir_vsnwprintf(_Pre_notnull_ _Always_(_Post_z_) wchar_t(&buffer)[_Size], _In_z_ _Printf_format_string_ const wchar_t* fmt, va_list va)
+{
+ return mir_vsnwprintf(buffer, _Size, fmt, va);
+}
+
+MIR_CORE_DLL(char *) mir_base64_encode(const class MBinBuffer &buf);
+
+#endif
+
+#ifdef _MSC_VER
+ #ifndef MIR_CORE_EXPORTS
+ #pragma comment(lib, "mir_core.lib")
+ #endif
+
+ #ifndef MIR_APP_EXPORTS
+ #pragma comment(lib, "mir_app.lib")
+ #endif
+#else
+ MIR_CORE_DLL(FILE*) _wfopen(const wchar_t *pwszFileName, const wchar_t *pwszMode);
+ MIR_CORE_DLL(int) _wchdir(const wchar_t *pwszPath);
+
+ template <size_t _Size>
+ inline wchar_t* wcsncpy_s(wchar_t(&buffer)[_Size], const wchar_t *src, size_t len)
+ {
+ return wcsncpy(buffer, src, (len == _TRUNCATE) ? _Size : len);
+ }
+
+ inline wchar_t* wcsncpy_s(wchar_t *dst, size_t dstLen, const wchar_t *src, size_t len)
+ {
+ return wcsncpy(dst, src, (len == _TRUNCATE) ? dstLen : len);
+ }
+
+ inline wchar_t* wcsncat_s(wchar_t *dst, size_t dstLen, const wchar_t *src, size_t len)
+ {
+ return wcsncat(dst, src, (len == _TRUNCATE) ? dstLen : len);
+ }
+
+ template <size_t _Size>
+ inline char* strncpy_s(char(&buffer)[_Size], const char *src, size_t len)
+ {
+ return strncpy(buffer, src, (len == _TRUNCATE) ? _Size : len);
+ }
+
+ inline char* strncpy_s(char *dst, size_t dstLen, const char *src, size_t len)
+ {
+ return strncpy(dst, src, (len == _TRUNCATE) ? dstLen : len);
+ }
+
+ inline char* strncat_s(char *dst, size_t dstLen, const char *src, size_t len)
+ {
+ return strncat(dst, src, (len == _TRUNCATE) ? dstLen : len);
+ }
+#endif
+
+#endif // M_CORE_H
diff --git a/include/m_crypto.h b/include/m_crypto.h index 142236d4cd..3e7f2ffebf 100644 --- a/include/m_crypto.h +++ b/include/m_crypto.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_database.h b/include/m_database.h index 5f2cd63102..d0bc296bd9 100644 --- a/include/m_database.h +++ b/include/m_database.h @@ -1,7 +1,7 @@ ///////////////////////////////////////////////////////////////////////////////////////// // Miranda NG: the free IM client for Microsoft* Windows* // -// Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) +// Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org) // Copyright (c) 2000-08 Miranda ICQ/IM project, // all portions of this codebase are copyrighted to the people // listed in contributors.txt. diff --git a/include/m_db_int.h b/include/m_db_int.h index 19d66ce353..74a1cfc955 100644 --- a/include/m_db_int.h +++ b/include/m_db_int.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows* -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) +Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org) all portions of this codebase are copyrighted to the people listed in contributors.txt. diff --git a/include/m_descbutton.h b/include/m_descbutton.h index 2c5b883938..c922f412d2 100644 --- a/include/m_descbutton.h +++ b/include/m_descbutton.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2007-12 Miranda ICQ/IM project,
Copyright (c) 2007 Artem Shpynov
diff --git a/include/m_email.h b/include/m_email.h index 2bbb299cff..b7e17aaa3a 100644 --- a/include/m_email.h +++ b/include/m_email.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_extraicons.h b/include/m_extraicons.h index d49e31367a..737a449640 100644 --- a/include/m_extraicons.h +++ b/include/m_extraicons.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2009 Ricardo Pescuma Domenecci
This is free software; you can redistribute it and/or
diff --git a/include/m_file.h b/include/m_file.h index 11bf688324..41b4409589 100644 --- a/include/m_file.h +++ b/include/m_file.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_findadd.h b/include/m_findadd.h index 7898361cf8..c8c58b76c4 100644 --- a/include/m_findadd.h +++ b/include/m_findadd.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_gui.h b/include/m_gui.h index 2f1aa7edf4..48041ff696 100644 --- a/include/m_gui.h +++ b/include/m_gui.h @@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua Copyright (c) 2005-12 George Hazan Copyright (c) 2007-09 Maxim Mluhov Copyright (c) 2007-09 Victor Pavlychko -Copyright (C) 2012-22 Miranda NG team +Copyright (C) 2012-23 Miranda NG team This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License diff --git a/include/m_history.h b/include/m_history.h index 943a749611..2fb8c66cd6 100644 --- a/include/m_history.h +++ b/include/m_history.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_hotkeys.h b/include/m_hotkeys.h index 1b9152d12f..fce9552511 100644 --- a/include/m_hotkeys.h +++ b/include/m_hotkeys.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_http.h b/include/m_http.h index 873446279e..4ff992ff2b 100644 --- a/include/m_http.h +++ b/include/m_http.h @@ -1,121 +1,121 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (Å„) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-08 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef M_HTTP_H__ -#define M_HTTP_H__ - -/* List of known http error codes */ - -// 1xx Informational -#define HTTP_CODE_CONTINUE 100 -#define HTTP_CODE_SWITCHING_PROTOCOLS 101 -#define HTTP_CODE_PROCESSING 102 - -// 2xx Success -#define HTTP_CODE_OK 200 -#define HTTP_CODE_CREATED 201 -#define HTTP_CODE_ACCEPTED 202 -#define HTTP_CODE_NON_AUTHORITATIVE_INFORMATION 203 -#define HTTP_CODE_NO_CONTENT 204 -#define HTTP_CODE_RESET_CONTENT 205 -#define HTTP_CODE_PARTIAL_CONTENT 206 -#define HTTP_CODE_MULTI_STATUS 207 - -#define HTTP_CODE_SUCCESS(code) ((code) <= (HTTP_CODE_MULTI_STATUS) && (code) >= (HTTP_CODE_OK)) - -// 3xx Redirection -#define HTTP_CODE_MULTIPLE_CHOICES 300 -#define HTTP_CODE_MOVED_PERMANENTLY 301 -#define HTTP_CODE_FOUND 302 -#define HTTP_CODE_SEE_OTHER 303 -#define HTTP_CODE_NOT_MODIFIED 304 -#define HTTP_CODE_USE_PROXY 305 -#define HTTP_CODE_SWITCH_PROXY 306 -#define HTTP_CODE_TEMPORARY_REDIRECT 307 -#define HTTP_CODE_PERMANENT_REDIRECT 308 - -// 4xx Client Error -#define HTTP_CODE_BAD_REQUEST 400 -#define HTTP_CODE_UNAUTHORIZED 401 -#define HTTP_CODE_PAYMENT_REQUIRED 402 -#define HTTP_CODE_FORBIDDEN 403 -#define HTTP_CODE_NOT_FOUND 404 -#define HTTP_CODE_METHOD_NOT_ALLOWED 405 -#define HTTP_CODE_NOT_ACCEPTABLE 406 -#define HTTP_CODE_PROXY_AUTHENTICATION_REQUIRED 407 -#define HTTP_CODE_REQUEST_TIMEOUT 408 -#define HTTP_CODE_CONFLICT 409 -#define HTTP_CODE_GONE 410 -#define HTTP_CODE_LENGTH_REQUIRED 411 -#define HTTP_CODE_PRECONDITION_FAILED 412 -#define HTTP_CODE_REQUEST_ENTITY_TOO_LARGE 413 -#define HTTP_CODE_REQUEST_URI_TOO_LONG 414 -#define HTTP_CODE_UNSUPPORTED_MEDIA_TYPE 415 -#define HTTP_CODE_REQUESTED_RANGE_NOT_SATISFIABLE 416 -#define HTTP_CODE_EXPECTATION_FAILED 417 -#define HTTP_CODE_IM_A_TEAPOT 418 -#define HTTP_CODE_AUTHENTICATION_TIMEOUT 419 -#define HTTP_CODE_METHOD_FAILURE 420 -#define HTTP_CODE_ENHANCE_YOUR_CALM 420 -#define HTTP_CODE_MISDIRECTED_REQUEST 421 -#define HTTP_CODE_UNPROCESSABLE_ENTITY 422 -#define HTTP_CODE_LOCKED 423 -#define HTTP_CODE_FAILED_DEPENDENCY 424 -#define HTTP_CODE_UNORDERED_COLLECTION 425 -#define HTTP_CODE_UPGRADE_REQUIRED 426 -#define HTTP_CODE_PRECONDITION_REQUIRED 428 -#define HTTP_CODE_TOO_MANY_REQUESTS 429 -#define HTTP_CODE_REQUEST_HEADER_FIELDS_TOO_LARGE 431 -#define HTTP_CODE_LOGIN_TIMEOUT 440 -#define HTTP_CODE_NO_RESPONSE 444 -#define HTTP_CODE_RETRY_WITH 449 -#define HTTP_CODE_BLOCKED_BY_PARENTAL_CONTROL 450 -#define HTTP_CODE_UNAVAILABLE_FOR_LEGAL_REASONS 451 -#define HTTP_CODE_REDIRECT 451 -#define HTTP_CODE_REQUEST_HEADER_TOO_LARGE 494 -#define HTTP_CODE_CERT_ERROR 495 -#define HTTP_CODE_NO_CERT 496 -#define HTTP_CODE_HTTP_TO_HTTPS 497 -#define HTTP_CODE_TOKEN_EXPIRED_INVALID 498 -#define HTTP_CODE_CLIENT_CLOSED_REQUEST 499 -#define HTTP_CODE_TOKEN_REQUIRED 499 - -// 5xx Server Error -#define HTTP_CODE_INTERNAL_SERVER_ERROR 500 -#define HTTP_CODE_NOT_IMPLEMENTED 501 -#define HTTP_CODE_BAD_GATEWAY 502 -#define HTTP_CODE_SERVICE_UNAVAILABLE 503 -#define HTTP_CODE_GATEWAY_TIMEOUT 504 -#define HTTP_CODE_HTTP_VERSION_NOT_SUPPORTED 505 -#define HTTP_CODE_VARIANT_ALSO_NEGOTIATES 506 -#define HTTP_CODE_INSUFFICIENT_STORAGE 507 -#define HTTP_CODE_LOOP_DETECTED 508 -#define HTTP_CODE_BANDWIDTH_LIMIT_EXCEEDED 509 -#define HTTP_CODE_NOT_EXTENDED 510 -#define HTTP_CODE_NETWORK_AUTHENTICATION_REQUIRED 511 -#define HTTP_CODE_WEB_SERVER_IS_DOWN 521 -#define HTTP_CODE_NETWORK_READ_TIMEOUT_ERROR 598 -#define HTTP_CODE_NETWORK_CONNECT_TIMEOUT_ERROR 599 - +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (Å„) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-08 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_HTTP_H__
+#define M_HTTP_H__
+
+/* List of known http error codes */
+
+// 1xx Informational
+#define HTTP_CODE_CONTINUE 100
+#define HTTP_CODE_SWITCHING_PROTOCOLS 101
+#define HTTP_CODE_PROCESSING 102
+
+// 2xx Success
+#define HTTP_CODE_OK 200
+#define HTTP_CODE_CREATED 201
+#define HTTP_CODE_ACCEPTED 202
+#define HTTP_CODE_NON_AUTHORITATIVE_INFORMATION 203
+#define HTTP_CODE_NO_CONTENT 204
+#define HTTP_CODE_RESET_CONTENT 205
+#define HTTP_CODE_PARTIAL_CONTENT 206
+#define HTTP_CODE_MULTI_STATUS 207
+
+#define HTTP_CODE_SUCCESS(code) ((code) <= (HTTP_CODE_MULTI_STATUS) && (code) >= (HTTP_CODE_OK))
+
+// 3xx Redirection
+#define HTTP_CODE_MULTIPLE_CHOICES 300
+#define HTTP_CODE_MOVED_PERMANENTLY 301
+#define HTTP_CODE_FOUND 302
+#define HTTP_CODE_SEE_OTHER 303
+#define HTTP_CODE_NOT_MODIFIED 304
+#define HTTP_CODE_USE_PROXY 305
+#define HTTP_CODE_SWITCH_PROXY 306
+#define HTTP_CODE_TEMPORARY_REDIRECT 307
+#define HTTP_CODE_PERMANENT_REDIRECT 308
+
+// 4xx Client Error
+#define HTTP_CODE_BAD_REQUEST 400
+#define HTTP_CODE_UNAUTHORIZED 401
+#define HTTP_CODE_PAYMENT_REQUIRED 402
+#define HTTP_CODE_FORBIDDEN 403
+#define HTTP_CODE_NOT_FOUND 404
+#define HTTP_CODE_METHOD_NOT_ALLOWED 405
+#define HTTP_CODE_NOT_ACCEPTABLE 406
+#define HTTP_CODE_PROXY_AUTHENTICATION_REQUIRED 407
+#define HTTP_CODE_REQUEST_TIMEOUT 408
+#define HTTP_CODE_CONFLICT 409
+#define HTTP_CODE_GONE 410
+#define HTTP_CODE_LENGTH_REQUIRED 411
+#define HTTP_CODE_PRECONDITION_FAILED 412
+#define HTTP_CODE_REQUEST_ENTITY_TOO_LARGE 413
+#define HTTP_CODE_REQUEST_URI_TOO_LONG 414
+#define HTTP_CODE_UNSUPPORTED_MEDIA_TYPE 415
+#define HTTP_CODE_REQUESTED_RANGE_NOT_SATISFIABLE 416
+#define HTTP_CODE_EXPECTATION_FAILED 417
+#define HTTP_CODE_IM_A_TEAPOT 418
+#define HTTP_CODE_AUTHENTICATION_TIMEOUT 419
+#define HTTP_CODE_METHOD_FAILURE 420
+#define HTTP_CODE_ENHANCE_YOUR_CALM 420
+#define HTTP_CODE_MISDIRECTED_REQUEST 421
+#define HTTP_CODE_UNPROCESSABLE_ENTITY 422
+#define HTTP_CODE_LOCKED 423
+#define HTTP_CODE_FAILED_DEPENDENCY 424
+#define HTTP_CODE_UNORDERED_COLLECTION 425
+#define HTTP_CODE_UPGRADE_REQUIRED 426
+#define HTTP_CODE_PRECONDITION_REQUIRED 428
+#define HTTP_CODE_TOO_MANY_REQUESTS 429
+#define HTTP_CODE_REQUEST_HEADER_FIELDS_TOO_LARGE 431
+#define HTTP_CODE_LOGIN_TIMEOUT 440
+#define HTTP_CODE_NO_RESPONSE 444
+#define HTTP_CODE_RETRY_WITH 449
+#define HTTP_CODE_BLOCKED_BY_PARENTAL_CONTROL 450
+#define HTTP_CODE_UNAVAILABLE_FOR_LEGAL_REASONS 451
+#define HTTP_CODE_REDIRECT 451
+#define HTTP_CODE_REQUEST_HEADER_TOO_LARGE 494
+#define HTTP_CODE_CERT_ERROR 495
+#define HTTP_CODE_NO_CERT 496
+#define HTTP_CODE_HTTP_TO_HTTPS 497
+#define HTTP_CODE_TOKEN_EXPIRED_INVALID 498
+#define HTTP_CODE_CLIENT_CLOSED_REQUEST 499
+#define HTTP_CODE_TOKEN_REQUIRED 499
+
+// 5xx Server Error
+#define HTTP_CODE_INTERNAL_SERVER_ERROR 500
+#define HTTP_CODE_NOT_IMPLEMENTED 501
+#define HTTP_CODE_BAD_GATEWAY 502
+#define HTTP_CODE_SERVICE_UNAVAILABLE 503
+#define HTTP_CODE_GATEWAY_TIMEOUT 504
+#define HTTP_CODE_HTTP_VERSION_NOT_SUPPORTED 505
+#define HTTP_CODE_VARIANT_ALSO_NEGOTIATES 506
+#define HTTP_CODE_INSUFFICIENT_STORAGE 507
+#define HTTP_CODE_LOOP_DETECTED 508
+#define HTTP_CODE_BANDWIDTH_LIMIT_EXCEEDED 509
+#define HTTP_CODE_NOT_EXTENDED 510
+#define HTTP_CODE_NETWORK_AUTHENTICATION_REQUIRED 511
+#define HTTP_CODE_WEB_SERVER_IS_DOWN 521
+#define HTTP_CODE_NETWORK_READ_TIMEOUT_ERROR 598
+#define HTTP_CODE_NETWORK_CONNECT_TIMEOUT_ERROR 599
+
#endif // M_HTTP_H__
\ No newline at end of file diff --git a/include/m_icolib.h b/include/m_icolib.h index 07255a5a4b..6f51d04250 100644 --- a/include/m_icolib.h +++ b/include/m_icolib.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_idle.h b/include/m_idle.h index 2c6d466d77..8725aaa715 100644 --- a/include/m_idle.h +++ b/include/m_idle.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-05 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_ignore.h b/include/m_ignore.h index e5e97b8ea3..03c5b4c39b 100644 --- a/include/m_ignore.h +++ b/include/m_ignore.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_imgsrvc.h b/include/m_imgsrvc.h index 1f347be779..012fdd5571 100644 --- a/include/m_imgsrvc.h +++ b/include/m_imgsrvc.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-12 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_import.h b/include/m_import.h index 6bfcc63de2..296e99dbae 100644 --- a/include/m_import.h +++ b/include/m_import.h @@ -1,59 +1,59 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-08 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef M_IMPORT_H__ -#define M_IMPORT_H__ 1 - -// launches the import wizard with given file name & options -// always returns 0 - -// Custom import options -#define IOPT_ADDUNKNOWN 0x00000001 -#define IOPT_MSGSENT 0x00000002 -#define IOPT_MSGRECV 0x00000004 -#define IOPT_AUTHREQ 0x00000020 -#define IOPT_ADDED 0x00000040 -#define IOPT_FILESENT 0x00000080 -#define IOPT_FILERECV 0x00000100 -#define IOPT_OTHERSENT 0x00000200 -#define IOPT_OTHERRECV 0x00000400 -#define IOPT_HISTORY 0x000007FE - -#define IOPT_SYSTEM 0x00000800 -#define IOPT_CONTACTS 0x00001000 -#define IOPT_GROUPS 0x00002000 -#define IOPT_SYS_SETTINGS 0x00004000 -#define IOPT_COMPLETE 0x00007FFE - -#define IOPT_CHECKDUPS 0x00010000 - -struct MImportOptions -{ - const wchar_t *pwszFileName; - uint32_t dwFlags; // IOPT_* flags combination -}; - -#define MS_IMPORT_RUN "Import/Run" - -#endif // M_IMPORT_H__ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-08 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_IMPORT_H__
+#define M_IMPORT_H__ 1
+
+// launches the import wizard with given file name & options
+// always returns 0
+
+// Custom import options
+#define IOPT_ADDUNKNOWN 0x00000001
+#define IOPT_MSGSENT 0x00000002
+#define IOPT_MSGRECV 0x00000004
+#define IOPT_AUTHREQ 0x00000020
+#define IOPT_ADDED 0x00000040
+#define IOPT_FILESENT 0x00000080
+#define IOPT_FILERECV 0x00000100
+#define IOPT_OTHERSENT 0x00000200
+#define IOPT_OTHERRECV 0x00000400
+#define IOPT_HISTORY 0x000007FE
+
+#define IOPT_SYSTEM 0x00000800
+#define IOPT_CONTACTS 0x00001000
+#define IOPT_GROUPS 0x00002000
+#define IOPT_SYS_SETTINGS 0x00004000
+#define IOPT_COMPLETE 0x00007FFE
+
+#define IOPT_CHECKDUPS 0x00010000
+
+struct MImportOptions
+{
+ const wchar_t *pwszFileName;
+ uint32_t dwFlags; // IOPT_* flags combination
+};
+
+#define MS_IMPORT_RUN "Import/Run"
+
+#endif // M_IMPORT_H__
diff --git a/include/m_jabber.h b/include/m_jabber.h index 22ad790591..54cef3d584 100644 --- a/include/m_jabber.h +++ b/include/m_jabber.h @@ -6,7 +6,7 @@ Copyright (c) 2002-04 Santithorn Bunchua Copyright (c) 2005-08 George Hazan
Copyright (c) 2007 Maxim Mluhov
Copyright (c) 2008-09 Dmitriy Chervov
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/include/m_json.h b/include/m_json.h index e9a0545217..f87e01bf82 100644 --- a/include/m_json.h +++ b/include/m_json.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_langpack.h b/include/m_langpack.h index e879b9925a..26f37ff380 100644 --- a/include/m_langpack.h +++ b/include/m_langpack.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-12 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_message.h b/include/m_message.h index 731314d8a1..1adc08a5e2 100644 --- a/include/m_message.h +++ b/include/m_message.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_metacontacts.h b/include/m_metacontacts.h index b73c14346d..01388f72ce 100644 --- a/include/m_metacontacts.h +++ b/include/m_metacontacts.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org),
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org),
Copyright (c) 2004-07 Scott Ellis (www.scottellis.com.au mail@scottellis.com.au)
Copyright (c) 2004 Universite Louis PASTEUR, STRASBOURG.
diff --git a/include/m_netlib.h b/include/m_netlib.h index b36badd926..b2f52be372 100644 --- a/include/m_netlib.h +++ b/include/m_netlib.h @@ -1,852 +1,852 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-12 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef M_NETLIB_H__ -#define M_NETLIB_H__ 1 - -#include "m_utils.h" - -///////////////////////////////////////////////////////////////////////////////////////// -// this module was created in 0.1.2.2 -// All error codes are returned via GetLastError() (or WSAGetLastError(): -// they're the same). -// This module is thread-safe where it is sensible for it to be so. This -// basically means that you can call anything from any thread, but don't try -// to predict what will happen if you try to recv() on the same connection from -// two different threads at the same time. -// Note that because the vast majority of the routines in this module return -// a pointer, I have decided to diverge from the rest of Miranda and go with -// the convention that functions return false on failure and nonzero on success. - -struct NETLIBHTTPREQUEST; -struct NETLIBOPENCONNECTION; - -#define NETLIB_USER_AGENT "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.112 Safari/537.36" - -///////////////////////////////////////////////////////////////////////////////////////// -// Initialises the netlib for a set of connections -// Returns a HNETLIBUSER to be used for future netlib calls, NULL on failure -// NOTE: Netlib is loaded after any plugins, so you need to wait until -// ME_SYSTEM_MODULESLOADED before calling this function -// Netlib settings are stored under the module szSettingsModule -// All netlib settings being with "NL". -// The default settings for registered users that don't have any settings stored -// in the database are the same as those displayed by the <All connections> page -// of the netlib options page. -// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY, ERROR_DUP_NAME - -struct NETLIBUSER -{ - char *szSettingsModule; // used for db settings and log - MAllStrings szDescriptiveName; // used in options dialog, already translated - uint32_t flags; - int minIncomingPorts; // only if NUF_INCOMING. Will be used for validation of user input. -}; - -#define NUF_INCOMING 0x01 // binds incoming ports -#define NUF_OUTGOING 0x02 // makes outgoing plain connections -#define NUF_NOOPTIONS 0x08 // don't create an options page for this. szDescriptiveName is never used. -#define NUF_HTTPCONNS 0x10 // at least some connections are made for HTTP communication. Enables the HTTP proxy option in options. -#define NUF_NOHTTPSOPTION 0x20 // disable the HTTPS proxy option in options. Use this if all communication is HTTP. -#define NUF_UNICODE 0x40 // if set ptszDescriptiveName points to Unicode, otherwise it points to ANSI string - -EXTERN_C MIR_APP_DLL(HNETLIBUSER) Netlib_RegisterUser(const NETLIBUSER *pDescr); - -///////////////////////////////////////////////////////////////////////////////////////// -// Assign a Netlib user handle a set of dynamic HTTP headers to be used with all -// -// HTTP connections that enable the HTTP-use-sticky headers flag. -// The headers persist until cleared with lParam = NULL. -// -// All memory should be allocated by the caller using malloc() from MS_SYSTEM_GET_MMI -// Once it has passed to Netlib, Netlib is the owner of it, the caller should not refer to the memory -// In any way after this point. -// -// NOTE: The szHeaders parameter should be a NULL terminated string following the HTTP header syntax. -// This string will be injected verbatim, thus the user should be aware of setting strings that are not -// headers. This service is NOT THREAD SAFE, only a single thread is expected to set the headers and a single -// thread reading the pointer internally, stopping race conditions and mutual exclusion don't happen. -// -// Version 0.3.2a+ (2003/10/27) -// - -EXTERN_C MIR_APP_DLL(int) Netlib_SetStickyHeaders(HNETLIBUSER nlu, const char *szHeaders); - -/* Notes on HTTP gateway usage -When a connection is initiated through an HTTP proxy using -MS_NETLIB_OPENCONNECTION, netlib will GET nlu.szHttpGatewayHello and read -the replied headers. Once this succeeds nlu.pfnHttpGatewayInit will be called -with a valid handle to the connection, the NETLIBOPENCONNECTION structure that -MS_NETLIB_OPENCONNECTION was called with, and the replied HTTP headers as its -parameters. This function is responsible for recving and parsing the data then -calling MS_NETLIB_SETHTTPPROXYINFO with the appropriate information. -nlu.pfnHttpGatewayInit should return nonzero on success. If it returns zero -then the entire connection attempt will return signalling failure. If your -function needs to return an error code it can do so via SetLastError(). -If nlu.pfnHttpGatewayInit returns success without having called -MS_NETLIB_SETHTTPPROXYINFO then the connection attempt will fail anyway. -If you need more fine-tuned control over the GET/POST URLs than just appending -sequence numbers you can call MS_NETLIB_SETHTTPPROXYINFO from within your -wrap/unwrap functions (see below). - -Just prior to MS_NETLIB_OPENCONNECTION returning nlu.pfnHttpGatewayBegin is -called with the handle to the connection and the NETLIBOPENCONNECTION structure -as its parameters. This is for gateways that need special non-protocol -initialisation. If you do send any packets in this function, you probably want -to remember to use the MSG_NOHTTPGATEWAYWRAP flag. This function pointer can be -NULL if this functionality isn't needed. This function must return nonzero on -success. If it fails the connect attempt will return failure without changing -LastError. - -Whenever MS_NETLIB_SEND is called on a connection through an HTTP proxy and -the MSG_NOHTTPGATEWAYWRAP flags is not set and nlu.pfnHttpGatewayWrapSend is -not NULL, nlu.pfnHttpGatewayWrapSend will be called *instead* of sending the -data. It is this function's responsibility to wrap the sending data -appropriately for transmission and call pfnNetlibSend to send it again. -The flags parameter to nlu.pfnHttpGatewayWrapSend should be passed straight -through to the pfnNetlibSend call. It has already been ORed with -MSG_NOHTTPGATEWAYWRAP. nlu.pfnHttpGatewayWrapSend should return the a -number of the same type as MS_NETLIB_SEND, ie the number of bytes sent or -SOCKET_ERROR. The number of wrapping bytes should be subtracted so that the -return value appears as if the proxy wasn't there. -pfnNetlibSend() is identical to CallService(MS_NETLIB_SEND, ...) but it's -quicker to call using this pointer than to do the CallService() lookup again. - -Whenever an HTTP reply is received inside MS_NETLIB_RECV the headers and data -are read into memory. If the headers indicate success then the data is passed -to nlu.pfnHttpGatewayUnwrapRecv (if it's non-NULL) for processing. This -function should remove (and do other processing if necessary) all HTTP proxy -specific headers and return a pointer to the buffer whose size is returned in -*outBufLen. If the buffer needs to be resized then NetlibRealloc() should be -used for that purpose, *not* your own CRT's realloc(). NetlibRealloc() behaves -identically to realloc() so it's possible to free the original buffer and -create a new one if that's the most sensible way to write your parser. -If errors are encountered you should SetLastError() and return NULL; -MS_NETLIB_RECV will return SOCKET_ERROR. If the passed buffer unwraps to -contain no actual data you should set *outBufLen to 0 but make sure you return -some non-NULL buffer that can be freed. - -When you call MS_NETLIB_SEND or MS_NETLIB_RECV from any of these functions, you -should use the MSG_DUMPPROXY flag so that the logging is neat. -*/ - -#define PROXYTYPE_SOCKS4 1 -#define PROXYTYPE_SOCKS5 2 -#define PROXYTYPE_HTTP 3 -#define PROXYTYPE_HTTPS 4 -#define PROXYTYPE_IE 5 - -struct NETLIBUSERSETTINGS -{ - int cbSize; // to be filled in before calling - int useProxy; // 1 or 0 - int proxyType; // a PROXYTYPE_ - char *szProxyServer; // can be NULL - int wProxyPort; // host byte order - int useProxyAuth; // 1 or 0. Always 0 for SOCKS4 - char *szProxyAuthUser; // can be NULL, always used by SOCKS4 - char *szProxyAuthPassword; // can be NULL - int useProxyAuthNtlm; // 1 or 0, only used by HTTP, HTTPS - int dnsThroughProxy; // 1 or 0 - int specifyIncomingPorts; // 1 or 0 - char *szIncomingPorts; // can be NULL. Of form "1024-1050, 1060-1070, 2000" - int specifyOutgoingPorts; // 0.3.3a+ - char *szOutgoingPorts; // 0.3.3a+ - int enableUPnP; // 0.6.1+ only for NUF_INCOMING - int validateSSL; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Gets the user-configured settings for a netlib user -// -// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib) -// The pointers referred to in the returned struct will remain valid until -// the hUser handle is closed, or until the user changes the settings in the -// options page, so it's best not to rely on them for too long. -// Errors: ERROR_INVALID_PARAMETER - -EXTERN_C MIR_APP_DLL(int) Netlib_GetUserSettings(HNETLIBUSER nlu, NETLIBUSERSETTINGS *result); - -///////////////////////////////////////////////////////////////////////////////////////// -//Gets the user-configured settings for a netlib user idetified by name -// -//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib) -//This function behaves like Netlib_GetUserSettings but the user is identified -//by the name provided by registration. When the name is not found NETLIBUSERSETTINGS is set to NULL. -//Errors: ERROR_INVALID_PARAMETER - -EXTERN_C MIR_APP_DLL(int) Netlib_GetUserSettingsByName(char * UserSettingsName, NETLIBUSERSETTINGS *result); - -///////////////////////////////////////////////////////////////////////////////////////// -// Changes the user-configurable settings for a netlib user -// -// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib) -// This function is only really useful for people that specify NUF_NOOPTIONS -// and want to create their own options. -// Even if a setting is not active (eg szProxyAuthPassword when useProxyAuth is -// zero) that settings is still set for use in the options dialog. -// Errors: ERROR_INVALID_PARAMETER - -EXTERN_C MIR_APP_DLL(int) Netlib_SetUserSettings(HNETLIBUSER nlu, const NETLIBUSERSETTINGS *result); - -///////////////////////////////////////////////////////////////////////////////////////// -//Changes the user-configurable settings for a netlib user idetified by name -// -//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib) -//This function behaves like Netlib_SetUserSettings but the user is identified -//by the name provided by registration. Nothing will be changed when the name is not found. -//Errors: ERROR_INVALID_PARAMETER - -EXTERN_C MIR_APP_DLL(int) Netlib_SetUserSettingsByName(char * UserSettingsName, NETLIBUSERSETTINGS *result); - -///////////////////////////////////////////////////////////////////////////////////////// -// Closes a netlib handle -// -// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib) -// This function should be called on all handles returned by netlib functions -// once you are done with them. If it's called on a socket-type handle, the -// socket will be closed. -// Errors: ERROR_INVALID_PARAMETER - -EXTERN_C MIR_APP_DLL(int) Netlib_CloseHandle(HANDLE h); - -///////////////////////////////////////////////////////////////////////////////////////// -// Open a port and wait for connections on it -// -// Returns a HANDLE on success, NULL on failure -// hUser should have been returned by MS_NETLIB_REGISTERUSER -// This function does the equivalent of socket(), bind(), getsockname(), -// listen(), accept() -// Internally this function creates a new thread which waits around in accept() -// for new connections. When one is received it calls nlb.pfnNewConnection *from -// this new thread* and then loops back to wait again. -// Close the returned handle to end the thread and close the open port. -// Errors: ERROR_INVALID_PARAMETER, any returned by socket() or bind() or -// listen() or getsockname() -// -// Notes: -// -// During development of 0.3.1a+ (2003/07/04) passing wPort != 0 -// will result in an attempt to bind on the port given in wPort -// if this port is taken then you will get an error, so be sure to check -// for such conditions. -// -// passing wPort != 0 is for people who need to open a set port for -// daemon activities, usually passing wPort == 0 is what you want and -// will result in a free port given by the TCP/IP socket layer and/or -// seeded from the user selected port ranges. -// -// also note that wPort if != 0, will have be converted to network byte order -// -/* pExtra was added during 0.3.4+, prior its just two args, since we use the cdecl convention -it shouldnt matter */ - -typedef void (*NETLIBNEWCONNECTIONPROC)(HNETLIBCONN hNewConnection, uint32_t dwRemoteIP, void *pExtra); - -struct NETLIBBIND -{ - NETLIBNEWCONNECTIONPROC pfnNewConnection; - - // function to call when there's a new connection. Params are: the - // new connection, IP of remote machine (host byte order) - uint32_t dwInternalIP; // set on return, host byte order - uint32_t dwExternalIP; // set on return, host byte order - uint16_t wPort, wExPort; // set on return, host byte order - void *pExtra; // argument is sent to callback -}; - -EXTERN_C MIR_APP_DLL(HNETLIBBIND) Netlib_BindPort(HNETLIBUSER nlu, NETLIBBIND *nlb); - -///////////////////////////////////////////////////////////////////////////////////////// -// Open a connection -// -// Returns a HNETLIBCONN to the new connection on success, NULL on failure -// hUser must have been returned by MS_NETLIB_REGISTERUSER -// Internally this function is the equivalent of socket(), gethostbyname(), -// connect() -// If NLOCF_HTTP is set and hUser is configured for an HTTP or HTTPS proxy then -// this function will connect() to the proxy server only, without performing any -// initialisation conversation. -// If hUser is configured for an HTTP proxy and does not support HTTP gateways -// and you try to open a connection without specifying NLOCF_HTTP then this -// function will first attempt to open an HTTPS connection, if that fails it -// will try a direct connection, if that fails it will return failure with the -// error from the connect() during the direct connection attempt. -// Errors: ERROR_INVALID_PARAMETER, any returned by socket(), gethostbyname(), -// connect(), MS_NETLIB_SEND, MS_NETLIB_RECV, select() -// ERROR_TIMEOUT (during proxy communication) -// ERROR_BAD_FORMAT (very invalid proxy reply) -// ERROR_ACCESS_DENIED (by proxy) -// ERROR_CONNECTION_UNAVAIL (socks proxy can't connect to identd) -// ERROR_INVALID_ACCESS (proxy refused identd auth) -// ERROR_INVALID_DATA (proxy returned invalid code) -// ERROR_INVALID_ID_AUTHORITY (proxy requires use of auth method that's not supported) -// ERROR_GEN_FAILURE (socks5/https general failure) -// ERROR_CALL_NOT_IMPLEMENTED (socks5 command not supported) -// ERROR_INVALID_ADDRESS (socks5 address type not supported) -// HTTP: anything from nlu.pfnHttpGatewayInit, nlu.pfnHttpGatewayBegin, -// MS_NETLIB_SENDHTTPREQUEST or MS_NETLIB_RECVHTTPHEADERS - -#define NLOCF_HTTP 0x0001 // this connection will be used for HTTP communications. If configured for an HTTP/HTTPS proxy the connection is opened as if there was no proxy. -#define NLOCF_STICKYHEADERS 0x0002 // this connection should send the sticky headers associated with NetLib user apart of any HTTP request -#define NLOCF_UDP 0x0008 // this connection is UDP -#define NLOCF_SSL 0x0010 // this connection is SSL - -EXTERN_C MIR_APP_DLL(HNETLIBCONN) Netlib_OpenConnection(HNETLIBUSER nlu, const char *szHost, int port, int timeout = 0, int flags = 0); - -///////////////////////////////////////////////////////////////////////////////////////// -// Sets the required information for an HTTP proxy connection -// -// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib) -// This function is designed to be called from within pfnHttpGatewayInit -// See notes below MS_NETLIB_REGISTERUSER. -// Errors: ERROR_INVALID_PARAMETER - -#define NLHPIF_USEGETSEQUENCE 0x0001 // append sequence numbers to GET requests -#define NLHPIF_USEPOSTSEQUENCE 0x0002 // append sequence numbers to POST requests -#define NLHPIF_GETPOSTSAMESEQUENCE 0x0004 // GET and POST use the same sequence -#define NLHPIF_HTTP11 0x0008 // HTTP 1.1 proxy - -struct NETLIBHTTPPROXYINFO -{ - uint32_t flags; - int firstGetSequence, firstPostSequence; - int combinePackets; - char *szHttpPostUrl; - char *szHttpGetUrl; -}; - -EXTERN_C MIR_APP_DLL(int) Netlib_SetHttpProxyInfo(HNETLIBCONN hConnection, const NETLIBHTTPPROXYINFO *nlhpi); - -///////////////////////////////////////////////////////////////////////////////////////// -// Gets the SOCKET associated with a netlib handle -// -// Returns the SOCKET on success, INVALID_SOCKET on failure -// hNetlibHandle should have been returned by MS_NETLIB_BINDPORT or -// MS_NETLIB_OPENCONNECTION only. -// Be careful how you use this socket because you might be connected via an -// HTTP proxy in which case calling send() or recv() will totally break things. -// Errors: ERROR_INVALID_PARAMETER - -EXTERN_C MIR_APP_DLL(UINT_PTR) Netlib_GetSocket(HNETLIBCONN hConnection); - -///////////////////////////////////////////////////////////////////////////////////////// - -#define Netlib_GetBase64DecodedBufferSize(cchEncoded) (((cchEncoded)>>2)*3) -#define Netlib_GetBase64EncodedBufferSize(cbDecoded) (((cbDecoded)*4+11)/12*4+1) - -///////////////////////////////////////////////////////////////////////////////////////// -// Gets HNETLIBUSER owner of a connection - -EXTERN_C MIR_APP_DLL(HNETLIBUSER) Netlib_GetConnNlu(HNETLIBCONN hConn); - -///////////////////////////////////////////////////////////////////////////////////////// -// Gets the fake User-Agent header field to make some sites happy - -EXTERN_C MIR_APP_DLL(char*) Netlib_GetUserAgent(); - -///////////////////////////////////////////////////////////////////////////////////////// -// Converts numerical representation of IP in SOCKADDR_INET into string representation with IP and port -// IPv4 will be supplied in formats address:port or address -// IPv6 will be supplied in formats [address]:port or [address] -// Returns pointer to the string or NULL if not successful - -struct sockaddr_in; -EXTERN_C MIR_APP_DLL(char*) Netlib_AddressToString(sockaddr_in *addr); -EXTERN_C MIR_APP_DLL(bool) Netlib_StringToAddress(const char *str, sockaddr_in *addr); - -///////////////////////////////////////////////////////////////////////////////////////// -// Gets connection Information -// IPv4 will be supplied in formats address:port or address -// IPv6 will be supplied in formats [address]:port or [address] -// Returns 0 if successful - -struct NETLIBCONNINFO -{ - char szIpPort[64]; - unsigned dwIpv4; - uint16_t wPort; -}; - -EXTERN_C MIR_APP_DLL(int) Netlib_GetConnectionInfo(HNETLIBCONN hConnection, NETLIBCONNINFO *connInfo); - -///////////////////////////////////////////////////////////////////////////////////////// -// Gets connection Information -// -// Returns (INT_PTR)(NETLIBIPLIST*) numeric IP address address array -// the last element of the array is all 0s, 0 if not successful - -struct NETLIBIPLIST -{ - unsigned cbNum; - char szIp[1][64]; -}; - -EXTERN_C MIR_APP_DLL(NETLIBIPLIST*) Netlib_GetMyIp(bool bGlobalOnly); - -///////////////////////////////////////////////////////////////////////////////////////// -// Send an HTTP request over a connection -// -// Returns number of bytes sent on success, SOCKET_ERROR on failure -// hConnection must have been returned by MS_NETLIB_OPENCONNECTION -// Note that if you use NLHRF_SMARTAUTHHEADER and NTLM authentication is in use -// then the full NTLM authentication transaction occurs, comprising sending the -// domain, receiving the challenge, then sending the response. -// nlhr.resultCode and nlhr.szResultDescr are ignored by this function. -// Errors: ERROR_INVALID_PARAMETER, anything returned by MS_NETLIB_SEND - -struct NETLIBHTTPHEADER -{ - char *szName; - char *szValue; -}; - -EXTERN_C MIR_APP_DLL(char*) Netlib_GetHeader(const NETLIBHTTPREQUEST *pRec, const char *pszName); - -///////////////////////////////////////////////////////////////////////////////////////// - -#define REQUEST_RESPONSE 0 // used by structure returned by MS_NETLIB_RECVHTTPHEADERS -#define REQUEST_GET 1 -#define REQUEST_POST 2 -#define REQUEST_CONNECT 3 -#define REQUEST_HEAD 4 -#define REQUEST_PUT 5 -#define REQUEST_DELETE 6 -#define REQUEST_PATCH 7 - -#define NLHRF_MANUALHOST 0x00000001 // do not remove any host and/or protocol portion of szUrl before sending it -#define NLHRF_HTTP11 0x00000010 // use HTTP 1.1 -#define NLHRF_PERSISTENT 0x00000020 // preserve connection on exit, open connection provided in the nlc field of the reply - // it should be supplied in nlc field of request for reuse or closed if not needed -#define NLHRF_SSL 0x00000040 // use SSL connection -#define NLHRF_NOPROXY 0x00000080 // do not use proxy server -#define NLHRF_REDIRECT 0x00000100 // handle HTTP redirect requests (response 30x), the resulting url provided in szUrl of the response -#define NLHRF_NODUMP 0x00010000 // never dump this to the log -#define NLHRF_NODUMPHEADERS 0x00020000 // don't dump http headers (only useful for POSTs and MS_NETLIB_HTTPTRANSACTION) -#define NLHRF_DUMPPROXY 0x00040000 // this transaction is a proxy communication. For dump filtering only. -#define NLHRF_DUMPASTEXT 0x00080000 // dump posted and reply data as text. Headers are always dumped as text. -#define NLHRF_NODUMPSEND 0x00100000 // do not dump sent message. - -struct NETLIBHTTPREQUEST -{ - int cbSize; - int requestType; // a REQUEST_ - uint32_t flags; - char *szUrl; - NETLIBHTTPHEADER *headers; // If this is a POST request and headers doesn't contain a Content-Length it'll be added automatically - int headersCount; - char *pData; // data to be sent in POST request. - int dataLength; // must be 0 for REQUEST_GET/REQUEST_CONNECT - int resultCode; - char *szResultDescr; - HNETLIBCONN nlc; - int timeout; - - __forceinline const char *operator[](const char *pszName) { - return Netlib_GetHeader(this, pszName); - } -}; - -EXTERN_C MIR_APP_DLL(int) Netlib_SendHttpRequest(HNETLIBCONN hConnection, NETLIBHTTPREQUEST *pRec); - -///////////////////////////////////////////////////////////////////////////////////////// -// Receives HTTP headers -// -// Returns a pointer to a NETLIBHTTPREQUEST structure on success, NULL on failure. -// Call Netlib_FreeHttpRequest() to free this. -// hConnection must have been returned by MS_NETLIB_OPENCONNECTION -// nlhr->pData = NULL and nlhr->dataLength = 0 always. The requested data should -// be retrieved using MS_NETLIB_RECV once the header has been parsed. -// If the headers haven't finished within 60 seconds the function returns NULL -// and ERROR_TIMEOUT. -// Errors: ERROR_INVALID_PARAMETER, any from MS_NETLIB_RECV or select() -// ERROR_HANDLE_EOF (connection closed before headers complete) -// ERROR_TIMEOUT (headers still not complete after 60 seconds) -// ERROR_BAD_FORMAT (invalid character or line ending in headers, or first line is blank) -// ERROR_BUFFER_OVERFLOW (each header line must be less than 4096 chars long) -// ERROR_INVALID_DATA (first header line is malformed ("http/[01].[0-9] [0-9]+ .*", or no colon in subsequent line) - -EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) Netlib_RecvHttpHeaders(HNETLIBCONN hConnection, int flags = 0); - -///////////////////////////////////////////////////////////////////////////////////////// -// Free the memory used by a NETLIBHTTPREQUEST structure -// -// Returns true on success, false on failure (!! this is different to most of the rest of Miranda, but consistent with netlib) -// This should only be called on structures returned by -// MS_NETLIB_RECVHTTPHEADERS or MS_NETLIB_HTTPTRANSACTION. Calling it on an -// arbitrary structure will have disastrous results. -// Errors: ERROR_INVALID_PARAMETER - -EXTERN_C MIR_APP_DLL(bool) Netlib_FreeHttpRequest(NETLIBHTTPREQUEST*); - -///////////////////////////////////////////////////////////////////////////////////////// -// smart pointer for NETLIBHTTPREQUEST via a call of Netlib_FreeHttpRequest() - -#ifdef __cplusplus -class NLHR_PTR -{ -protected: - NETLIBHTTPREQUEST *_p; - -public: - __forceinline explicit NLHR_PTR(NETLIBHTTPREQUEST *p) : _p(p) {} - - __forceinline NETLIBHTTPREQUEST* operator=(INT_PTR i_p) - { - return operator=((NETLIBHTTPREQUEST*)i_p); - } - __forceinline NETLIBHTTPREQUEST* operator=(NETLIBHTTPREQUEST *p) - { - if (_p) - Netlib_FreeHttpRequest(_p); - _p = p; - return _p; - } - __forceinline operator NETLIBHTTPREQUEST*() const { return _p; } - __forceinline NETLIBHTTPREQUEST* operator->() const { return _p; } - __forceinline ~NLHR_PTR() - { - Netlib_FreeHttpRequest(_p); - } -}; - -struct MIR_APP_EXPORT MHttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject -{ - MHttpRequest(); - ~MHttpRequest(); - - CMStringA m_szUrl; - CMStringA m_szParam; - void *pUserInfo = nullptr; - - void AddHeader(const char *szName, const char *szValue); -}; - -template <class T> -class MTHttpRequest : public MHttpRequest -{ -public: - __forceinline MTHttpRequest() - {} - - typedef void (T::*MTHttpRequestHandler)(NETLIBHTTPREQUEST*, struct AsyncHttpRequest*); - MTHttpRequestHandler m_pFunc = nullptr; -}; - -MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const INT_PARAM&); -MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const INT64_PARAM&); -MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const CHAR_PARAM&); -MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const WCHAR_PARAM&); - -#endif - -///////////////////////////////////////////////////////////////////////////////////////// -// Do an entire HTTP transaction -// -// Returns a pointer to another NETLIBHTTPREQUEST structure on success, NULL on failure. -// Call Netlib_FreeHttpRequest() to free this. -// hUser must have been returned by MS_NETLIB_REGISTERUSER -// nlhr.szUrl should be a full HTTP URL. If it does not start with http:// , that -// will be assumed (but it's best not to use this fact, for reasons of -// extensibility). -// This function is the equivalent of MS_NETLIB_OPENCONNECTION, -// MS_NETLIB_SENDHTTPREQ, MS_NETLIB_RECVHTTPHEADERS, MS_NETLIB_RECV, -// MS_NETLIB_CLOSEHANDLE -// nlhr.headers will be augmented with the following headers unless they have -// already been set by the caller: -// "Host" (regardless of whether it is requested in nlhr.flags) -// "User-Agent" (of the form "Miranda/0.1.2.2 (alpha)" or "Miranda/0.1.2.2") -// "Content-Length" (for POSTs only. Set to nlhr.dataLength) -// If you do not want to send one of these headers, create a nlhr.headers with -// szValue = NULL. -// In the return value headers, headerCount, pData, dataLength, resultCode and -// szResultDescr are all valid. -// In the return value pData[dataLength] == 0 always, as an extra safeguard -// against programming slips. -// Note that the function can succeed (ie not return NULL) yet result in an HTTP -// error code. You should check that resultCode == 2xx before proceeding. -// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY, anything from the above -// list of functions - -EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) Netlib_HttpTransaction(HNETLIBUSER hNlu, NETLIBHTTPREQUEST *pRequest); - -///////////////////////////////////////////////////////////////////////////////////////// -// Send data over a connection -// -// Returns the number of bytes sent on success, SOCKET_ERROR on failure -// Errors: ERROR_INVALID_PARAMETER -// anything from send(), nlu.pfnHttpGatewayWrapSend() -// HTTP proxy: ERROR_GEN_FAILURE (http result code wasn't 2xx) -// anything from socket(), connect(), -// MS_NETLIB_SENDHTTPREQUEST, MS_NETLIB_RECVHTTPHEADERS -// flags: - -#define MSG_NOHTTPGATEWAYWRAP 0x010000 // don't wrap the outgoing packet using nlu.pfnHttpGatewayWrapSend -#define MSG_NODUMP 0x020000 // don't dump this packet to the log -#define MSG_DUMPPROXY 0x040000 // this is proxy communiciation. For dump filtering only. -#define MSG_DUMPASTEXT 0x080000 // this is textual data, don't dump as hex -#define MSG_RAW 0x100000 // send as raw data, bypass any HTTP proxy stuff -#define MSG_DUMPSSL 0x200000 // this is SSL traffic. For dump filtering only. -#define MSG_NOTITLE 0x400000 // skip date, time & protocol from dump - -EXTERN_C MIR_APP_DLL(int) Netlib_Send(HNETLIBCONN hConn, const char *buf, int len, int flags = 0); - -///////////////////////////////////////////////////////////////////////////////////////// -// Receive data over a connection -// -// Returns the number of bytes read on success, SOCKET_ERROR on failure, -// 0 if the connection has been closed -// Flags supported: MSG_PEEK, MSG_NODUMP, MSG_DUMPPROXY, MSG_NOHTTPGATEWAYWRAP, -// MSG_DUMPASTEXT, MSG_RAW -// On using MSG_NOHTTPGATEWAYWRAP: Because packets through an HTTP proxy are -// batched and cached and stuff, using this flag is not a guarantee that it -// will be obeyed, and if it is it may even be propogated to future calls -// even if you don't specify it then. Because of this, the flag should be -// considered an all-or-nothing thing: either use it for the entire duration -// of a connection, or not at all. -// Errors: ERROR_INVALID_PARAMETER, anything from recv() -// HTTP proxy: ERROR_GEN_FAILURE (http result code wasn't 2xx) -// ERROR_INVALID_DATA (no Content-Length header in reply) -// ERROR_NOT_ENOUGH_MEMORY (Content-Length very large) -// ERROR_HANDLE_EOF (connection closed before Content-Length bytes recved) -// anything from select(), MS_NETLIB_RECVHTTPHEADERS, -// nlu.pfnHttpGatewayUnwrapRecv, socket(), connect(), -// MS_NETLIB_SENDHTTPREQUEST - -EXTERN_C MIR_APP_DLL(int) Netlib_Recv(HNETLIBCONN hConn, char *buf, int len, int flags = 0); - -///////////////////////////////////////////////////////////////////////////////////////// -// Determine the status of one or more connections -// Returns the number of ready connections, SOCKET_ERROR on failure, 0 if the timeout expired. -// All handles passed to this function must have been returned by either -// MS_NETLIB_OPENCONNECTION or MS_NETLIB_BINDPORT. -// The last handle in each list must be followed by either NULL or INVALID_HANDLE_VALUE. -// Errors: ERROR_INVALID_HANDLE, ERROR_INVALID_DATA, anything from select() - -struct NETLIBSELECT -{ - uint32_t dwTimeout; // in milliseconds, INFINITE is acceptable - HNETLIBCONN hReadConns[FD_SETSIZE + 1]; - HNETLIBCONN hWriteConns[FD_SETSIZE + 1]; - HNETLIBCONN hExceptConns[FD_SETSIZE + 1]; -}; - -EXTERN_C MIR_APP_DLL(int) Netlib_Select(NETLIBSELECT *nls); - -struct NETLIBSELECTEX -{ - uint32_t dwTimeout; // in milliseconds, INFINITE is acceptable - HNETLIBCONN hReadConns[FD_SETSIZE + 1]; - HNETLIBCONN hWriteConns[FD_SETSIZE + 1]; - HNETLIBCONN hExceptConns[FD_SETSIZE + 1]; - - BOOL hReadStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */ - BOOL hWriteStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */ - BOOL hExceptStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */ -}; - -EXTERN_C MIR_APP_DLL(int) Netlib_SelectEx(NETLIBSELECTEX *nls); - -///////////////////////////////////////////////////////////////////////////////////////// -// Shutdown connection - -EXTERN_C MIR_APP_DLL(void) Netlib_Shutdown(HNETLIBCONN h); - -///////////////////////////////////////////////////////////////////////////////////////// -// Create a packet receiver -// -// Returns a HANDLE on success, NULL on failure -// The packet receiver implements the common situation where you have variable -// length packets coming in over a connection and you want to split them up -// in order to handle them. -// The major limitation is that the buffer is created in memory, so you can't -// have arbitrarily large packets. -// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY - -EXTERN_C MIR_APP_DLL(HANDLE) Netlib_CreatePacketReceiver(HNETLIBCONN hConnection, int iMaxSize); - -///////////////////////////////////////////////////////////////////////////////////////// -// Get the next set of packets from a packet receiver -// -// Returns the total number of bytes available in the buffer, 0 if the -// connection was closed, SOCKET_ERROR on error. -// hPacketRecver must have been returned by MS_NETLIB_CREATEPACKETRECVER -// If nlpr.bytesUsed is set to zero and the buffer is already full up to -// maxPacketSize, it is assumed that too large a packet has been received. All -// data in the buffer is discarded and receiving is begun anew. This will -// probably cause alignment problems so if you think this is likely to happen -// then you should deal with it yourself. -// Closing the packet receiver will not close the associated connection, but -// will discard any bytes still in the buffer, so if you intend to carry on -// reading from that connection, make sure you have processed the buffer first. -// This function is the equivalent of a memmove() to remove the first bytesUsed -// from the buffer, select() if dwTimeout is not INFINITE, then MS_NETLIB_RECV. -// Errors: ERROR_INVALID_PARAMETER, ERROR_TIMEOUT, -// anything from select(), MS_NETLIB_RECV - -struct NETLIBPACKETRECVER -{ - uint32_t dwTimeout; // fill before calling. In milliseconds. INFINITE is valid - int bytesUsed; // fill before calling. This many bytes are removed from the start of the buffer. Set to 0 on return - int bytesAvailable; // equal to the return value, unless the return value is 0 - int bufferSize; // same as parameter to MS_NETLIB_CREATEPACKETRECVER - uint8_t *buffer; // contains the recved data -}; - -EXTERN_C MIR_APP_DLL(int) Netlib_GetMorePackets(HANDLE hReceiver, NETLIBPACKETRECVER *nlprParam); - -///////////////////////////////////////////////////////////////////////////////////////// -// Sets a gateway polling timeout interval -// -// Returns previous timeout value -// Errors: -1 - -EXTERN_C MIR_APP_DLL(int) Netlib_SetPollingTimeout(HNETLIBCONN hConnection, int iTimeout); - -///////////////////////////////////////////////////////////////////////////////////////// -// netlib log funcitons - -EXTERN_C MIR_APP_DLL(int) Netlib_Log(HNETLIBUSER hUser, const char *pszStr); -EXTERN_C MIR_APP_DLL(int) Netlib_LogW(HNETLIBUSER hUser, const wchar_t *pwszStr); - -EXTERN_C MIR_APP_DLL(int) Netlib_Logf(HNETLIBUSER hUser, _Printf_format_string_ const char *fmt, ...); -EXTERN_C MIR_APP_DLL(int) Netlib_LogfW(HNETLIBUSER hUser, _Printf_format_string_ const wchar_t *fmt, ...); - -EXTERN_C MIR_APP_DLL(void) Netlib_Dump(HNETLIBCONN nlc, const void *buf, size_t len, bool bIsSent, int flags); - -// Inits a required security provider. Right now only NTLM is supported -// Returns HANDLE = NULL on error or non-null value on success -// Known providers: Basic, NTLM, Negotiate, Kerberos, GSSAPI - (Kerberos SASL) -EXTERN_C MIR_APP_DLL(HANDLE) Netlib_InitSecurityProvider(const wchar_t *szProviderName, const wchar_t *szPrincipal = nullptr); - -// Destroys a security provider's handle, provided by Netlib_InitSecurityProvider. -// Right now only NTLM is supported -EXTERN_C MIR_APP_DLL(void) Netlib_DestroySecurityProvider(HANDLE hProvider); - -// Returns the NTLM response string. The result value should be freed using mir_free -EXTERN_C MIR_APP_DLL(char*) Netlib_NtlmCreateResponse(HANDLE hProvider, const char *szChallenge, wchar_t *szLogin, wchar_t *szPass, unsigned &complete); - -///////////////////////////////////////////////////////////////////////////////////////// -// SSL/TLS support - -#if !defined(HSSL_DEFINED) -DECLARE_HANDLE(HSSL); -#endif - -// Makes connection SSL -// Returns 0 on failure 1 on success -EXTERN_C MIR_APP_DLL(int) Netlib_StartSsl(HNETLIBCONN hConnection, const char *host); - -// negotiates SSL session, verifies cert, returns NULL if failed -EXTERN_C MIR_APP_DLL(HSSL) Netlib_SslConnect(SOCKET s, const char* host, int verify); - -// return true if there is either unsend or buffered received data (ie. after peek) -EXTERN_C MIR_APP_DLL(BOOL) Netlib_SslPending(HSSL ssl); - -// reads number of bytes, keeps in buffer if peek != 0 -EXTERN_C MIR_APP_DLL(int) Netlib_SslRead(HSSL ssl, char *buf, int num, int peek); - -// writes data to the SSL socket -EXTERN_C MIR_APP_DLL(int) Netlib_SslWrite(HSSL ssl, const char *buf, int num); - -// closes SSL session, but keeps socket open -EXTERN_C MIR_APP_DLL(void) Netlib_SslShutdown(HSSL ssl); - -// frees all data associated with the SSL socket -EXTERN_C MIR_APP_DLL(void) Netlib_SslFree(HSSL ssl); - -// gets TLS channel binging data for a socket -EXTERN_C MIR_APP_DLL(void*) Netlib_GetTlsUnique(HNETLIBCONN nlc, int &cbLen, int &tlsVer); - -///////////////////////////////////////////////////////////////////////////////////////// -// WebSocket support - -struct WSHeader -{ - WSHeader() - { - memset(this, 0, sizeof(*this)); - } - - bool bIsFinal, bIsMasked; - int opCode, firstByte; - size_t payloadSize, headerSize; -}; - -// connects to a WebSocket server -EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) WebSocket_Connect(HNETLIBUSER, const char *szHost, NETLIBHTTPHEADER *pHeaders = nullptr); - -// validates that the provided buffer contains full WebSocket datagram -EXTERN_C MIR_APP_DLL(bool) WebSocket_InitHeader(WSHeader &hdr, const void *pData, size_t bufSize); - -// sends a packet to WebSocket -EXTERN_C MIR_APP_DLL(void) WebSocket_SendText(HNETLIBCONN nlc, const char *pData); -EXTERN_C MIR_APP_DLL(void) WebSocket_SendBinary(HNETLIBCONN nlc, const void *pData, size_t strLen); - -///////////////////////////////////////////////////////////////////////////////////////// -// Netlib hooks (0.8+) - -// WARNING: these hooks are being called in the context of the calling thread, without switching -// to the first thread, like all another events do. The hook procedure should be ready for the -// multithreaded mode -// -// Parameters: -// wParam: NETLIBNOTIFY* - points to the data being sent/received -// lParam: NETLIBUSER* - points to the protocol definition - -struct NETLIBNOTIFY -{ - const char *buf; - int len; - int flags; - int result; // amount of bytes really sent/received -}; - -#define ME_NETLIB_FASTRECV "Netlib/OnRecv" // being called on every receive -#define ME_NETLIB_FASTSEND "Netlib/OnSend" // being called on every send -#define ME_NETLIB_FASTDUMP "Netlib/OnDump" // being called on every dump - -struct NETLIBCONNECTIONEVENTINFO -{ - BOOL connected; // 1-opening socket 0-closing socket - BOOL listening; // 1-bind 0-connect - SOCKADDR_IN local; // local IP+port (always used) - SOCKADDR_IN remote; // remote IP+port (only connect (opening + closing only if no proxy)) - SOCKADDR_IN proxy; // proxy IP+port (only connect when used) - char *szSettingsModule; // name of the registered Netlib user that requested the action -}; - -//This event is sent as a new port is bound or a new connection opened. -//It is NOT sent for sigle HTTP(S) requests. -//wParam=(WPARAM)(NETLIBCONNECTIONEVENTINFO*)hInfo -//lParam=(LPARAM)0 (not used) -#define ME_NETLIB_EVENT_CONNECTED "Netlib/Event/Connected" - -//This event is sent if coneection or listening socket is closed. -//It is NOT sent for sigle HTTP(S) requests. -//wParam=(WPARAM)(NETLIBCONNECTIONEVENTINFO*)hInfo -//lParam=(LPARAM)0 (not used) -#define ME_NETLIB_EVENT_DISCONNECTED "Netlib/Event/Disconnected" - -#endif // M_NETLIB_H__ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-12 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_NETLIB_H__
+#define M_NETLIB_H__ 1
+
+#include "m_utils.h"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// this module was created in 0.1.2.2
+// All error codes are returned via GetLastError() (or WSAGetLastError():
+// they're the same).
+// This module is thread-safe where it is sensible for it to be so. This
+// basically means that you can call anything from any thread, but don't try
+// to predict what will happen if you try to recv() on the same connection from
+// two different threads at the same time.
+// Note that because the vast majority of the routines in this module return
+// a pointer, I have decided to diverge from the rest of Miranda and go with
+// the convention that functions return false on failure and nonzero on success.
+
+struct NETLIBHTTPREQUEST;
+struct NETLIBOPENCONNECTION;
+
+#define NETLIB_USER_AGENT "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.112 Safari/537.36"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Initialises the netlib for a set of connections
+// Returns a HNETLIBUSER to be used for future netlib calls, NULL on failure
+// NOTE: Netlib is loaded after any plugins, so you need to wait until
+// ME_SYSTEM_MODULESLOADED before calling this function
+// Netlib settings are stored under the module szSettingsModule
+// All netlib settings being with "NL".
+// The default settings for registered users that don't have any settings stored
+// in the database are the same as those displayed by the <All connections> page
+// of the netlib options page.
+// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY, ERROR_DUP_NAME
+
+struct NETLIBUSER
+{
+ char *szSettingsModule; // used for db settings and log
+ MAllStrings szDescriptiveName; // used in options dialog, already translated
+ uint32_t flags;
+ int minIncomingPorts; // only if NUF_INCOMING. Will be used for validation of user input.
+};
+
+#define NUF_INCOMING 0x01 // binds incoming ports
+#define NUF_OUTGOING 0x02 // makes outgoing plain connections
+#define NUF_NOOPTIONS 0x08 // don't create an options page for this. szDescriptiveName is never used.
+#define NUF_HTTPCONNS 0x10 // at least some connections are made for HTTP communication. Enables the HTTP proxy option in options.
+#define NUF_NOHTTPSOPTION 0x20 // disable the HTTPS proxy option in options. Use this if all communication is HTTP.
+#define NUF_UNICODE 0x40 // if set ptszDescriptiveName points to Unicode, otherwise it points to ANSI string
+
+EXTERN_C MIR_APP_DLL(HNETLIBUSER) Netlib_RegisterUser(const NETLIBUSER *pDescr);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Assign a Netlib user handle a set of dynamic HTTP headers to be used with all
+//
+// HTTP connections that enable the HTTP-use-sticky headers flag.
+// The headers persist until cleared with lParam = NULL.
+//
+// All memory should be allocated by the caller using malloc() from MS_SYSTEM_GET_MMI
+// Once it has passed to Netlib, Netlib is the owner of it, the caller should not refer to the memory
+// In any way after this point.
+//
+// NOTE: The szHeaders parameter should be a NULL terminated string following the HTTP header syntax.
+// This string will be injected verbatim, thus the user should be aware of setting strings that are not
+// headers. This service is NOT THREAD SAFE, only a single thread is expected to set the headers and a single
+// thread reading the pointer internally, stopping race conditions and mutual exclusion don't happen.
+//
+// Version 0.3.2a+ (2003/10/27)
+//
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SetStickyHeaders(HNETLIBUSER nlu, const char *szHeaders);
+
+/* Notes on HTTP gateway usage
+When a connection is initiated through an HTTP proxy using
+MS_NETLIB_OPENCONNECTION, netlib will GET nlu.szHttpGatewayHello and read
+the replied headers. Once this succeeds nlu.pfnHttpGatewayInit will be called
+with a valid handle to the connection, the NETLIBOPENCONNECTION structure that
+MS_NETLIB_OPENCONNECTION was called with, and the replied HTTP headers as its
+parameters. This function is responsible for recving and parsing the data then
+calling MS_NETLIB_SETHTTPPROXYINFO with the appropriate information.
+nlu.pfnHttpGatewayInit should return nonzero on success. If it returns zero
+then the entire connection attempt will return signalling failure. If your
+function needs to return an error code it can do so via SetLastError().
+If nlu.pfnHttpGatewayInit returns success without having called
+MS_NETLIB_SETHTTPPROXYINFO then the connection attempt will fail anyway.
+If you need more fine-tuned control over the GET/POST URLs than just appending
+sequence numbers you can call MS_NETLIB_SETHTTPPROXYINFO from within your
+wrap/unwrap functions (see below).
+
+Just prior to MS_NETLIB_OPENCONNECTION returning nlu.pfnHttpGatewayBegin is
+called with the handle to the connection and the NETLIBOPENCONNECTION structure
+as its parameters. This is for gateways that need special non-protocol
+initialisation. If you do send any packets in this function, you probably want
+to remember to use the MSG_NOHTTPGATEWAYWRAP flag. This function pointer can be
+NULL if this functionality isn't needed. This function must return nonzero on
+success. If it fails the connect attempt will return failure without changing
+LastError.
+
+Whenever MS_NETLIB_SEND is called on a connection through an HTTP proxy and
+the MSG_NOHTTPGATEWAYWRAP flags is not set and nlu.pfnHttpGatewayWrapSend is
+not NULL, nlu.pfnHttpGatewayWrapSend will be called *instead* of sending the
+data. It is this function's responsibility to wrap the sending data
+appropriately for transmission and call pfnNetlibSend to send it again.
+The flags parameter to nlu.pfnHttpGatewayWrapSend should be passed straight
+through to the pfnNetlibSend call. It has already been ORed with
+MSG_NOHTTPGATEWAYWRAP. nlu.pfnHttpGatewayWrapSend should return the a
+number of the same type as MS_NETLIB_SEND, ie the number of bytes sent or
+SOCKET_ERROR. The number of wrapping bytes should be subtracted so that the
+return value appears as if the proxy wasn't there.
+pfnNetlibSend() is identical to CallService(MS_NETLIB_SEND, ...) but it's
+quicker to call using this pointer than to do the CallService() lookup again.
+
+Whenever an HTTP reply is received inside MS_NETLIB_RECV the headers and data
+are read into memory. If the headers indicate success then the data is passed
+to nlu.pfnHttpGatewayUnwrapRecv (if it's non-NULL) for processing. This
+function should remove (and do other processing if necessary) all HTTP proxy
+specific headers and return a pointer to the buffer whose size is returned in
+*outBufLen. If the buffer needs to be resized then NetlibRealloc() should be
+used for that purpose, *not* your own CRT's realloc(). NetlibRealloc() behaves
+identically to realloc() so it's possible to free the original buffer and
+create a new one if that's the most sensible way to write your parser.
+If errors are encountered you should SetLastError() and return NULL;
+MS_NETLIB_RECV will return SOCKET_ERROR. If the passed buffer unwraps to
+contain no actual data you should set *outBufLen to 0 but make sure you return
+some non-NULL buffer that can be freed.
+
+When you call MS_NETLIB_SEND or MS_NETLIB_RECV from any of these functions, you
+should use the MSG_DUMPPROXY flag so that the logging is neat.
+*/
+
+#define PROXYTYPE_SOCKS4 1
+#define PROXYTYPE_SOCKS5 2
+#define PROXYTYPE_HTTP 3
+#define PROXYTYPE_HTTPS 4
+#define PROXYTYPE_IE 5
+
+struct NETLIBUSERSETTINGS
+{
+ int cbSize; // to be filled in before calling
+ int useProxy; // 1 or 0
+ int proxyType; // a PROXYTYPE_
+ char *szProxyServer; // can be NULL
+ int wProxyPort; // host byte order
+ int useProxyAuth; // 1 or 0. Always 0 for SOCKS4
+ char *szProxyAuthUser; // can be NULL, always used by SOCKS4
+ char *szProxyAuthPassword; // can be NULL
+ int useProxyAuthNtlm; // 1 or 0, only used by HTTP, HTTPS
+ int dnsThroughProxy; // 1 or 0
+ int specifyIncomingPorts; // 1 or 0
+ char *szIncomingPorts; // can be NULL. Of form "1024-1050, 1060-1070, 2000"
+ int specifyOutgoingPorts; // 0.3.3a+
+ char *szOutgoingPorts; // 0.3.3a+
+ int enableUPnP; // 0.6.1+ only for NUF_INCOMING
+ int validateSSL;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Gets the user-configured settings for a netlib user
+//
+// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+// The pointers referred to in the returned struct will remain valid until
+// the hUser handle is closed, or until the user changes the settings in the
+// options page, so it's best not to rely on them for too long.
+// Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(int) Netlib_GetUserSettings(HNETLIBUSER nlu, NETLIBUSERSETTINGS *result);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+//Gets the user-configured settings for a netlib user idetified by name
+//
+//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+//This function behaves like Netlib_GetUserSettings but the user is identified
+//by the name provided by registration. When the name is not found NETLIBUSERSETTINGS is set to NULL.
+//Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(int) Netlib_GetUserSettingsByName(char * UserSettingsName, NETLIBUSERSETTINGS *result);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Changes the user-configurable settings for a netlib user
+//
+// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+// This function is only really useful for people that specify NUF_NOOPTIONS
+// and want to create their own options.
+// Even if a setting is not active (eg szProxyAuthPassword when useProxyAuth is
+// zero) that settings is still set for use in the options dialog.
+// Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SetUserSettings(HNETLIBUSER nlu, const NETLIBUSERSETTINGS *result);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+//Changes the user-configurable settings for a netlib user idetified by name
+//
+//Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+//This function behaves like Netlib_SetUserSettings but the user is identified
+//by the name provided by registration. Nothing will be changed when the name is not found.
+//Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SetUserSettingsByName(char * UserSettingsName, NETLIBUSERSETTINGS *result);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Closes a netlib handle
+//
+// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+// This function should be called on all handles returned by netlib functions
+// once you are done with them. If it's called on a socket-type handle, the
+// socket will be closed.
+// Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(int) Netlib_CloseHandle(HANDLE h);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Open a port and wait for connections on it
+//
+// Returns a HANDLE on success, NULL on failure
+// hUser should have been returned by MS_NETLIB_REGISTERUSER
+// This function does the equivalent of socket(), bind(), getsockname(),
+// listen(), accept()
+// Internally this function creates a new thread which waits around in accept()
+// for new connections. When one is received it calls nlb.pfnNewConnection *from
+// this new thread* and then loops back to wait again.
+// Close the returned handle to end the thread and close the open port.
+// Errors: ERROR_INVALID_PARAMETER, any returned by socket() or bind() or
+// listen() or getsockname()
+//
+// Notes:
+//
+// During development of 0.3.1a+ (2003/07/04) passing wPort != 0
+// will result in an attempt to bind on the port given in wPort
+// if this port is taken then you will get an error, so be sure to check
+// for such conditions.
+//
+// passing wPort != 0 is for people who need to open a set port for
+// daemon activities, usually passing wPort == 0 is what you want and
+// will result in a free port given by the TCP/IP socket layer and/or
+// seeded from the user selected port ranges.
+//
+// also note that wPort if != 0, will have be converted to network byte order
+//
+/* pExtra was added during 0.3.4+, prior its just two args, since we use the cdecl convention
+it shouldnt matter */
+
+typedef void (*NETLIBNEWCONNECTIONPROC)(HNETLIBCONN hNewConnection, uint32_t dwRemoteIP, void *pExtra);
+
+struct NETLIBBIND
+{
+ NETLIBNEWCONNECTIONPROC pfnNewConnection;
+
+ // function to call when there's a new connection. Params are: the
+ // new connection, IP of remote machine (host byte order)
+ uint32_t dwInternalIP; // set on return, host byte order
+ uint32_t dwExternalIP; // set on return, host byte order
+ uint16_t wPort, wExPort; // set on return, host byte order
+ void *pExtra; // argument is sent to callback
+};
+
+EXTERN_C MIR_APP_DLL(HNETLIBBIND) Netlib_BindPort(HNETLIBUSER nlu, NETLIBBIND *nlb);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Open a connection
+//
+// Returns a HNETLIBCONN to the new connection on success, NULL on failure
+// hUser must have been returned by MS_NETLIB_REGISTERUSER
+// Internally this function is the equivalent of socket(), gethostbyname(),
+// connect()
+// If NLOCF_HTTP is set and hUser is configured for an HTTP or HTTPS proxy then
+// this function will connect() to the proxy server only, without performing any
+// initialisation conversation.
+// If hUser is configured for an HTTP proxy and does not support HTTP gateways
+// and you try to open a connection without specifying NLOCF_HTTP then this
+// function will first attempt to open an HTTPS connection, if that fails it
+// will try a direct connection, if that fails it will return failure with the
+// error from the connect() during the direct connection attempt.
+// Errors: ERROR_INVALID_PARAMETER, any returned by socket(), gethostbyname(),
+// connect(), MS_NETLIB_SEND, MS_NETLIB_RECV, select()
+// ERROR_TIMEOUT (during proxy communication)
+// ERROR_BAD_FORMAT (very invalid proxy reply)
+// ERROR_ACCESS_DENIED (by proxy)
+// ERROR_CONNECTION_UNAVAIL (socks proxy can't connect to identd)
+// ERROR_INVALID_ACCESS (proxy refused identd auth)
+// ERROR_INVALID_DATA (proxy returned invalid code)
+// ERROR_INVALID_ID_AUTHORITY (proxy requires use of auth method that's not supported)
+// ERROR_GEN_FAILURE (socks5/https general failure)
+// ERROR_CALL_NOT_IMPLEMENTED (socks5 command not supported)
+// ERROR_INVALID_ADDRESS (socks5 address type not supported)
+// HTTP: anything from nlu.pfnHttpGatewayInit, nlu.pfnHttpGatewayBegin,
+// MS_NETLIB_SENDHTTPREQUEST or MS_NETLIB_RECVHTTPHEADERS
+
+#define NLOCF_HTTP 0x0001 // this connection will be used for HTTP communications. If configured for an HTTP/HTTPS proxy the connection is opened as if there was no proxy.
+#define NLOCF_STICKYHEADERS 0x0002 // this connection should send the sticky headers associated with NetLib user apart of any HTTP request
+#define NLOCF_UDP 0x0008 // this connection is UDP
+#define NLOCF_SSL 0x0010 // this connection is SSL
+
+EXTERN_C MIR_APP_DLL(HNETLIBCONN) Netlib_OpenConnection(HNETLIBUSER nlu, const char *szHost, int port, int timeout = 0, int flags = 0);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Sets the required information for an HTTP proxy connection
+//
+// Returns nonzero on success, 0 on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+// This function is designed to be called from within pfnHttpGatewayInit
+// See notes below MS_NETLIB_REGISTERUSER.
+// Errors: ERROR_INVALID_PARAMETER
+
+#define NLHPIF_USEGETSEQUENCE 0x0001 // append sequence numbers to GET requests
+#define NLHPIF_USEPOSTSEQUENCE 0x0002 // append sequence numbers to POST requests
+#define NLHPIF_GETPOSTSAMESEQUENCE 0x0004 // GET and POST use the same sequence
+#define NLHPIF_HTTP11 0x0008 // HTTP 1.1 proxy
+
+struct NETLIBHTTPPROXYINFO
+{
+ uint32_t flags;
+ int firstGetSequence, firstPostSequence;
+ int combinePackets;
+ char *szHttpPostUrl;
+ char *szHttpGetUrl;
+};
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SetHttpProxyInfo(HNETLIBCONN hConnection, const NETLIBHTTPPROXYINFO *nlhpi);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Gets the SOCKET associated with a netlib handle
+//
+// Returns the SOCKET on success, INVALID_SOCKET on failure
+// hNetlibHandle should have been returned by MS_NETLIB_BINDPORT or
+// MS_NETLIB_OPENCONNECTION only.
+// Be careful how you use this socket because you might be connected via an
+// HTTP proxy in which case calling send() or recv() will totally break things.
+// Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(UINT_PTR) Netlib_GetSocket(HNETLIBCONN hConnection);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#define Netlib_GetBase64DecodedBufferSize(cchEncoded) (((cchEncoded)>>2)*3)
+#define Netlib_GetBase64EncodedBufferSize(cbDecoded) (((cbDecoded)*4+11)/12*4+1)
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Gets HNETLIBUSER owner of a connection
+
+EXTERN_C MIR_APP_DLL(HNETLIBUSER) Netlib_GetConnNlu(HNETLIBCONN hConn);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Gets the fake User-Agent header field to make some sites happy
+
+EXTERN_C MIR_APP_DLL(char*) Netlib_GetUserAgent();
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Converts numerical representation of IP in SOCKADDR_INET into string representation with IP and port
+// IPv4 will be supplied in formats address:port or address
+// IPv6 will be supplied in formats [address]:port or [address]
+// Returns pointer to the string or NULL if not successful
+
+struct sockaddr_in;
+EXTERN_C MIR_APP_DLL(char*) Netlib_AddressToString(sockaddr_in *addr);
+EXTERN_C MIR_APP_DLL(bool) Netlib_StringToAddress(const char *str, sockaddr_in *addr);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Gets connection Information
+// IPv4 will be supplied in formats address:port or address
+// IPv6 will be supplied in formats [address]:port or [address]
+// Returns 0 if successful
+
+struct NETLIBCONNINFO
+{
+ char szIpPort[64];
+ unsigned dwIpv4;
+ uint16_t wPort;
+};
+
+EXTERN_C MIR_APP_DLL(int) Netlib_GetConnectionInfo(HNETLIBCONN hConnection, NETLIBCONNINFO *connInfo);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Gets connection Information
+//
+// Returns (INT_PTR)(NETLIBIPLIST*) numeric IP address address array
+// the last element of the array is all 0s, 0 if not successful
+
+struct NETLIBIPLIST
+{
+ unsigned cbNum;
+ char szIp[1][64];
+};
+
+EXTERN_C MIR_APP_DLL(NETLIBIPLIST*) Netlib_GetMyIp(bool bGlobalOnly);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Send an HTTP request over a connection
+//
+// Returns number of bytes sent on success, SOCKET_ERROR on failure
+// hConnection must have been returned by MS_NETLIB_OPENCONNECTION
+// Note that if you use NLHRF_SMARTAUTHHEADER and NTLM authentication is in use
+// then the full NTLM authentication transaction occurs, comprising sending the
+// domain, receiving the challenge, then sending the response.
+// nlhr.resultCode and nlhr.szResultDescr are ignored by this function.
+// Errors: ERROR_INVALID_PARAMETER, anything returned by MS_NETLIB_SEND
+
+struct NETLIBHTTPHEADER
+{
+ char *szName;
+ char *szValue;
+};
+
+EXTERN_C MIR_APP_DLL(char*) Netlib_GetHeader(const NETLIBHTTPREQUEST *pRec, const char *pszName);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+#define REQUEST_RESPONSE 0 // used by structure returned by MS_NETLIB_RECVHTTPHEADERS
+#define REQUEST_GET 1
+#define REQUEST_POST 2
+#define REQUEST_CONNECT 3
+#define REQUEST_HEAD 4
+#define REQUEST_PUT 5
+#define REQUEST_DELETE 6
+#define REQUEST_PATCH 7
+
+#define NLHRF_MANUALHOST 0x00000001 // do not remove any host and/or protocol portion of szUrl before sending it
+#define NLHRF_HTTP11 0x00000010 // use HTTP 1.1
+#define NLHRF_PERSISTENT 0x00000020 // preserve connection on exit, open connection provided in the nlc field of the reply
+ // it should be supplied in nlc field of request for reuse or closed if not needed
+#define NLHRF_SSL 0x00000040 // use SSL connection
+#define NLHRF_NOPROXY 0x00000080 // do not use proxy server
+#define NLHRF_REDIRECT 0x00000100 // handle HTTP redirect requests (response 30x), the resulting url provided in szUrl of the response
+#define NLHRF_NODUMP 0x00010000 // never dump this to the log
+#define NLHRF_NODUMPHEADERS 0x00020000 // don't dump http headers (only useful for POSTs and MS_NETLIB_HTTPTRANSACTION)
+#define NLHRF_DUMPPROXY 0x00040000 // this transaction is a proxy communication. For dump filtering only.
+#define NLHRF_DUMPASTEXT 0x00080000 // dump posted and reply data as text. Headers are always dumped as text.
+#define NLHRF_NODUMPSEND 0x00100000 // do not dump sent message.
+
+struct NETLIBHTTPREQUEST
+{
+ int cbSize;
+ int requestType; // a REQUEST_
+ uint32_t flags;
+ char *szUrl;
+ NETLIBHTTPHEADER *headers; // If this is a POST request and headers doesn't contain a Content-Length it'll be added automatically
+ int headersCount;
+ char *pData; // data to be sent in POST request.
+ int dataLength; // must be 0 for REQUEST_GET/REQUEST_CONNECT
+ int resultCode;
+ char *szResultDescr;
+ HNETLIBCONN nlc;
+ int timeout;
+
+ __forceinline const char *operator[](const char *pszName) {
+ return Netlib_GetHeader(this, pszName);
+ }
+};
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SendHttpRequest(HNETLIBCONN hConnection, NETLIBHTTPREQUEST *pRec);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Receives HTTP headers
+//
+// Returns a pointer to a NETLIBHTTPREQUEST structure on success, NULL on failure.
+// Call Netlib_FreeHttpRequest() to free this.
+// hConnection must have been returned by MS_NETLIB_OPENCONNECTION
+// nlhr->pData = NULL and nlhr->dataLength = 0 always. The requested data should
+// be retrieved using MS_NETLIB_RECV once the header has been parsed.
+// If the headers haven't finished within 60 seconds the function returns NULL
+// and ERROR_TIMEOUT.
+// Errors: ERROR_INVALID_PARAMETER, any from MS_NETLIB_RECV or select()
+// ERROR_HANDLE_EOF (connection closed before headers complete)
+// ERROR_TIMEOUT (headers still not complete after 60 seconds)
+// ERROR_BAD_FORMAT (invalid character or line ending in headers, or first line is blank)
+// ERROR_BUFFER_OVERFLOW (each header line must be less than 4096 chars long)
+// ERROR_INVALID_DATA (first header line is malformed ("http/[01].[0-9] [0-9]+ .*", or no colon in subsequent line)
+
+EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) Netlib_RecvHttpHeaders(HNETLIBCONN hConnection, int flags = 0);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Free the memory used by a NETLIBHTTPREQUEST structure
+//
+// Returns true on success, false on failure (!! this is different to most of the rest of Miranda, but consistent with netlib)
+// This should only be called on structures returned by
+// MS_NETLIB_RECVHTTPHEADERS or MS_NETLIB_HTTPTRANSACTION. Calling it on an
+// arbitrary structure will have disastrous results.
+// Errors: ERROR_INVALID_PARAMETER
+
+EXTERN_C MIR_APP_DLL(bool) Netlib_FreeHttpRequest(NETLIBHTTPREQUEST*);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// smart pointer for NETLIBHTTPREQUEST via a call of Netlib_FreeHttpRequest()
+
+#ifdef __cplusplus
+class NLHR_PTR
+{
+protected:
+ NETLIBHTTPREQUEST *_p;
+
+public:
+ __forceinline explicit NLHR_PTR(NETLIBHTTPREQUEST *p) : _p(p) {}
+
+ __forceinline NETLIBHTTPREQUEST* operator=(INT_PTR i_p)
+ {
+ return operator=((NETLIBHTTPREQUEST*)i_p);
+ }
+ __forceinline NETLIBHTTPREQUEST* operator=(NETLIBHTTPREQUEST *p)
+ {
+ if (_p)
+ Netlib_FreeHttpRequest(_p);
+ _p = p;
+ return _p;
+ }
+ __forceinline operator NETLIBHTTPREQUEST*() const { return _p; }
+ __forceinline NETLIBHTTPREQUEST* operator->() const { return _p; }
+ __forceinline ~NLHR_PTR()
+ {
+ Netlib_FreeHttpRequest(_p);
+ }
+};
+
+struct MIR_APP_EXPORT MHttpRequest : public NETLIBHTTPREQUEST, public MZeroedObject
+{
+ MHttpRequest();
+ ~MHttpRequest();
+
+ CMStringA m_szUrl;
+ CMStringA m_szParam;
+ void *pUserInfo = nullptr;
+
+ void AddHeader(const char *szName, const char *szValue);
+};
+
+template <class T>
+class MTHttpRequest : public MHttpRequest
+{
+public:
+ __forceinline MTHttpRequest()
+ {}
+
+ typedef void (T::*MTHttpRequestHandler)(NETLIBHTTPREQUEST*, struct AsyncHttpRequest*);
+ MTHttpRequestHandler m_pFunc = nullptr;
+};
+
+MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const INT_PARAM&);
+MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const INT64_PARAM&);
+MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const CHAR_PARAM&);
+MIR_APP_DLL(MHttpRequest*) operator<<(MHttpRequest*, const WCHAR_PARAM&);
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Do an entire HTTP transaction
+//
+// Returns a pointer to another NETLIBHTTPREQUEST structure on success, NULL on failure.
+// Call Netlib_FreeHttpRequest() to free this.
+// hUser must have been returned by MS_NETLIB_REGISTERUSER
+// nlhr.szUrl should be a full HTTP URL. If it does not start with http:// , that
+// will be assumed (but it's best not to use this fact, for reasons of
+// extensibility).
+// This function is the equivalent of MS_NETLIB_OPENCONNECTION,
+// MS_NETLIB_SENDHTTPREQ, MS_NETLIB_RECVHTTPHEADERS, MS_NETLIB_RECV,
+// MS_NETLIB_CLOSEHANDLE
+// nlhr.headers will be augmented with the following headers unless they have
+// already been set by the caller:
+// "Host" (regardless of whether it is requested in nlhr.flags)
+// "User-Agent" (of the form "Miranda/0.1.2.2 (alpha)" or "Miranda/0.1.2.2")
+// "Content-Length" (for POSTs only. Set to nlhr.dataLength)
+// If you do not want to send one of these headers, create a nlhr.headers with
+// szValue = NULL.
+// In the return value headers, headerCount, pData, dataLength, resultCode and
+// szResultDescr are all valid.
+// In the return value pData[dataLength] == 0 always, as an extra safeguard
+// against programming slips.
+// Note that the function can succeed (ie not return NULL) yet result in an HTTP
+// error code. You should check that resultCode == 2xx before proceeding.
+// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY, anything from the above
+// list of functions
+
+EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) Netlib_HttpTransaction(HNETLIBUSER hNlu, NETLIBHTTPREQUEST *pRequest);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Send data over a connection
+//
+// Returns the number of bytes sent on success, SOCKET_ERROR on failure
+// Errors: ERROR_INVALID_PARAMETER
+// anything from send(), nlu.pfnHttpGatewayWrapSend()
+// HTTP proxy: ERROR_GEN_FAILURE (http result code wasn't 2xx)
+// anything from socket(), connect(),
+// MS_NETLIB_SENDHTTPREQUEST, MS_NETLIB_RECVHTTPHEADERS
+// flags:
+
+#define MSG_NOHTTPGATEWAYWRAP 0x010000 // don't wrap the outgoing packet using nlu.pfnHttpGatewayWrapSend
+#define MSG_NODUMP 0x020000 // don't dump this packet to the log
+#define MSG_DUMPPROXY 0x040000 // this is proxy communiciation. For dump filtering only.
+#define MSG_DUMPASTEXT 0x080000 // this is textual data, don't dump as hex
+#define MSG_RAW 0x100000 // send as raw data, bypass any HTTP proxy stuff
+#define MSG_DUMPSSL 0x200000 // this is SSL traffic. For dump filtering only.
+#define MSG_NOTITLE 0x400000 // skip date, time & protocol from dump
+
+EXTERN_C MIR_APP_DLL(int) Netlib_Send(HNETLIBCONN hConn, const char *buf, int len, int flags = 0);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Receive data over a connection
+//
+// Returns the number of bytes read on success, SOCKET_ERROR on failure,
+// 0 if the connection has been closed
+// Flags supported: MSG_PEEK, MSG_NODUMP, MSG_DUMPPROXY, MSG_NOHTTPGATEWAYWRAP,
+// MSG_DUMPASTEXT, MSG_RAW
+// On using MSG_NOHTTPGATEWAYWRAP: Because packets through an HTTP proxy are
+// batched and cached and stuff, using this flag is not a guarantee that it
+// will be obeyed, and if it is it may even be propogated to future calls
+// even if you don't specify it then. Because of this, the flag should be
+// considered an all-or-nothing thing: either use it for the entire duration
+// of a connection, or not at all.
+// Errors: ERROR_INVALID_PARAMETER, anything from recv()
+// HTTP proxy: ERROR_GEN_FAILURE (http result code wasn't 2xx)
+// ERROR_INVALID_DATA (no Content-Length header in reply)
+// ERROR_NOT_ENOUGH_MEMORY (Content-Length very large)
+// ERROR_HANDLE_EOF (connection closed before Content-Length bytes recved)
+// anything from select(), MS_NETLIB_RECVHTTPHEADERS,
+// nlu.pfnHttpGatewayUnwrapRecv, socket(), connect(),
+// MS_NETLIB_SENDHTTPREQUEST
+
+EXTERN_C MIR_APP_DLL(int) Netlib_Recv(HNETLIBCONN hConn, char *buf, int len, int flags = 0);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Determine the status of one or more connections
+// Returns the number of ready connections, SOCKET_ERROR on failure, 0 if the timeout expired.
+// All handles passed to this function must have been returned by either
+// MS_NETLIB_OPENCONNECTION or MS_NETLIB_BINDPORT.
+// The last handle in each list must be followed by either NULL or INVALID_HANDLE_VALUE.
+// Errors: ERROR_INVALID_HANDLE, ERROR_INVALID_DATA, anything from select()
+
+struct NETLIBSELECT
+{
+ uint32_t dwTimeout; // in milliseconds, INFINITE is acceptable
+ HNETLIBCONN hReadConns[FD_SETSIZE + 1];
+ HNETLIBCONN hWriteConns[FD_SETSIZE + 1];
+ HNETLIBCONN hExceptConns[FD_SETSIZE + 1];
+};
+
+EXTERN_C MIR_APP_DLL(int) Netlib_Select(NETLIBSELECT *nls);
+
+struct NETLIBSELECTEX
+{
+ uint32_t dwTimeout; // in milliseconds, INFINITE is acceptable
+ HNETLIBCONN hReadConns[FD_SETSIZE + 1];
+ HNETLIBCONN hWriteConns[FD_SETSIZE + 1];
+ HNETLIBCONN hExceptConns[FD_SETSIZE + 1];
+
+ BOOL hReadStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */
+ BOOL hWriteStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */
+ BOOL hExceptStatus[FD_SETSIZE+1]; /* out, [in, expected to be FALSE] */
+};
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SelectEx(NETLIBSELECTEX *nls);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Shutdown connection
+
+EXTERN_C MIR_APP_DLL(void) Netlib_Shutdown(HNETLIBCONN h);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Create a packet receiver
+//
+// Returns a HANDLE on success, NULL on failure
+// The packet receiver implements the common situation where you have variable
+// length packets coming in over a connection and you want to split them up
+// in order to handle them.
+// The major limitation is that the buffer is created in memory, so you can't
+// have arbitrarily large packets.
+// Errors: ERROR_INVALID_PARAMETER, ERROR_OUTOFMEMORY
+
+EXTERN_C MIR_APP_DLL(HANDLE) Netlib_CreatePacketReceiver(HNETLIBCONN hConnection, int iMaxSize);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Get the next set of packets from a packet receiver
+//
+// Returns the total number of bytes available in the buffer, 0 if the
+// connection was closed, SOCKET_ERROR on error.
+// hPacketRecver must have been returned by MS_NETLIB_CREATEPACKETRECVER
+// If nlpr.bytesUsed is set to zero and the buffer is already full up to
+// maxPacketSize, it is assumed that too large a packet has been received. All
+// data in the buffer is discarded and receiving is begun anew. This will
+// probably cause alignment problems so if you think this is likely to happen
+// then you should deal with it yourself.
+// Closing the packet receiver will not close the associated connection, but
+// will discard any bytes still in the buffer, so if you intend to carry on
+// reading from that connection, make sure you have processed the buffer first.
+// This function is the equivalent of a memmove() to remove the first bytesUsed
+// from the buffer, select() if dwTimeout is not INFINITE, then MS_NETLIB_RECV.
+// Errors: ERROR_INVALID_PARAMETER, ERROR_TIMEOUT,
+// anything from select(), MS_NETLIB_RECV
+
+struct NETLIBPACKETRECVER
+{
+ uint32_t dwTimeout; // fill before calling. In milliseconds. INFINITE is valid
+ int bytesUsed; // fill before calling. This many bytes are removed from the start of the buffer. Set to 0 on return
+ int bytesAvailable; // equal to the return value, unless the return value is 0
+ int bufferSize; // same as parameter to MS_NETLIB_CREATEPACKETRECVER
+ uint8_t *buffer; // contains the recved data
+};
+
+EXTERN_C MIR_APP_DLL(int) Netlib_GetMorePackets(HANDLE hReceiver, NETLIBPACKETRECVER *nlprParam);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Sets a gateway polling timeout interval
+//
+// Returns previous timeout value
+// Errors: -1
+
+EXTERN_C MIR_APP_DLL(int) Netlib_SetPollingTimeout(HNETLIBCONN hConnection, int iTimeout);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// netlib log funcitons
+
+EXTERN_C MIR_APP_DLL(int) Netlib_Log(HNETLIBUSER hUser, const char *pszStr);
+EXTERN_C MIR_APP_DLL(int) Netlib_LogW(HNETLIBUSER hUser, const wchar_t *pwszStr);
+
+EXTERN_C MIR_APP_DLL(int) Netlib_Logf(HNETLIBUSER hUser, _Printf_format_string_ const char *fmt, ...);
+EXTERN_C MIR_APP_DLL(int) Netlib_LogfW(HNETLIBUSER hUser, _Printf_format_string_ const wchar_t *fmt, ...);
+
+EXTERN_C MIR_APP_DLL(void) Netlib_Dump(HNETLIBCONN nlc, const void *buf, size_t len, bool bIsSent, int flags);
+
+// Inits a required security provider. Right now only NTLM is supported
+// Returns HANDLE = NULL on error or non-null value on success
+// Known providers: Basic, NTLM, Negotiate, Kerberos, GSSAPI - (Kerberos SASL)
+EXTERN_C MIR_APP_DLL(HANDLE) Netlib_InitSecurityProvider(const wchar_t *szProviderName, const wchar_t *szPrincipal = nullptr);
+
+// Destroys a security provider's handle, provided by Netlib_InitSecurityProvider.
+// Right now only NTLM is supported
+EXTERN_C MIR_APP_DLL(void) Netlib_DestroySecurityProvider(HANDLE hProvider);
+
+// Returns the NTLM response string. The result value should be freed using mir_free
+EXTERN_C MIR_APP_DLL(char*) Netlib_NtlmCreateResponse(HANDLE hProvider, const char *szChallenge, wchar_t *szLogin, wchar_t *szPass, unsigned &complete);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// SSL/TLS support
+
+#if !defined(HSSL_DEFINED)
+DECLARE_HANDLE(HSSL);
+#endif
+
+// Makes connection SSL
+// Returns 0 on failure 1 on success
+EXTERN_C MIR_APP_DLL(int) Netlib_StartSsl(HNETLIBCONN hConnection, const char *host);
+
+// negotiates SSL session, verifies cert, returns NULL if failed
+EXTERN_C MIR_APP_DLL(HSSL) Netlib_SslConnect(SOCKET s, const char* host, int verify);
+
+// return true if there is either unsend or buffered received data (ie. after peek)
+EXTERN_C MIR_APP_DLL(BOOL) Netlib_SslPending(HSSL ssl);
+
+// reads number of bytes, keeps in buffer if peek != 0
+EXTERN_C MIR_APP_DLL(int) Netlib_SslRead(HSSL ssl, char *buf, int num, int peek);
+
+// writes data to the SSL socket
+EXTERN_C MIR_APP_DLL(int) Netlib_SslWrite(HSSL ssl, const char *buf, int num);
+
+// closes SSL session, but keeps socket open
+EXTERN_C MIR_APP_DLL(void) Netlib_SslShutdown(HSSL ssl);
+
+// frees all data associated with the SSL socket
+EXTERN_C MIR_APP_DLL(void) Netlib_SslFree(HSSL ssl);
+
+// gets TLS channel binging data for a socket
+EXTERN_C MIR_APP_DLL(void*) Netlib_GetTlsUnique(HNETLIBCONN nlc, int &cbLen, int &tlsVer);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// WebSocket support
+
+struct WSHeader
+{
+ WSHeader()
+ {
+ memset(this, 0, sizeof(*this));
+ }
+
+ bool bIsFinal, bIsMasked;
+ int opCode, firstByte;
+ size_t payloadSize, headerSize;
+};
+
+// connects to a WebSocket server
+EXTERN_C MIR_APP_DLL(NETLIBHTTPREQUEST*) WebSocket_Connect(HNETLIBUSER, const char *szHost, NETLIBHTTPHEADER *pHeaders = nullptr);
+
+// validates that the provided buffer contains full WebSocket datagram
+EXTERN_C MIR_APP_DLL(bool) WebSocket_InitHeader(WSHeader &hdr, const void *pData, size_t bufSize);
+
+// sends a packet to WebSocket
+EXTERN_C MIR_APP_DLL(void) WebSocket_SendText(HNETLIBCONN nlc, const char *pData);
+EXTERN_C MIR_APP_DLL(void) WebSocket_SendBinary(HNETLIBCONN nlc, const void *pData, size_t strLen);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Netlib hooks (0.8+)
+
+// WARNING: these hooks are being called in the context of the calling thread, without switching
+// to the first thread, like all another events do. The hook procedure should be ready for the
+// multithreaded mode
+//
+// Parameters:
+// wParam: NETLIBNOTIFY* - points to the data being sent/received
+// lParam: NETLIBUSER* - points to the protocol definition
+
+struct NETLIBNOTIFY
+{
+ const char *buf;
+ int len;
+ int flags;
+ int result; // amount of bytes really sent/received
+};
+
+#define ME_NETLIB_FASTRECV "Netlib/OnRecv" // being called on every receive
+#define ME_NETLIB_FASTSEND "Netlib/OnSend" // being called on every send
+#define ME_NETLIB_FASTDUMP "Netlib/OnDump" // being called on every dump
+
+struct NETLIBCONNECTIONEVENTINFO
+{
+ BOOL connected; // 1-opening socket 0-closing socket
+ BOOL listening; // 1-bind 0-connect
+ SOCKADDR_IN local; // local IP+port (always used)
+ SOCKADDR_IN remote; // remote IP+port (only connect (opening + closing only if no proxy))
+ SOCKADDR_IN proxy; // proxy IP+port (only connect when used)
+ char *szSettingsModule; // name of the registered Netlib user that requested the action
+};
+
+//This event is sent as a new port is bound or a new connection opened.
+//It is NOT sent for sigle HTTP(S) requests.
+//wParam=(WPARAM)(NETLIBCONNECTIONEVENTINFO*)hInfo
+//lParam=(LPARAM)0 (not used)
+#define ME_NETLIB_EVENT_CONNECTED "Netlib/Event/Connected"
+
+//This event is sent if coneection or listening socket is closed.
+//It is NOT sent for sigle HTTP(S) requests.
+//wParam=(WPARAM)(NETLIBCONNECTIONEVENTINFO*)hInfo
+//lParam=(LPARAM)0 (not used)
+#define ME_NETLIB_EVENT_DISCONNECTED "Netlib/Event/Disconnected"
+
+#endif // M_NETLIB_H__
diff --git a/include/m_options.h b/include/m_options.h index b60b84a711..e2cdc1122d 100644 --- a/include/m_options.h +++ b/include/m_options.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_protocols.h b/include/m_protocols.h index 889de6882a..927443bb69 100644 --- a/include/m_protocols.h +++ b/include/m_protocols.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_protoint.h b/include/m_protoint.h index 1eea83eaa8..972ca5a9da 100644 --- a/include/m_protoint.h +++ b/include/m_protoint.h @@ -1,313 +1,313 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-08 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef M_PROTOINT_H__ -#define M_PROTOINT_H__ 1 - -#include <m_system.h> -#include <m_protosvc.h> -#include <m_database.h> -#include <m_genmenu.h> -#include <m_utils.h> - -///////////////////////////////////////////////////////////////////////////////////////// -// protocol helpers - -struct PROTO_INTERFACE; - -// Call it in the very beginning of your proto's constructor -EXTERN_C MIR_APP_DLL(void) ProtoConstructor(PROTO_INTERFACE *pThis, const char *pszModuleName, const wchar_t *ptszUserName); - -// Call it in the very end of your proto's destructor -EXTERN_C MIR_APP_DLL(void) ProtoDestructor(PROTO_INTERFACE *pThis); - -#if defined( __cplusplus ) -typedef void (MIR_CDECL PROTO_INTERFACE::*ProtoThreadFunc)(void*); -EXTERN_C MIR_APP_DLL(void) ProtoForkThread(PROTO_INTERFACE *pThis, ProtoThreadFunc, void *param); -EXTERN_C MIR_APP_DLL(HANDLE) ProtoForkThreadEx(PROTO_INTERFACE *pThis, ProtoThreadFunc, void *param, UINT* threadID); -EXTERN_C MIR_APP_DLL(void) ProtoWindowAdd(PROTO_INTERFACE *pThis, HWND hwnd); -EXTERN_C MIR_APP_DLL(void) ProtoWindowRemove(PROTO_INTERFACE *pThis, HWND hwnd); - -typedef int (MIR_CDECL PROTO_INTERFACE::*ProtoEventFunc)(WPARAM, LPARAM); -EXTERN_C MIR_APP_DLL(void) ProtoHookEvent(PROTO_INTERFACE *pThis, const char* szName, ProtoEventFunc pFunc); -EXTERN_C MIR_APP_DLL(HANDLE) ProtoCreateHookableEvent(PROTO_INTERFACE *pThis, const char* szService); - -typedef INT_PTR (MIR_CDECL PROTO_INTERFACE::*ProtoServiceFunc)(WPARAM, LPARAM); -EXTERN_C MIR_APP_DLL(void) ProtoCreateService(PROTO_INTERFACE *pThis, const char* szService, ProtoServiceFunc); - -typedef INT_PTR (MIR_CDECL PROTO_INTERFACE::*ProtoServiceFuncParam)(WPARAM, LPARAM, LPARAM); -EXTERN_C MIR_APP_DLL(void) ProtoCreateServiceParam(PROTO_INTERFACE *pThis, const char* szService, ProtoServiceFuncParam, LPARAM); -#endif - -///////////////////////////////////////////////////////////////////////////////////////// -// interface declaration - -enum ProtoMenuItemType -{ - PROTO_MENU_REQ_AUTH, - PROTO_MENU_GRANT_AUTH, - PROTO_MENU_REVOKE_AUTH, - PROTO_MENU_LOAD_HISTORY -}; - -struct MIR_APP_EXPORT PROTO_INTERFACE : public MZeroedObject -{ - -protected: - MWindowList m_hWindowList = 0; // list of all windows which belong to this protocol's instance - -public: - int m_iStatus; // current protocol status - int m_iDesiredStatus; // status to be set after logging in - int m_iXStatus; // extanded status - int m_iVersion; // version 2 or higher designate support of Unicode services - wchar_t* m_tszUserName; // human readable protocol's name - char* m_szModuleName; // internal protocol name, also its database module name - HANDLE m_hProtoIcon = 0; // icon to be displayed in the account manager - HNETLIBUSER m_hNetlibUser = 0; // network agent - HGENMENU m_hmiMainMenu = 0; // if protocol menus are displayed in the main menu, this is the root - - PROTO_INTERFACE(const char *pszModuleName, const wchar_t *ptszUserName); - ~PROTO_INTERFACE(); - - ////////////////////////////////////////////////////////////////////////////////////// - // Helpers - - __forceinline INT_PTR ProtoBroadcastAck(MCONTACT hContact, int type, int hResult, HANDLE hProcess, LPARAM lParam = 0) { - return ::ProtoBroadcastAck(m_szModuleName, hContact, type, hResult, hProcess, lParam); } - __forceinline void ProtoBroadcastAsync(MCONTACT hContact, int type, int hResult, HANDLE hProcess, LPARAM lParam = 0) { - return ::ProtoBroadcastAsync(m_szModuleName, hContact, type, hResult, hProcess, lParam); } - - __forceinline INT_PTR delSetting(const char *name) { return db_unset(0, m_szModuleName, name); } - __forceinline INT_PTR delSetting(MCONTACT hContact, const char *name) { return db_unset(hContact, m_szModuleName, name); } - - __forceinline bool getBool(const char *name, bool defaultValue = false) { - return db_get_b(0, m_szModuleName, name, defaultValue) != 0; } - __forceinline bool getBool(MCONTACT hContact, const char *name, bool defaultValue = false) { - return db_get_b(hContact, m_szModuleName, name, defaultValue) != 0; } - - MBinBuffer getBlob(const char *pSetting); - MBinBuffer getBlob(MCONTACT hContact, const char *pSetting); - - __forceinline bool isChatRoom(MCONTACT hContact) { return getBool(hContact, "ChatRoom", false); } - - __forceinline int getByte(const char *name, uint8_t defaultValue = 0) { - return db_get_b(0, m_szModuleName, name, defaultValue); } - __forceinline int getByte(MCONTACT hContact, const char *name, uint8_t defaultValue = 0) { - return db_get_b(hContact, m_szModuleName, name, defaultValue); } - - __forceinline int getWord(const char *name, uint16_t defaultValue = 0) { - return db_get_w(0, m_szModuleName, name, defaultValue); } - __forceinline int getWord(MCONTACT hContact, const char *name, uint16_t defaultValue = 0) { - return db_get_w(hContact, m_szModuleName, name, defaultValue); } - - __forceinline uint32_t getDword(const char *name, uint32_t defaultValue = 0) { - return db_get_dw(0, m_szModuleName, name, defaultValue); } - __forceinline uint32_t getDword(MCONTACT hContact, const char *name, uint32_t defaultValue = 0) { - return db_get_dw(hContact, m_szModuleName, name, defaultValue); } - - __forceinline INT_PTR getString(const char *name, DBVARIANT *result) { - return db_get_s(0, m_szModuleName, name, result, DBVT_ASCIIZ); } - __forceinline INT_PTR getString(MCONTACT hContact, const char *name, DBVARIANT *result) { - return db_get_s(hContact, m_szModuleName, name, result, DBVT_ASCIIZ); } - - __forceinline INT_PTR getUString(const char *name, DBVARIANT *result) { - return db_get_s(0, m_szModuleName, name, result, DBVT_UTF8); } - __forceinline INT_PTR getUString(MCONTACT hContact, const char *name, DBVARIANT *result) { - return db_get_s(hContact, m_szModuleName, name, result, DBVT_UTF8); } - - __forceinline INT_PTR getWString(const char *name, DBVARIANT *result) { - return db_get_s(0, m_szModuleName, name, result, DBVT_WCHAR); } - __forceinline INT_PTR getWString(MCONTACT hContact, const char *name, DBVARIANT *result) { - return db_get_s(hContact, m_szModuleName, name, result, DBVT_WCHAR); } - - __forceinline char* getStringA(const char *name, const char *szValue = nullptr) { - return db_get_sa(0, m_szModuleName, name, szValue); } - __forceinline char* getStringA(MCONTACT hContact, const char *name, const char *szValue = nullptr) { - return db_get_sa(hContact, m_szModuleName, name, szValue); } - - __forceinline char* getUStringA(const char *name, const char *szValue = nullptr) { - return db_get_utfa(0, m_szModuleName, name, szValue); } - __forceinline char* getUStringA(MCONTACT hContact, const char *name, const char *szValue = nullptr) { - return db_get_utfa(hContact, m_szModuleName, name, szValue); } - - __forceinline wchar_t* getWStringA(const char *name, const wchar_t *szValue = nullptr) { - return db_get_wsa(0, m_szModuleName, name, szValue); } - __forceinline wchar_t* getWStringA(MCONTACT hContact, const char *name, const wchar_t *szValue = nullptr) { - return db_get_wsa(hContact, m_szModuleName, name, szValue); } - - __forceinline CMStringA getMStringA(const char *name, const char *szValue = nullptr) { - return db_get_sm(0, m_szModuleName, name, szValue); } - __forceinline CMStringA getMStringA(MCONTACT hContact, const char *name, const char *szValue = nullptr) { - return db_get_sm(hContact, m_szModuleName, name, szValue); } - - __forceinline CMStringW getMStringW(const char *name, const wchar_t *szValue = nullptr) { - return db_get_wsm(0, m_szModuleName, name, szValue); } - __forceinline CMStringW getMStringW(MCONTACT hContact, const char *name, const wchar_t *szValue = nullptr) { - return db_get_wsm(hContact, m_szModuleName, name, szValue); } - - __forceinline void setByte(const char *name, uint8_t value) { db_set_b(0, m_szModuleName, name, value); } - __forceinline void setByte(MCONTACT hContact, const char *name, uint8_t value) { db_set_b(hContact, m_szModuleName, name, value); } - - __forceinline void setWord(const char *name, uint16_t value) { db_set_w(0, m_szModuleName, name, value); } - __forceinline void setWord(MCONTACT hContact, const char *name, uint16_t value) { db_set_w(hContact, m_szModuleName, name, value); } - - __forceinline void setDword(const char *name, uint32_t value) { db_set_dw(0, m_szModuleName, name, value); } - __forceinline void setDword(MCONTACT hContact, const char *name, uint32_t value) { db_set_dw(hContact, m_szModuleName, name, value); } - - __forceinline void setString(const char *name, const char* value) { db_set_s(0, m_szModuleName, name, value); } - __forceinline void setString(MCONTACT hContact, const char *name, const char* value) { db_set_s(hContact, m_szModuleName, name, value); } - - __forceinline void setUString(const char *name, const char* value) { db_set_utf(0, m_szModuleName, name, value); } - __forceinline void setUString(MCONTACT hContact, const char *name, const char* value) { db_set_utf(hContact, m_szModuleName, name, value); } - - __forceinline void setWString(const char *name, const wchar_t* value) { db_set_ws(0, m_szModuleName, name, value); } - __forceinline void setWString(MCONTACT hContact, const char *name, const wchar_t* value) { db_set_ws(hContact, m_szModuleName, name, value); } - - __forceinline Contacts AccContacts() const { return Contacts(m_szModuleName); } - - ////////////////////////////////////////////////////////////////////////////////////// - // Service functions - - void debugLogA(const char *szFormat, ...); - void debugLogW(const wchar_t *wszFormat, ...); - - void setAllContactStatuses(int iStatus, bool bSkipChats = true); - - void ReportSelfAvatarChanged(); - - void WindowSubscribe(HWND hwnd); - void WindowUnsubscribe(HWND hwnd); - - HGENMENU GetMenuItem(ProtoMenuItemType); - - ////////////////////////////////////////////////////////////////////////////////////// - // Virtual functions - - virtual MCONTACT AddToList(int flags, PROTOSEARCHRESULT *psr); - virtual MCONTACT AddToListByEvent(int flags, int iContact, MEVENT hDbEvent); - - virtual int Authorize(MEVENT hDbEvent); - virtual int AuthDeny(MEVENT hDbEvent, const wchar_t *szReason); - virtual int AuthRecv(MCONTACT hContact, PROTORECVEVENT *); - virtual int AuthRequest(MCONTACT hContact, const wchar_t *szMessage); - - virtual HANDLE FileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szPath); - virtual int FileCancel(MCONTACT hContact, HANDLE hTransfer); - virtual int FileDeny(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szReason); - virtual int FileResume(HANDLE hTransfer, int action, const wchar_t *szFilename); - - virtual INT_PTR GetCaps(int type, MCONTACT hContact = 0); - virtual int GetInfo(MCONTACT hContact, int infoType); - - virtual HANDLE SearchBasic(const wchar_t *id); - virtual HANDLE SearchByEmail(const wchar_t *email); - virtual HANDLE SearchByName(const wchar_t *nick, const wchar_t *firstName, const wchar_t *lastName); - virtual HWND SearchAdvanced(HWND owner); - virtual HWND CreateExtendedSearchUI(HWND owner); - - virtual int RecvContacts(MCONTACT hContact, PROTORECVEVENT *); - virtual int RecvFile(MCONTACT hContact, PROTORECVFILE *); - virtual MEVENT RecvMsg(MCONTACT hContact, PROTORECVEVENT *); - - virtual int SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList); - virtual HANDLE SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles); - virtual int SendMsg(MCONTACT hContact, int flags, const char *msg); - - virtual int SetApparentMode(MCONTACT hContact, int mode); - virtual int SetStatus(int iNewStatus); - - virtual HANDLE GetAwayMsg(MCONTACT hContact); - virtual int RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT *evt); - virtual int SetAwayMsg(int iStatus, const wchar_t *msg); - - virtual int UserIsTyping(MCONTACT hContact, int type); - - ////////////////////////////////////////////////////////////////////////////////////// - // events - - // builds the account's protocol menu - virtual void OnBuildProtoMenu(void); - - // called when an account's contact is added - virtual void OnContactAdded(MCONTACT); - - // called when an account's contact is deleted - virtual void OnContactDeleted(MCONTACT); - - // called when an event is altered in database - virtual void OnEventEdited(MCONTACT, MEVENT); - - // called when an account gets physically removed from the database - virtual void OnErase(); - - // the analog of ME_SYSTEM_MODULESLOADED for an account - virtual void OnModulesLoaded(void); - - // same for ME_SYSTEM_SHUTDOWN - virtual void OnShutdown(void); - - // same for ME_SYSTEM_OKTOEXIT - virtual bool IsReadyToExit(void); -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Basic class for all protocols written in C++ - -template<class T> struct PROTO : public PROTO_INTERFACE -{ - typedef PROTO_INTERFACE CSuper; - - __forceinline PROTO(const char *szProto, const wchar_t *tszUserName) : - PROTO_INTERFACE(szProto, tszUserName) - {} - - __forceinline HANDLE CreateProtoEvent(const char *name) { - return ::ProtoCreateHookableEvent(this, name); } - - typedef int(MIR_CDECL T::*MyEventFunc)(WPARAM, LPARAM); - __forceinline void HookProtoEvent(const char *name, MyEventFunc pFunc) { - ::ProtoHookEvent(this, name, (ProtoEventFunc)pFunc); } - - typedef void(MIR_CDECL T::*MyThreadFunc)(void*); - __forceinline void ForkThread(MyThreadFunc pFunc, void *param = nullptr) { - ::ProtoForkThread(this, (ProtoThreadFunc)pFunc, param); } - HANDLE __forceinline ForkThreadEx(MyThreadFunc pFunc, void *param, UINT *pThreadId) { - return ::ProtoForkThreadEx(this, (ProtoThreadFunc)pFunc, param, pThreadId); } - - typedef INT_PTR(MIR_CDECL T::*MyServiceFunc)(WPARAM, LPARAM); - __forceinline void CreateProtoService(const char *name, MyServiceFunc pFunc) { - ::ProtoCreateService(this, name, (ProtoServiceFunc)pFunc); } - - typedef INT_PTR(MIR_CDECL T::*MyServiceFuncParam)(WPARAM, LPARAM, LPARAM); - __forceinline void CreateProtoServiceParam(const char *name, MyServiceFuncParam pFunc, LPARAM param) { - ::ProtoCreateServiceParam(this, name, (ProtoServiceFuncParam)pFunc, param); } -}; - -///////////////////////////////////////////////////////////////////////////////////////// - -MIR_APP_DLL(PROTO_INTERFACE *) Proto_GetInstance(const char *szModule); -MIR_APP_DLL(PROTO_INTERFACE *) Proto_GetInstance(MCONTACT hContact); - -#endif // M_PROTOINT_H__ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-08 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_PROTOINT_H__
+#define M_PROTOINT_H__ 1
+
+#include <m_system.h>
+#include <m_protosvc.h>
+#include <m_database.h>
+#include <m_genmenu.h>
+#include <m_utils.h>
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// protocol helpers
+
+struct PROTO_INTERFACE;
+
+// Call it in the very beginning of your proto's constructor
+EXTERN_C MIR_APP_DLL(void) ProtoConstructor(PROTO_INTERFACE *pThis, const char *pszModuleName, const wchar_t *ptszUserName);
+
+// Call it in the very end of your proto's destructor
+EXTERN_C MIR_APP_DLL(void) ProtoDestructor(PROTO_INTERFACE *pThis);
+
+#if defined( __cplusplus )
+typedef void (MIR_CDECL PROTO_INTERFACE::*ProtoThreadFunc)(void*);
+EXTERN_C MIR_APP_DLL(void) ProtoForkThread(PROTO_INTERFACE *pThis, ProtoThreadFunc, void *param);
+EXTERN_C MIR_APP_DLL(HANDLE) ProtoForkThreadEx(PROTO_INTERFACE *pThis, ProtoThreadFunc, void *param, UINT* threadID);
+EXTERN_C MIR_APP_DLL(void) ProtoWindowAdd(PROTO_INTERFACE *pThis, HWND hwnd);
+EXTERN_C MIR_APP_DLL(void) ProtoWindowRemove(PROTO_INTERFACE *pThis, HWND hwnd);
+
+typedef int (MIR_CDECL PROTO_INTERFACE::*ProtoEventFunc)(WPARAM, LPARAM);
+EXTERN_C MIR_APP_DLL(void) ProtoHookEvent(PROTO_INTERFACE *pThis, const char* szName, ProtoEventFunc pFunc);
+EXTERN_C MIR_APP_DLL(HANDLE) ProtoCreateHookableEvent(PROTO_INTERFACE *pThis, const char* szService);
+
+typedef INT_PTR (MIR_CDECL PROTO_INTERFACE::*ProtoServiceFunc)(WPARAM, LPARAM);
+EXTERN_C MIR_APP_DLL(void) ProtoCreateService(PROTO_INTERFACE *pThis, const char* szService, ProtoServiceFunc);
+
+typedef INT_PTR (MIR_CDECL PROTO_INTERFACE::*ProtoServiceFuncParam)(WPARAM, LPARAM, LPARAM);
+EXTERN_C MIR_APP_DLL(void) ProtoCreateServiceParam(PROTO_INTERFACE *pThis, const char* szService, ProtoServiceFuncParam, LPARAM);
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// interface declaration
+
+enum ProtoMenuItemType
+{
+ PROTO_MENU_REQ_AUTH,
+ PROTO_MENU_GRANT_AUTH,
+ PROTO_MENU_REVOKE_AUTH,
+ PROTO_MENU_LOAD_HISTORY
+};
+
+struct MIR_APP_EXPORT PROTO_INTERFACE : public MZeroedObject
+{
+
+protected:
+ MWindowList m_hWindowList = 0; // list of all windows which belong to this protocol's instance
+
+public:
+ int m_iStatus; // current protocol status
+ int m_iDesiredStatus; // status to be set after logging in
+ int m_iXStatus; // extanded status
+ int m_iVersion; // version 2 or higher designate support of Unicode services
+ wchar_t* m_tszUserName; // human readable protocol's name
+ char* m_szModuleName; // internal protocol name, also its database module name
+ HANDLE m_hProtoIcon = 0; // icon to be displayed in the account manager
+ HNETLIBUSER m_hNetlibUser = 0; // network agent
+ HGENMENU m_hmiMainMenu = 0; // if protocol menus are displayed in the main menu, this is the root
+
+ PROTO_INTERFACE(const char *pszModuleName, const wchar_t *ptszUserName);
+ ~PROTO_INTERFACE();
+
+ //////////////////////////////////////////////////////////////////////////////////////
+ // Helpers
+
+ __forceinline INT_PTR ProtoBroadcastAck(MCONTACT hContact, int type, int hResult, HANDLE hProcess, LPARAM lParam = 0) {
+ return ::ProtoBroadcastAck(m_szModuleName, hContact, type, hResult, hProcess, lParam); }
+ __forceinline void ProtoBroadcastAsync(MCONTACT hContact, int type, int hResult, HANDLE hProcess, LPARAM lParam = 0) {
+ return ::ProtoBroadcastAsync(m_szModuleName, hContact, type, hResult, hProcess, lParam); }
+
+ __forceinline INT_PTR delSetting(const char *name) { return db_unset(0, m_szModuleName, name); }
+ __forceinline INT_PTR delSetting(MCONTACT hContact, const char *name) { return db_unset(hContact, m_szModuleName, name); }
+
+ __forceinline bool getBool(const char *name, bool defaultValue = false) {
+ return db_get_b(0, m_szModuleName, name, defaultValue) != 0; }
+ __forceinline bool getBool(MCONTACT hContact, const char *name, bool defaultValue = false) {
+ return db_get_b(hContact, m_szModuleName, name, defaultValue) != 0; }
+
+ MBinBuffer getBlob(const char *pSetting);
+ MBinBuffer getBlob(MCONTACT hContact, const char *pSetting);
+
+ __forceinline bool isChatRoom(MCONTACT hContact) { return getBool(hContact, "ChatRoom", false); }
+
+ __forceinline int getByte(const char *name, uint8_t defaultValue = 0) {
+ return db_get_b(0, m_szModuleName, name, defaultValue); }
+ __forceinline int getByte(MCONTACT hContact, const char *name, uint8_t defaultValue = 0) {
+ return db_get_b(hContact, m_szModuleName, name, defaultValue); }
+
+ __forceinline int getWord(const char *name, uint16_t defaultValue = 0) {
+ return db_get_w(0, m_szModuleName, name, defaultValue); }
+ __forceinline int getWord(MCONTACT hContact, const char *name, uint16_t defaultValue = 0) {
+ return db_get_w(hContact, m_szModuleName, name, defaultValue); }
+
+ __forceinline uint32_t getDword(const char *name, uint32_t defaultValue = 0) {
+ return db_get_dw(0, m_szModuleName, name, defaultValue); }
+ __forceinline uint32_t getDword(MCONTACT hContact, const char *name, uint32_t defaultValue = 0) {
+ return db_get_dw(hContact, m_szModuleName, name, defaultValue); }
+
+ __forceinline INT_PTR getString(const char *name, DBVARIANT *result) {
+ return db_get_s(0, m_szModuleName, name, result, DBVT_ASCIIZ); }
+ __forceinline INT_PTR getString(MCONTACT hContact, const char *name, DBVARIANT *result) {
+ return db_get_s(hContact, m_szModuleName, name, result, DBVT_ASCIIZ); }
+
+ __forceinline INT_PTR getUString(const char *name, DBVARIANT *result) {
+ return db_get_s(0, m_szModuleName, name, result, DBVT_UTF8); }
+ __forceinline INT_PTR getUString(MCONTACT hContact, const char *name, DBVARIANT *result) {
+ return db_get_s(hContact, m_szModuleName, name, result, DBVT_UTF8); }
+
+ __forceinline INT_PTR getWString(const char *name, DBVARIANT *result) {
+ return db_get_s(0, m_szModuleName, name, result, DBVT_WCHAR); }
+ __forceinline INT_PTR getWString(MCONTACT hContact, const char *name, DBVARIANT *result) {
+ return db_get_s(hContact, m_szModuleName, name, result, DBVT_WCHAR); }
+
+ __forceinline char* getStringA(const char *name, const char *szValue = nullptr) {
+ return db_get_sa(0, m_szModuleName, name, szValue); }
+ __forceinline char* getStringA(MCONTACT hContact, const char *name, const char *szValue = nullptr) {
+ return db_get_sa(hContact, m_szModuleName, name, szValue); }
+
+ __forceinline char* getUStringA(const char *name, const char *szValue = nullptr) {
+ return db_get_utfa(0, m_szModuleName, name, szValue); }
+ __forceinline char* getUStringA(MCONTACT hContact, const char *name, const char *szValue = nullptr) {
+ return db_get_utfa(hContact, m_szModuleName, name, szValue); }
+
+ __forceinline wchar_t* getWStringA(const char *name, const wchar_t *szValue = nullptr) {
+ return db_get_wsa(0, m_szModuleName, name, szValue); }
+ __forceinline wchar_t* getWStringA(MCONTACT hContact, const char *name, const wchar_t *szValue = nullptr) {
+ return db_get_wsa(hContact, m_szModuleName, name, szValue); }
+
+ __forceinline CMStringA getMStringA(const char *name, const char *szValue = nullptr) {
+ return db_get_sm(0, m_szModuleName, name, szValue); }
+ __forceinline CMStringA getMStringA(MCONTACT hContact, const char *name, const char *szValue = nullptr) {
+ return db_get_sm(hContact, m_szModuleName, name, szValue); }
+
+ __forceinline CMStringW getMStringW(const char *name, const wchar_t *szValue = nullptr) {
+ return db_get_wsm(0, m_szModuleName, name, szValue); }
+ __forceinline CMStringW getMStringW(MCONTACT hContact, const char *name, const wchar_t *szValue = nullptr) {
+ return db_get_wsm(hContact, m_szModuleName, name, szValue); }
+
+ __forceinline void setByte(const char *name, uint8_t value) { db_set_b(0, m_szModuleName, name, value); }
+ __forceinline void setByte(MCONTACT hContact, const char *name, uint8_t value) { db_set_b(hContact, m_szModuleName, name, value); }
+
+ __forceinline void setWord(const char *name, uint16_t value) { db_set_w(0, m_szModuleName, name, value); }
+ __forceinline void setWord(MCONTACT hContact, const char *name, uint16_t value) { db_set_w(hContact, m_szModuleName, name, value); }
+
+ __forceinline void setDword(const char *name, uint32_t value) { db_set_dw(0, m_szModuleName, name, value); }
+ __forceinline void setDword(MCONTACT hContact, const char *name, uint32_t value) { db_set_dw(hContact, m_szModuleName, name, value); }
+
+ __forceinline void setString(const char *name, const char* value) { db_set_s(0, m_szModuleName, name, value); }
+ __forceinline void setString(MCONTACT hContact, const char *name, const char* value) { db_set_s(hContact, m_szModuleName, name, value); }
+
+ __forceinline void setUString(const char *name, const char* value) { db_set_utf(0, m_szModuleName, name, value); }
+ __forceinline void setUString(MCONTACT hContact, const char *name, const char* value) { db_set_utf(hContact, m_szModuleName, name, value); }
+
+ __forceinline void setWString(const char *name, const wchar_t* value) { db_set_ws(0, m_szModuleName, name, value); }
+ __forceinline void setWString(MCONTACT hContact, const char *name, const wchar_t* value) { db_set_ws(hContact, m_szModuleName, name, value); }
+
+ __forceinline Contacts AccContacts() const { return Contacts(m_szModuleName); }
+
+ //////////////////////////////////////////////////////////////////////////////////////
+ // Service functions
+
+ void debugLogA(const char *szFormat, ...);
+ void debugLogW(const wchar_t *wszFormat, ...);
+
+ void setAllContactStatuses(int iStatus, bool bSkipChats = true);
+
+ void ReportSelfAvatarChanged();
+
+ void WindowSubscribe(HWND hwnd);
+ void WindowUnsubscribe(HWND hwnd);
+
+ HGENMENU GetMenuItem(ProtoMenuItemType);
+
+ //////////////////////////////////////////////////////////////////////////////////////
+ // Virtual functions
+
+ virtual MCONTACT AddToList(int flags, PROTOSEARCHRESULT *psr);
+ virtual MCONTACT AddToListByEvent(int flags, int iContact, MEVENT hDbEvent);
+
+ virtual int Authorize(MEVENT hDbEvent);
+ virtual int AuthDeny(MEVENT hDbEvent, const wchar_t *szReason);
+ virtual int AuthRecv(MCONTACT hContact, PROTORECVEVENT *);
+ virtual int AuthRequest(MCONTACT hContact, const wchar_t *szMessage);
+
+ virtual HANDLE FileAllow(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szPath);
+ virtual int FileCancel(MCONTACT hContact, HANDLE hTransfer);
+ virtual int FileDeny(MCONTACT hContact, HANDLE hTransfer, const wchar_t *szReason);
+ virtual int FileResume(HANDLE hTransfer, int action, const wchar_t *szFilename);
+
+ virtual INT_PTR GetCaps(int type, MCONTACT hContact = 0);
+ virtual int GetInfo(MCONTACT hContact, int infoType);
+
+ virtual HANDLE SearchBasic(const wchar_t *id);
+ virtual HANDLE SearchByEmail(const wchar_t *email);
+ virtual HANDLE SearchByName(const wchar_t *nick, const wchar_t *firstName, const wchar_t *lastName);
+ virtual HWND SearchAdvanced(HWND owner);
+ virtual HWND CreateExtendedSearchUI(HWND owner);
+
+ virtual int RecvContacts(MCONTACT hContact, PROTORECVEVENT *);
+ virtual int RecvFile(MCONTACT hContact, PROTORECVFILE *);
+ virtual MEVENT RecvMsg(MCONTACT hContact, PROTORECVEVENT *);
+
+ virtual int SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList);
+ virtual HANDLE SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles);
+ virtual int SendMsg(MCONTACT hContact, int flags, const char *msg);
+
+ virtual int SetApparentMode(MCONTACT hContact, int mode);
+ virtual int SetStatus(int iNewStatus);
+
+ virtual HANDLE GetAwayMsg(MCONTACT hContact);
+ virtual int RecvAwayMsg(MCONTACT hContact, int mode, PROTORECVEVENT *evt);
+ virtual int SetAwayMsg(int iStatus, const wchar_t *msg);
+
+ virtual int UserIsTyping(MCONTACT hContact, int type);
+
+ //////////////////////////////////////////////////////////////////////////////////////
+ // events
+
+ // builds the account's protocol menu
+ virtual void OnBuildProtoMenu(void);
+
+ // called when an account's contact is added
+ virtual void OnContactAdded(MCONTACT);
+
+ // called when an account's contact is deleted
+ virtual void OnContactDeleted(MCONTACT);
+
+ // called when an event is altered in database
+ virtual void OnEventEdited(MCONTACT, MEVENT);
+
+ // called when an account gets physically removed from the database
+ virtual void OnErase();
+
+ // the analog of ME_SYSTEM_MODULESLOADED for an account
+ virtual void OnModulesLoaded(void);
+
+ // same for ME_SYSTEM_SHUTDOWN
+ virtual void OnShutdown(void);
+
+ // same for ME_SYSTEM_OKTOEXIT
+ virtual bool IsReadyToExit(void);
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Basic class for all protocols written in C++
+
+template<class T> struct PROTO : public PROTO_INTERFACE
+{
+ typedef PROTO_INTERFACE CSuper;
+
+ __forceinline PROTO(const char *szProto, const wchar_t *tszUserName) :
+ PROTO_INTERFACE(szProto, tszUserName)
+ {}
+
+ __forceinline HANDLE CreateProtoEvent(const char *name) {
+ return ::ProtoCreateHookableEvent(this, name); }
+
+ typedef int(MIR_CDECL T::*MyEventFunc)(WPARAM, LPARAM);
+ __forceinline void HookProtoEvent(const char *name, MyEventFunc pFunc) {
+ ::ProtoHookEvent(this, name, (ProtoEventFunc)pFunc); }
+
+ typedef void(MIR_CDECL T::*MyThreadFunc)(void*);
+ __forceinline void ForkThread(MyThreadFunc pFunc, void *param = nullptr) {
+ ::ProtoForkThread(this, (ProtoThreadFunc)pFunc, param); }
+ HANDLE __forceinline ForkThreadEx(MyThreadFunc pFunc, void *param, UINT *pThreadId) {
+ return ::ProtoForkThreadEx(this, (ProtoThreadFunc)pFunc, param, pThreadId); }
+
+ typedef INT_PTR(MIR_CDECL T::*MyServiceFunc)(WPARAM, LPARAM);
+ __forceinline void CreateProtoService(const char *name, MyServiceFunc pFunc) {
+ ::ProtoCreateService(this, name, (ProtoServiceFunc)pFunc); }
+
+ typedef INT_PTR(MIR_CDECL T::*MyServiceFuncParam)(WPARAM, LPARAM, LPARAM);
+ __forceinline void CreateProtoServiceParam(const char *name, MyServiceFuncParam pFunc, LPARAM param) {
+ ::ProtoCreateServiceParam(this, name, (ProtoServiceFuncParam)pFunc, param); }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+MIR_APP_DLL(PROTO_INTERFACE *) Proto_GetInstance(const char *szModule);
+MIR_APP_DLL(PROTO_INTERFACE *) Proto_GetInstance(MCONTACT hContact);
+
+#endif // M_PROTOINT_H__
diff --git a/include/m_protosvc.h b/include/m_protosvc.h index 3aaea79a1e..e6f1df3ab2 100644 --- a/include/m_protosvc.h +++ b/include/m_protosvc.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-09 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_regexp.h b/include/m_regexp.h index f59b2985dc..51bb1cd1ea 100644 --- a/include/m_regexp.h +++ b/include/m_regexp.h @@ -1,106 +1,106 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-08 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef MIM_REGEXP_H -#define MIM_REGEXP_H - -#include <pcre.h> - -class MRegexp16 -{ - pcre16 *m_pattern = nullptr; - pcre16_extra *m_extra = nullptr; - bool m_bIsValid = false; - const wchar_t *m_prevText; - int m_nMatches = 0, m_start = 0; - int m_offsets[100]; - - MRegexp16(const MRegexp16&); // never applied - -public: - MRegexp16() - {} - - MRegexp16(const wchar_t *pwszPattern) - { - compile(pwszPattern); - } - - void compile(const wchar_t *pwszPattern) - { - m_bIsValid = false; - - int erroffset; - const char *err; - m_pattern = ::pcre16_compile(pwszPattern, 0, &err, &erroffset, nullptr); - if (m_pattern == nullptr) - return; - - m_extra = ::pcre16_study(m_pattern, 0, &err); - if (m_extra == nullptr) - return; - - m_bIsValid = true; - } - - ~MRegexp16() - { - if (m_pattern) ::pcre16_free(m_pattern); - if (m_extra) ::pcre16_free(m_extra); - } - - __forceinline bool isValid() const { return m_bIsValid; } - __forceinline int numMatches() const { return m_nMatches; } - - __forceinline int getPos() const { return m_offsets[0]; } - __forceinline int getLength() const { return m_offsets[1] - m_offsets[0]; } - - CMStringW getMatch() - { - return CMStringW(m_prevText + getPos(), getLength()); - } - - CMStringW getGroup(int i) - { - if (i >= m_nMatches) - return L""; - - return CMStringW(m_prevText + m_offsets[i*2], m_offsets[i*2 + 1] - m_offsets[i*2]); - } - - int match(const wchar_t *pwszText) - { - return m_nMatches = ::pcre16_exec(m_pattern, m_extra, m_prevText = pwszText, (int)mir_wstrlen(pwszText), 0, 0, m_offsets, _countof(m_offsets)); - } - - int nextMatch(const wchar_t *pwszText) - { - m_nMatches = ::pcre16_exec(m_pattern, m_extra, m_prevText = pwszText, (int)mir_wstrlen(pwszText), m_start, 0, m_offsets, _countof(m_offsets)); - m_start = (m_nMatches >= 0) ? m_offsets[1] : 0; - - return m_nMatches; - } -}; - -#endif // MIM_REGEXP_H +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-08 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef MIM_REGEXP_H
+#define MIM_REGEXP_H
+
+#include <pcre.h>
+
+class MRegexp16
+{
+ pcre16 *m_pattern = nullptr;
+ pcre16_extra *m_extra = nullptr;
+ bool m_bIsValid = false;
+ const wchar_t *m_prevText;
+ int m_nMatches = 0, m_start = 0;
+ int m_offsets[100];
+
+ MRegexp16(const MRegexp16&); // never applied
+
+public:
+ MRegexp16()
+ {}
+
+ MRegexp16(const wchar_t *pwszPattern)
+ {
+ compile(pwszPattern);
+ }
+
+ void compile(const wchar_t *pwszPattern)
+ {
+ m_bIsValid = false;
+
+ int erroffset;
+ const char *err;
+ m_pattern = ::pcre16_compile(pwszPattern, 0, &err, &erroffset, nullptr);
+ if (m_pattern == nullptr)
+ return;
+
+ m_extra = ::pcre16_study(m_pattern, 0, &err);
+ if (m_extra == nullptr)
+ return;
+
+ m_bIsValid = true;
+ }
+
+ ~MRegexp16()
+ {
+ if (m_pattern) ::pcre16_free(m_pattern);
+ if (m_extra) ::pcre16_free(m_extra);
+ }
+
+ __forceinline bool isValid() const { return m_bIsValid; }
+ __forceinline int numMatches() const { return m_nMatches; }
+
+ __forceinline int getPos() const { return m_offsets[0]; }
+ __forceinline int getLength() const { return m_offsets[1] - m_offsets[0]; }
+
+ CMStringW getMatch()
+ {
+ return CMStringW(m_prevText + getPos(), getLength());
+ }
+
+ CMStringW getGroup(int i)
+ {
+ if (i >= m_nMatches)
+ return L"";
+
+ return CMStringW(m_prevText + m_offsets[i*2], m_offsets[i*2 + 1] - m_offsets[i*2]);
+ }
+
+ int match(const wchar_t *pwszText)
+ {
+ return m_nMatches = ::pcre16_exec(m_pattern, m_extra, m_prevText = pwszText, (int)mir_wstrlen(pwszText), 0, 0, m_offsets, _countof(m_offsets));
+ }
+
+ int nextMatch(const wchar_t *pwszText)
+ {
+ m_nMatches = ::pcre16_exec(m_pattern, m_extra, m_prevText = pwszText, (int)mir_wstrlen(pwszText), m_start, 0, m_offsets, _countof(m_offsets));
+ m_start = (m_nMatches >= 0) ? m_offsets[1] : 0;
+
+ return m_nMatches;
+ }
+};
+
+#endif // MIM_REGEXP_H
diff --git a/include/m_skin.h b/include/m_skin.h index 30168b167d..7d7c66ea40 100644 --- a/include/m_skin.h +++ b/include/m_skin.h @@ -1,6 +1,6 @@ // Miranda NG: the free IM client for Microsoft* Windows*
//
-// Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+// Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
// Copyright (c) 2000-08 Miranda ICQ/IM project,
// all portions of this codebase are copyrighted to the people
// listed in contributors.txt.
diff --git a/include/m_srmm_int.h b/include/m_srmm_int.h index bb7d29f411..c9ac8c14b7 100644 --- a/include/m_srmm_int.h +++ b/include/m_srmm_int.h @@ -1,301 +1,301 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-08 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef M_SRMM_INT_H__ -#define M_SRMM_INT_H__ 1 - -#include <m_gui.h> - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// toolbar button internal representation - -#define MIN_CBUTTONID 4000 -#define MAX_CBUTTONID 5000 - -#define BBSF_IMBUTTON (1<<0) -#define BBSF_CHATBUTTON (1<<1) -#define BBSF_CANBEHIDDEN (1<<2) -#define BBSF_NTBSWAPED (1<<3) -#define BBSF_NTBDESTRUCT (1<<4) - -struct CustomButtonData : public MZeroedObject -{ - ~CustomButtonData() - {} - - int m_dwPosition; // default order pos of button, counted from window edge (left or right) - - int m_dwButtonID; // id of button used while button creation and to store button info in DB - ptrA m_pszModuleName; // module name without spaces and underline symbols (e.g. "tabsrmm") - - int m_dwButtonCID; // button's control id - int m_dwArrowCID; // only use with BBBF_ISARROWBUTTON flag - - ptrW m_pwszText; // button's text - ptrW m_pwszTooltip; // button's tooltip - - int m_iButtonWidth; // must be 22 for regular button and 33 for button with arrow - HANDLE m_hIcon; // Handle to icolib registred icon - - bool m_bIMButton, m_bChatButton; - bool m_bCanBeHidden, m_bCantBeHidden, m_bHidden, m_bSeparator, m_bDisabled, m_bPushButton; - bool m_bRSided; - uint8_t m_opFlags; - HPLUGIN m_pPlugin; - uint32_t m_dwOrigPosition; - struct THotkeyItem *m_hotkey; - - struct { - bool bit1 : 1, bit2 : 1, bit3 : 1, bit4 : 1; - } m_dwOrigFlags; -}; - -// gets the required button or NULL, if i is out of boundaries -EXTERN_C MIR_APP_DLL(CustomButtonData*) Srmm_GetNthButton(int i); - -// retrieves total number of toolbar buttons -EXTERN_C MIR_APP_DLL(int) Srmm_GetButtonCount(void); - -// emulates a click on a toolbar button -EXTERN_C MIR_APP_DLL(void) Srmm_ClickToolbarIcon(MCONTACT hContact, int idFrom, HWND hwndFrom, BOOL code); - -// these messages are sent to the message windows if toolbar buttons are changed -#define WM_CBD_FIRST (WM_USER+0x600) - -// wParam = 0 (ignored) -// lParam = (CustomButtonData*)pointer to button or null if any button can be changed -#define WM_CBD_UPDATED (WM_CBD_FIRST+1) - -// wParam = button id -// lParam = (CustomButtonData*)pointer to button -#define WM_CBD_REMOVED (WM_CBD_FIRST+2) - -// wParam = 0 (ignored) -// lParam = 0 (ignored) -#define WM_CBD_LOADICONS (WM_CBD_FIRST+3) - -// wParam = 0 (ignored) -// lParam = 0 (ignored) -#define WM_CBD_RECREATE (WM_CBD_FIRST+4) - -///////////////////////////////////////////////////////////////////////////////////////// -// SRMM log window container - -class CMsgDialog; - -class MIR_APP_EXPORT CSrmmLogWindow -{ - CSrmmLogWindow(const CSrmmLogWindow &) = delete; - CSrmmLogWindow &operator=(const CSrmmLogWindow &) = delete; - -protected: - CMsgDialog &m_pDlg; - - CSrmmLogWindow(CMsgDialog &pDlg) : - m_pDlg(pDlg) - {} - -public: - virtual ~CSrmmLogWindow() {} - - virtual void Attach() = 0; - virtual void Detach() = 0; - - virtual bool AtBottom() = 0; - virtual void Clear() = 0; - virtual int GetType() = 0; - virtual HWND GetHwnd() = 0; - virtual wchar_t* GetSelection() = 0; - virtual void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) = 0; - virtual void LogEvents(struct LOGINFO *, bool) = 0; - virtual void Resize() = 0; - virtual void ScrollToBottom() = 0; - virtual void UpdateOptions() {}; - - virtual INT_PTR Notify(WPARAM, LPARAM) { return 0; } -}; - -typedef CSrmmLogWindow *(MIR_CDECL *pfnSrmmLogCreator)(CMsgDialog &pDlg); - -EXTERN_C MIR_APP_DLL(HANDLE) RegisterSrmmLog(CMPlugin *pPlugin, const char *pszShortName, const wchar_t *pwszScreenName, pfnSrmmLogCreator fnBuilder); -EXTERN_C MIR_APP_DLL(void) UnregisterSrmmLog(HANDLE); - -///////////////////////////////////////////////////////////////////////////////////////// -// Standard built-in RTF logger class - -class MIR_APP_EXPORT CRtfLogWindow : public CSrmmLogWindow -{ -protected: - CCtrlRichEdit &m_rtf; - -public: - CRtfLogWindow(CMsgDialog &pDlg); - ~CRtfLogWindow() override; - - virtual INT_PTR WndProc(UINT msg, WPARAM wParam, LPARAM lParam); - - //////////////////////////////////////////////////////////////////////////////////////// - void Attach() override; - void Detach() override; - - bool AtBottom() override; - void Clear() override; - HWND GetHwnd() override; - wchar_t* GetSelection() override; - int GetType() override; - void Resize() override; - void ScrollToBottom() override; - - INT_PTR Notify(WPARAM, LPARAM) override; -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Basic SRMM window dialog - -#include <chat_resource.h> - -// message procedures' stubs -EXTERN_C MIR_APP_DLL(LRESULT) CALLBACK stubLogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -EXTERN_C MIR_APP_DLL(LRESULT) CALLBACK stubMessageProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -EXTERN_C MIR_APP_DLL(LRESULT) CALLBACK stubNicklistProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - -class MIR_APP_EXPORT CSrmmBaseDialog : public CDlgBase -{ - friend class CRtfLogWindow; - - CSrmmBaseDialog(const CSrmmBaseDialog &) = delete; - CSrmmBaseDialog &operator=(const CSrmmBaseDialog &) = delete; - -protected: - CSrmmBaseDialog(CMPluginBase &pPlugin, int idDialog, struct SESSION_INFO *si = nullptr); - - bool OnInitDialog() override; - void OnDestroy() override; - - INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override; - - bool AllowTyping() const; - int NotifyEvent(int code); - #ifdef _WINDOWS - bool ProcessFileDrop(HDROP hDrop, MCONTACT hContact); - bool PasteFilesAsURL(HDROP hDrop); - #endif - bool ProcessHotkeys(int key, bool bShift, bool bCtrl, bool bAlt); - void RefreshButtonStatus(void); - void RunUserMenu(HWND hwndOwner, struct USERINFO *ui, const POINT &pt); - -protected: - CSrmmLogWindow *m_pLog = nullptr; - CCtrlRichEdit m_message; - SESSION_INFO *m_si; - COLORREF m_clrInputBG, m_clrInputFG; - - // user typing support; - uint32_t m_nLastTyping = 0; - uint8_t m_bShowTyping = 0; - int m_nTypeSecs = 0, m_nTypeMode = 0; - const USERINFO* m_pUserTyping = nullptr; - - CCtrlListBox m_nickList; - CCtrlButton m_btnColor, m_btnBkColor, m_btnOk; - CCtrlButton m_btnBold, m_btnItalic, m_btnUnderline; - CCtrlButton m_btnHistory, m_btnChannelMgr, m_btnNickList, m_btnFilter; - - void onClick_BIU(CCtrlButton *); - void onClick_Color(CCtrlButton *); - void onClick_BkColor(CCtrlButton *); - - void onClick_ChanMgr(CCtrlButton *); - void onClick_History(CCtrlButton *); - - void onDblClick_List(CCtrlListBox *); - -public: - MCONTACT m_hContact; - int m_iLogFilterFlags; - bool m_bFilterEnabled, m_bNicklistEnabled; - bool m_bFGSet, m_bBGSet; - bool m_bInMenu; - COLORREF m_iFG, m_iBG; - CTimer timerFlash, timerType; - - void ClearLog(); - void RedrawLog(); - void ShowColorChooser(int iCtrlId); - - virtual void AddLog(); - virtual void CloseTab() {} - virtual bool IsActive() const PURE; - virtual void LoadSettings() PURE; - virtual void SetStatusText(const wchar_t *, HICON) {} - virtual void ShowFilterMenu() {} - virtual void UpdateNickList() {} - virtual void UpdateOptions(); - virtual void UpdateStatusBar() {} - virtual void UpdateTitle() PURE; - - virtual LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam); - virtual LRESULT WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam); - - __forceinline bool isChat() const { return m_si != nullptr; } - __forceinline SESSION_INFO *getChat() const { return m_si; } - __forceinline CSrmmLogWindow *log() const { return m_pLog; } - - __forceinline void setTyping(int nSecs, const USERINFO* pUser = nullptr) { - m_pUserTyping = pUser; - m_nTypeSecs = nSecs; - } - - __inline void* operator new(size_t size) { return calloc(1, size); } - __inline void operator delete(void *p) { free(p); } -}; - -#ifndef SRMM_OWN_STRUCTURES -class CMsgDialog : public CSrmmBaseDialog {}; -#endif - -///////////////////////////////////////////////////////////////////////////////////////// -// receives LOGSTREAMDATA* as the first parameter - -#ifdef _WINDOWS -EXTERN_C MIR_APP_DLL(DWORD) CALLBACK Srmm_LogStreamCallback(DWORD_PTR dwCookie, uint8_t *pbBuff, LONG cb, LONG *pcb); -#endif - -///////////////////////////////////////////////////////////////////////////////////////// -// sends a message to all SRMM windows - -EXTERN_C MIR_APP_DLL(void) Srmm_Broadcast(UINT, WPARAM, LPARAM); - -///////////////////////////////////////////////////////////////////////////////////////// -// creates plugin-specific hot key for sending messages - -EXTERN_C MIR_APP_DLL(void) Srmm_CreateHotkey(const char *pszSection, const char *pszDescription); - -///////////////////////////////////////////////////////////////////////////////////////// -// finds a SRMM window using hContact - -EXTERN_C MIR_APP_DLL(HWND) Srmm_FindWindow(MCONTACT hContact); -EXTERN_C MIR_APP_DLL(CMsgDialog*) Srmm_FindDialog(MCONTACT hContact); - -#endif // M_MESSAGE_H__ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-08 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_SRMM_INT_H__
+#define M_SRMM_INT_H__ 1
+
+#include <m_gui.h>
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// toolbar button internal representation
+
+#define MIN_CBUTTONID 4000
+#define MAX_CBUTTONID 5000
+
+#define BBSF_IMBUTTON (1<<0)
+#define BBSF_CHATBUTTON (1<<1)
+#define BBSF_CANBEHIDDEN (1<<2)
+#define BBSF_NTBSWAPED (1<<3)
+#define BBSF_NTBDESTRUCT (1<<4)
+
+struct CustomButtonData : public MZeroedObject
+{
+ ~CustomButtonData()
+ {}
+
+ int m_dwPosition; // default order pos of button, counted from window edge (left or right)
+
+ int m_dwButtonID; // id of button used while button creation and to store button info in DB
+ ptrA m_pszModuleName; // module name without spaces and underline symbols (e.g. "tabsrmm")
+
+ int m_dwButtonCID; // button's control id
+ int m_dwArrowCID; // only use with BBBF_ISARROWBUTTON flag
+
+ ptrW m_pwszText; // button's text
+ ptrW m_pwszTooltip; // button's tooltip
+
+ int m_iButtonWidth; // must be 22 for regular button and 33 for button with arrow
+ HANDLE m_hIcon; // Handle to icolib registred icon
+
+ bool m_bIMButton, m_bChatButton;
+ bool m_bCanBeHidden, m_bCantBeHidden, m_bHidden, m_bSeparator, m_bDisabled, m_bPushButton;
+ bool m_bRSided;
+ uint8_t m_opFlags;
+ HPLUGIN m_pPlugin;
+ uint32_t m_dwOrigPosition;
+ struct THotkeyItem *m_hotkey;
+
+ struct {
+ bool bit1 : 1, bit2 : 1, bit3 : 1, bit4 : 1;
+ } m_dwOrigFlags;
+};
+
+// gets the required button or NULL, if i is out of boundaries
+EXTERN_C MIR_APP_DLL(CustomButtonData*) Srmm_GetNthButton(int i);
+
+// retrieves total number of toolbar buttons
+EXTERN_C MIR_APP_DLL(int) Srmm_GetButtonCount(void);
+
+// emulates a click on a toolbar button
+EXTERN_C MIR_APP_DLL(void) Srmm_ClickToolbarIcon(MCONTACT hContact, int idFrom, HWND hwndFrom, BOOL code);
+
+// these messages are sent to the message windows if toolbar buttons are changed
+#define WM_CBD_FIRST (WM_USER+0x600)
+
+// wParam = 0 (ignored)
+// lParam = (CustomButtonData*)pointer to button or null if any button can be changed
+#define WM_CBD_UPDATED (WM_CBD_FIRST+1)
+
+// wParam = button id
+// lParam = (CustomButtonData*)pointer to button
+#define WM_CBD_REMOVED (WM_CBD_FIRST+2)
+
+// wParam = 0 (ignored)
+// lParam = 0 (ignored)
+#define WM_CBD_LOADICONS (WM_CBD_FIRST+3)
+
+// wParam = 0 (ignored)
+// lParam = 0 (ignored)
+#define WM_CBD_RECREATE (WM_CBD_FIRST+4)
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// SRMM log window container
+
+class CMsgDialog;
+
+class MIR_APP_EXPORT CSrmmLogWindow
+{
+ CSrmmLogWindow(const CSrmmLogWindow &) = delete;
+ CSrmmLogWindow &operator=(const CSrmmLogWindow &) = delete;
+
+protected:
+ CMsgDialog &m_pDlg;
+
+ CSrmmLogWindow(CMsgDialog &pDlg) :
+ m_pDlg(pDlg)
+ {}
+
+public:
+ virtual ~CSrmmLogWindow() {}
+
+ virtual void Attach() = 0;
+ virtual void Detach() = 0;
+
+ virtual bool AtBottom() = 0;
+ virtual void Clear() = 0;
+ virtual int GetType() = 0;
+ virtual HWND GetHwnd() = 0;
+ virtual wchar_t* GetSelection() = 0;
+ virtual void LogEvents(MEVENT hDbEventFirst, int count, bool bAppend) = 0;
+ virtual void LogEvents(struct LOGINFO *, bool) = 0;
+ virtual void Resize() = 0;
+ virtual void ScrollToBottom() = 0;
+ virtual void UpdateOptions() {};
+
+ virtual INT_PTR Notify(WPARAM, LPARAM) { return 0; }
+};
+
+typedef CSrmmLogWindow *(MIR_CDECL *pfnSrmmLogCreator)(CMsgDialog &pDlg);
+
+EXTERN_C MIR_APP_DLL(HANDLE) RegisterSrmmLog(CMPlugin *pPlugin, const char *pszShortName, const wchar_t *pwszScreenName, pfnSrmmLogCreator fnBuilder);
+EXTERN_C MIR_APP_DLL(void) UnregisterSrmmLog(HANDLE);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Standard built-in RTF logger class
+
+class MIR_APP_EXPORT CRtfLogWindow : public CSrmmLogWindow
+{
+protected:
+ CCtrlRichEdit &m_rtf;
+
+public:
+ CRtfLogWindow(CMsgDialog &pDlg);
+ ~CRtfLogWindow() override;
+
+ virtual INT_PTR WndProc(UINT msg, WPARAM wParam, LPARAM lParam);
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ void Attach() override;
+ void Detach() override;
+
+ bool AtBottom() override;
+ void Clear() override;
+ HWND GetHwnd() override;
+ wchar_t* GetSelection() override;
+ int GetType() override;
+ void Resize() override;
+ void ScrollToBottom() override;
+
+ INT_PTR Notify(WPARAM, LPARAM) override;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Basic SRMM window dialog
+
+#include <chat_resource.h>
+
+// message procedures' stubs
+EXTERN_C MIR_APP_DLL(LRESULT) CALLBACK stubLogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+EXTERN_C MIR_APP_DLL(LRESULT) CALLBACK stubMessageProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+EXTERN_C MIR_APP_DLL(LRESULT) CALLBACK stubNicklistProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+class MIR_APP_EXPORT CSrmmBaseDialog : public CDlgBase
+{
+ friend class CRtfLogWindow;
+
+ CSrmmBaseDialog(const CSrmmBaseDialog &) = delete;
+ CSrmmBaseDialog &operator=(const CSrmmBaseDialog &) = delete;
+
+protected:
+ CSrmmBaseDialog(CMPluginBase &pPlugin, int idDialog, struct SESSION_INFO *si = nullptr);
+
+ bool OnInitDialog() override;
+ void OnDestroy() override;
+
+ INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) override;
+
+ bool AllowTyping() const;
+ int NotifyEvent(int code);
+ #ifdef _WINDOWS
+ bool ProcessFileDrop(HDROP hDrop, MCONTACT hContact);
+ bool PasteFilesAsURL(HDROP hDrop);
+ #endif
+ bool ProcessHotkeys(int key, bool bShift, bool bCtrl, bool bAlt);
+ void RefreshButtonStatus(void);
+ void RunUserMenu(HWND hwndOwner, struct USERINFO *ui, const POINT &pt);
+
+protected:
+ CSrmmLogWindow *m_pLog = nullptr;
+ CCtrlRichEdit m_message;
+ SESSION_INFO *m_si;
+ COLORREF m_clrInputBG, m_clrInputFG;
+
+ // user typing support;
+ uint32_t m_nLastTyping = 0;
+ uint8_t m_bShowTyping = 0;
+ int m_nTypeSecs = 0, m_nTypeMode = 0;
+ const USERINFO* m_pUserTyping = nullptr;
+
+ CCtrlListBox m_nickList;
+ CCtrlButton m_btnColor, m_btnBkColor, m_btnOk;
+ CCtrlButton m_btnBold, m_btnItalic, m_btnUnderline;
+ CCtrlButton m_btnHistory, m_btnChannelMgr, m_btnNickList, m_btnFilter;
+
+ void onClick_BIU(CCtrlButton *);
+ void onClick_Color(CCtrlButton *);
+ void onClick_BkColor(CCtrlButton *);
+
+ void onClick_ChanMgr(CCtrlButton *);
+ void onClick_History(CCtrlButton *);
+
+ void onDblClick_List(CCtrlListBox *);
+
+public:
+ MCONTACT m_hContact;
+ int m_iLogFilterFlags;
+ bool m_bFilterEnabled, m_bNicklistEnabled;
+ bool m_bFGSet, m_bBGSet;
+ bool m_bInMenu;
+ COLORREF m_iFG, m_iBG;
+ CTimer timerFlash, timerType;
+
+ void ClearLog();
+ void RedrawLog();
+ void ShowColorChooser(int iCtrlId);
+
+ virtual void AddLog();
+ virtual void CloseTab() {}
+ virtual bool IsActive() const PURE;
+ virtual void LoadSettings() PURE;
+ virtual void SetStatusText(const wchar_t *, HICON) {}
+ virtual void ShowFilterMenu() {}
+ virtual void UpdateNickList() {}
+ virtual void UpdateOptions();
+ virtual void UpdateStatusBar() {}
+ virtual void UpdateTitle() PURE;
+
+ virtual LRESULT WndProc_Message(UINT msg, WPARAM wParam, LPARAM lParam);
+ virtual LRESULT WndProc_Nicklist(UINT msg, WPARAM wParam, LPARAM lParam);
+
+ __forceinline bool isChat() const { return m_si != nullptr; }
+ __forceinline SESSION_INFO *getChat() const { return m_si; }
+ __forceinline CSrmmLogWindow *log() const { return m_pLog; }
+
+ __forceinline void setTyping(int nSecs, const USERINFO* pUser = nullptr) {
+ m_pUserTyping = pUser;
+ m_nTypeSecs = nSecs;
+ }
+
+ __inline void* operator new(size_t size) { return calloc(1, size); }
+ __inline void operator delete(void *p) { free(p); }
+};
+
+#ifndef SRMM_OWN_STRUCTURES
+class CMsgDialog : public CSrmmBaseDialog {};
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// receives LOGSTREAMDATA* as the first parameter
+
+#ifdef _WINDOWS
+EXTERN_C MIR_APP_DLL(DWORD) CALLBACK Srmm_LogStreamCallback(DWORD_PTR dwCookie, uint8_t *pbBuff, LONG cb, LONG *pcb);
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// sends a message to all SRMM windows
+
+EXTERN_C MIR_APP_DLL(void) Srmm_Broadcast(UINT, WPARAM, LPARAM);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// creates plugin-specific hot key for sending messages
+
+EXTERN_C MIR_APP_DLL(void) Srmm_CreateHotkey(const char *pszSection, const char *pszDescription);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// finds a SRMM window using hContact
+
+EXTERN_C MIR_APP_DLL(HWND) Srmm_FindWindow(MCONTACT hContact);
+EXTERN_C MIR_APP_DLL(CMsgDialog*) Srmm_FindDialog(MCONTACT hContact);
+
+#endif // M_MESSAGE_H__
diff --git a/include/m_string.h b/include/m_string.h index 677385899a..8ddd07fb3d 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -1,1129 +1,1129 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#pragma once - -#ifndef M_STRING_H__ -#define M_STRING_H__ - -#include <stdio.h> -#include <string.h> - -#ifdef _MSC_VER - #include <mbstring.h> -#else - #include <ctype.h> -#endif // _WINDOWS -#include <wchar.h> - -#include <m_core.h> - -#ifdef __MINGW32__ -#include <limits.h> - -__inline size_t strnlen(const char *string, size_t maxlen) -{ - const char *end = (const char *)memchr ((const void *)string, '\0', maxlen); - return end ? (size_t) (end - string) : maxlen; -} -__inline size_t wcsnlen(const wchar_t *string, size_t maxlen) -{ - const wchar_t *end = wmemchr (string, L'\0', maxlen); - return end ? (size_t) (end - string) : maxlen; -} - -/* FIXME: This may be wrong assumption about Langpack_GetDefaultCodePage */ -#define Langpack_GetDefaultCodePage() CP_THREAD_ACP -/* FIXME: This is unsafe */ -#define memcpy_s(dest,size,src,count) memcpy(dest,src,count) -/* FIXME: This is quite silly implementation of _mbsstr */ -#define _mbsstr(str,search) strstr((const char *)str,(const char *)search) -#define __max(x,y) (((x)<(y))?(y):(x)) -#endif /* __MINGW32__ */ - -///////////////////////////////////////////////////////////////////////////////////////// - -struct CMStringData; - -MIR_CORE_DLL(CMStringData*) mirstr_allocate(int nChars, int nCharSize); -MIR_CORE_DLL(void) mirstr_free(CMStringData *pData); -MIR_CORE_DLL(CMStringData*) mirstr_realloc(CMStringData* pData, int nChars, int nCharSize); -MIR_CORE_DLL(CMStringData*) mirstr_getNil(); - -MIR_CORE_DLL(void) mirstr_lock(CMStringData* pThis); -MIR_CORE_DLL(void) mirstr_release(CMStringData* pThis); -MIR_CORE_DLL(void) mirstr_unlock(CMStringData* pThis); - -///////////////////////////////////////////////////////////////////////////////////////// - -enum CMStringDataFormat { FORMAT }; - -struct CMStringData -{ - int nDataLength; // Length of currently used data in XCHARs (not including terminating null) - int nAllocLength; // Length of allocated data in XCHARs (not including terminating null) - long nRefs; // Reference count: negative == locked - - __forceinline void* data() { return (this + 1); } - __forceinline void AddRef() { InterlockedIncrement(&nRefs); } - __forceinline bool IsLocked() const { return nRefs < 0; } - __forceinline bool IsShared() const { return nRefs > 1; } - - __forceinline void Lock() { mirstr_lock(this); } - __forceinline void Release() { mirstr_release(this); } - __forceinline void Unlock() { mirstr_unlock(this); } -}; - -template< typename BaseType = char > -class ChTraitsBase -{ -public: - typedef char XCHAR; - typedef LPSTR PXSTR; - typedef LPCSTR PCXSTR; - typedef wchar_t YCHAR; - typedef LPWSTR PYSTR; - typedef LPCWSTR PCYSTR; -}; - -template<> -class ChTraitsBase< wchar_t > -{ -public: - typedef wchar_t XCHAR; - typedef LPWSTR PXSTR; - typedef LPCWSTR PCXSTR; - typedef char YCHAR; - typedef LPSTR PYSTR; - typedef LPCSTR PCYSTR; -}; - -template< typename BaseType > -class CMSimpleStringT -{ -public: - typedef typename ChTraitsBase< BaseType >::XCHAR XCHAR; - typedef typename ChTraitsBase< BaseType >::PXSTR PXSTR; - typedef typename ChTraitsBase< BaseType >::PCXSTR PCXSTR; - typedef typename ChTraitsBase< BaseType >::YCHAR YCHAR; - typedef typename ChTraitsBase< BaseType >::PYSTR PYSTR; - typedef typename ChTraitsBase< BaseType >::PCYSTR PCYSTR; - -public: - explicit CMSimpleStringT(); - - CMSimpleStringT(const CMSimpleStringT& strSrc); - CMSimpleStringT(PCXSTR pszSrc); - CMSimpleStringT(const XCHAR* pchSrc, int nLength); - ~CMSimpleStringT(); - - CMSimpleStringT& operator=(const CMSimpleStringT& strSrc); - - __forceinline CMSimpleStringT& operator=(PCXSTR pszSrc) - { SetString(pszSrc); - return *this; - } - - __forceinline CMSimpleStringT& operator+=(const CMSimpleStringT& strSrc) - { Append(strSrc); - return *this; - } - - __forceinline CMSimpleStringT& operator+=(PCXSTR pszSrc) - { Append(pszSrc); - return *this; - } - - __forceinline CMSimpleStringT& operator+=(char ch) - { AppendChar(XCHAR(ch)); - return *this; - } - - __forceinline CMSimpleStringT& operator+=(unsigned char ch) - { AppendChar(XCHAR(ch)); - return *this; - } - - __forceinline CMSimpleStringT& operator+=(wchar_t ch) - { AppendChar(XCHAR(ch)); - return *this; - } - - __forceinline XCHAR operator[](int iChar) const - { return m_pszData[iChar]; - } - - __forceinline operator PCXSTR() const - { return m_pszData; - } - - __forceinline PCXSTR c_str() const - { return m_pszData; - } - - __forceinline int GetAllocLength() const - { return GetData()->nAllocLength; - } - - __forceinline XCHAR GetAt(int iChar) const - { return m_pszData[iChar]; - } - - __forceinline PXSTR GetBuffer(int nMinBufferLength) - { return PrepareWrite(nMinBufferLength); - } - - __forceinline int GetLength() const - { return GetData()->nDataLength; - } - - __forceinline PCXSTR GetString() const - { return m_pszData; - } - - __forceinline PCXSTR GetTail() const - { return m_pszData + GetData()->nDataLength; - } - - __forceinline bool IsEmpty() const - { return GetLength() == 0; - } - - __forceinline void Preallocate(int nLength) - { PrepareWrite(nLength); - } - - __forceinline void ReleaseBufferSetLength(int nNewLength) - { SetLength(nNewLength); - } - - void Append(PCXSTR pszSrc); - void Append(PCXSTR pszSrc, int nLength); - void AppendChar(XCHAR ch); - void Append(const CMSimpleStringT& strSrc); - - void Empty(); - void FreeExtra(); - - PXSTR GetBuffer(); - PXSTR GetBufferSetLength(int nLength); - - PXSTR LockBuffer(); - void UnlockBuffer(); - - void ReleaseBuffer(int nNewLength = -1); - - void Truncate(int nNewLength); - void SetAt(int iChar, XCHAR ch); - void SetString(PCXSTR pszSrc); - void SetString(PCXSTR pszSrc, int nLength); - -public: - template <typename Basetype> - friend CMSimpleStringT<BaseType> operator+(const CMSimpleStringT<BaseType> &str1, const CMSimpleStringT<BaseType> &str2); - - template <typename Basetype> - friend CMSimpleStringT<BaseType> operator+(const CMSimpleStringT<BaseType> &str1, PCXSTR psz2); - - template <typename Basetype> - friend CMSimpleStringT<BaseType> operator+(PCXSTR psz1, const CMSimpleStringT<BaseType> &str2); - - static void MIR_SYSCALL CopyChars(XCHAR* pchDest, const XCHAR* pchSrc, int nChars); - static void MIR_SYSCALL CopyChars(XCHAR* pchDest, size_t nDestLen, const XCHAR* pchSrc, int nChars); - static void MIR_SYSCALL CopyCharsOverlapped(XCHAR* pchDest, const XCHAR* pchSrc, int nChars); - static void MIR_SYSCALL CopyCharsOverlapped(XCHAR* pchDest, size_t nDestLen, const XCHAR* pchSrc, int nChars); - static int MIR_SYSCALL StringLength(const char* psz); - static int MIR_SYSCALL StringLength(const wchar_t* psz); - static int MIR_SYSCALL StringLengthN(const char* psz, size_t sizeInXChar); - static int MIR_SYSCALL StringLengthN(const wchar_t* psz, size_t sizeInXChar); - static void MIR_SYSCALL Concatenate(CMSimpleStringT& strResult, PCXSTR psz1, int nLength1, PCXSTR psz2, int nLength2); - - // Implementation -private: - __forceinline CMStringData* GetData() const - { return (reinterpret_cast<CMStringData *>(m_pszData)-1); - } - - void Attach(CMStringData* pData); - void Fork(int nLength); - PXSTR PrepareWrite(int nLength); - void PrepareWrite2(int nLength); - void Reallocate(int nLength); - void SetLength(int nLength); - static CMStringData* MIR_SYSCALL CloneData(CMStringData* pData); - -private: - PXSTR m_pszData; -}; - - -template< typename _CharType = char > -class ChTraitsCRT : public ChTraitsBase < _CharType > -{ -public: - static char* MIR_SYSCALL CharNext(const char *p) - { - #ifdef _MSC_VER - return reinterpret_cast<char*>(_mbsinc(reinterpret_cast<const unsigned char*>(p))); - #else - return reinterpret_cast<char*>(p+1); - #endif - } - - static int MIR_SYSCALL IsDigit(char ch) - { - #ifdef _MSC_VER - return _ismbcdigit(ch); - #else - return isdigit(ch); - #endif - } - - static int MIR_SYSCALL IsSpace(char ch) - { - #ifdef _MSC_VER - return _ismbcspace(ch); - #else - return isspace(ch); - #endif - } - - static int MIR_SYSCALL StringCompare(const char *pszA, const char *pszB) - { - #ifdef _MSC_VER - return _mbscmp(reinterpret_cast<const unsigned char*>(pszA), reinterpret_cast<const unsigned char*>(pszB)); - #else - return strcmp(pszA, pszB); - #endif - } - - static int MIR_SYSCALL StringCompareIgnore(const char *pszA, const char *pszB) - { - #ifdef _MSC_VER - return _mbsicmp(reinterpret_cast<const unsigned char*>(pszA), reinterpret_cast<const unsigned char*>(pszB)); - #else - return strcasecmp(pszA, pszB); - #endif - } - - static int MIR_SYSCALL StringCollate(const char *pszA, const char *pszB) - { - #ifdef _MSC_VER - return _mbscoll(reinterpret_cast<const unsigned char*>(pszA), reinterpret_cast<const unsigned char*>(pszB)); - #else - return strcoll(pszA, pszB); - #endif - } - - static int MIR_SYSCALL StringCollateIgnore(const char *pszA, const char *pszB) - { - #ifdef _MSC_VER - return _mbsicoll(reinterpret_cast<const unsigned char*>(pszA), reinterpret_cast<const unsigned char*>(pszB)); - #else - return strcoll(pszA, pszB); - #endif - } - - static const char* MIR_SYSCALL StringFindString(const char *pszBlock, const char *pszMatch) - { - #ifdef _MSC_VER - return reinterpret_cast<const char*>(_mbsstr(reinterpret_cast<const unsigned char*>(pszBlock), - reinterpret_cast<const unsigned char*>(pszMatch))); - #else - return strstr(pszBlock, pszMatch); - #endif - } - - static char* MIR_SYSCALL StringFindString(char *pszBlock, const char *pszMatch) - { - return const_cast<char*>(StringFindString(const_cast<const char*>(pszBlock), pszMatch)); - } - - static const char* MIR_SYSCALL StringFindChar(const char *pszBlock, char chMatch) - { - #ifdef _MSC_VER - return reinterpret_cast<const char*>(_mbschr(reinterpret_cast<const unsigned char*>(pszBlock), (unsigned char)chMatch)); - #else - return strchr(pszBlock, chMatch); - #endif - } - - static const char* MIR_SYSCALL StringFindCharRev(const char *psz, char ch) - { - #ifdef _MSC_VER - return reinterpret_cast<const char*>(_mbsrchr(reinterpret_cast<const unsigned char*>(psz), (unsigned char)ch)); - #else - return strrchr(psz, ch); - #endif - } - - static const char* MIR_SYSCALL StringScanSet(const char *pszBlock, const char *pszMatch) - { - #ifdef _MSC_VER - return reinterpret_cast<const char*>(_mbspbrk(reinterpret_cast<const unsigned char*>(pszBlock), - reinterpret_cast<const unsigned char*>(pszMatch))); - #else - return strpbrk(pszBlock, pszMatch); - #endif - } - - static int MIR_SYSCALL StringSpanIncluding(const char *pszBlock, const char *pszSet) - { - #ifdef _MSC_VER - return (int)_mbsspn(reinterpret_cast<const unsigned char*>(pszBlock), reinterpret_cast<const unsigned char*>(pszSet)); - #else - return (int)strspn(pszBlock, pszSet); - #endif - } - - static int MIR_SYSCALL StringSpanExcluding(const char *pszBlock, const char *pszSet) - { - #ifdef _MSC_VER - return (int)_mbscspn(reinterpret_cast<const unsigned char*>(pszBlock), reinterpret_cast<const unsigned char*>(pszSet)); - #else - return (int)strcspn(pszBlock, pszSet); - #endif - } - - static char* MIR_SYSCALL StringUppercase(char *psz) - { - #ifdef _MSC_VER - CharUpperBuffA(psz, (uint32_t)strlen(psz)); - #else - strupr(psz); - #endif - return psz; - } - - static char* MIR_SYSCALL StringLowercase(char *psz) - { - #ifdef _MSC_VER - CharLowerBuffA(psz, (uint32_t)strlen(psz)); - #else - strlwr(psz); - #endif - return psz; - } - - static char* MIR_SYSCALL StringUppercase(char *psz, size_t size) - { - #ifdef _MSC_VER - CharUpperBuffA(psz, (uint32_t)size); - #else - - #endif - return psz; - } - - static char* MIR_SYSCALL StringLowercase(char *psz, size_t size) - { - #ifdef _MSC_VER - CharLowerBuffA(psz, (uint32_t)size); - #endif - return psz; - } - - static char* MIR_SYSCALL StringReverse(char *psz) - { - #ifdef _MSC_VER - return reinterpret_cast<LPSTR>(_mbsrev(reinterpret_cast<unsigned char*>(psz))); - #else - return strrev(psz); - #endif - } - - static int MIR_SYSCALL GetFormattedLength(_Printf_format_string_ const char *pszFormat, va_list args) - { - #ifdef _MSC_VER - return _vscprintf(pszFormat, args); - #else - return 0; // !!!!!!!!!! - #endif - } - - static int MIR_SYSCALL Format(char *pszBuffer, size_t nlength, _Printf_format_string_ const char *pszFormat, va_list args) - { - #ifdef _MSC_VER - return vsprintf_s(pszBuffer, nlength, pszFormat, args); - #else - return 0; // !!!!!!!!!! - #endif - } - - static int MIR_SYSCALL GetBaseTypeLength(const char *pszSrc) - { - // Returns required buffer length in XCHARs - return int(strlen(pszSrc)); - } - - static int MIR_SYSCALL GetBaseTypeLength(const char *pszSrc, int nLength) - { - (void)pszSrc; - // Returns required buffer length in XCHARs - return nLength; - } - - static int MIR_SYSCALL GetBaseTypeLength(const wchar_t *pszSource) - { - // Returns required buffer length in XCHARs - #ifdef _MSC_VER - return ::WideCharToMultiByte(Langpack_GetDefaultCodePage(), 0, pszSource, -1, NULL, 0, NULL, NULL) - 1; - #else - return 0; - #endif - } - - static int MIR_SYSCALL GetBaseTypeLength(const wchar_t *pszSource, int nLength) - { - // Returns required buffer length in XCHARs - #ifdef _MSC_VER - return ::WideCharToMultiByte(Langpack_GetDefaultCodePage(), 0, pszSource, nLength, NULL, 0, NULL, NULL); - #else - return 0; - #endif - } - - static void MIR_SYSCALL ConvertToBaseType(char*pszDest, int nDestLength, const char *pszSrc, int nSrcLength = -1) - { - if (nSrcLength == -1) { nSrcLength = 1 + GetBaseTypeLength(pszSrc); } - // nLen is in XCHARs - memcpy_s(pszDest, nDestLength*sizeof(char), pszSrc, nSrcLength*sizeof(char)); - } - - static void MIR_SYSCALL ConvertToBaseType(char*pszDest, int nDestLength, const wchar_t *pszSrc, int nSrcLength = -1) - { - // nLen is in XCHARs - #ifdef _MSC_VER - ::WideCharToMultiByte(Langpack_GetDefaultCodePage(), 0, pszSrc, nSrcLength, pszDest, nDestLength, NULL, NULL); - #endif - } - - static void ConvertToOem(_CharType* pstrString) - { - #ifdef _MSC_VER - bool fSuccess = ::CharToOemA(pstrString, pstrString); - #endif // _MSC_VER - } - - static void ConvertToAnsi(_CharType* pstrString) - { - #ifdef _MSC_VER - bool fSuccess = ::OemToCharA(pstrString, pstrString); - #endif - } - - static void ConvertToOem(_CharType* pstrString, size_t size) - { - #ifdef _MSC_VER - uint32_t dwSize = static_cast<uint32_t>(size); - ::CharToOemBuffA(pstrString, pstrString, dwSize); - #endif - } - - static void ConvertToAnsi(_CharType* pstrString, size_t size) - { - #ifdef _MSC_VER - uint32_t dwSize = static_cast<uint32_t>(size); - ::OemToCharBuffA(pstrString, pstrString, dwSize); - #endif - } - - static void MIR_SYSCALL FloodCharacters(char ch, int nLength, char* pch) - { - // nLength is in XCHARs - memset(pch, ch, nLength); - } - - static int MIR_SYSCALL SafeStringLen(const char *psz) - { - // returns length in bytes - return (psz != NULL) ? int(strlen(psz)) : 0; - } - - static int MIR_SYSCALL SafeStringLen(const wchar_t *psz) - { - // returns length in wchar_ts - return (psz != NULL) ? int(wcslen(psz)) : 0; - } - - static int MIR_SYSCALL GetCharLen(const wchar_t *pch) - { - // returns char length - return 1; - } - - static int MIR_SYSCALL GetCharLen(const char *pch) - { - // returns char length - #ifdef _MSC_VER - return int(_mbclen(reinterpret_cast<const unsigned char*>(pch))); - #else - return mblen(pch, strlen(pch)); - #endif - } - - static uint32_t MIR_SYSCALL GetEnvironmentVariable(const char *pszVar, char*pszBuffer, uint32_t dwSize) - { - #ifdef _MSC_VER - return ::GetEnvironmentVariableA(pszVar, pszBuffer, dwSize); - #else - return 0; // !!!!!!!!!! - #endif - } - - static char* MirCopy(const char *pstrString, size_t size) - { - return mir_strndup(pstrString, size); - } -}; - -// specialization for wchar_t -template<> -class ChTraitsCRT< wchar_t > : public ChTraitsBase< wchar_t > -{ - static uint32_t MIR_SYSCALL _GetEnvironmentVariableW(const wchar_t *pszName, wchar_t *pszBuffer, uint32_t nSize) - { - #ifdef _MSC_VER - return ::GetEnvironmentVariableW(pszName, pszBuffer, nSize); - #else - return 0; // !!!!!!!!!! - #endif - } - -public: - static wchar_t* MIR_SYSCALL CharNext(const wchar_t *psz) - { - return const_cast<wchar_t*>(psz+1); - } - - static int MIR_SYSCALL IsDigit(wchar_t ch) - { - #ifdef _MSC_VER - return iswdigit(static_cast<unsigned short>(ch)); - #else - return 0; - #endif - } - - static int MIR_SYSCALL IsSpace(wchar_t ch) - { - #ifdef _MSC_VER - return iswspace(static_cast<unsigned short>(ch)); - #else - return 0; - #endif - } - - static int MIR_SYSCALL StringCompare(const wchar_t *pszA, const wchar_t *pszB) - { - return wcscmp(pszA, pszB); - } - - static int MIR_SYSCALL StringCompareIgnore(const wchar_t *pszA, const wchar_t *pszB) - { - #ifdef _MSC_VER - return _wcsicmp(pszA, pszB); - #else - return 0; - #endif - } - - static int MIR_SYSCALL StringCollate(const wchar_t *pszA, const wchar_t *pszB) - { - return wcscoll(pszA, pszB); - } - - static int MIR_SYSCALL StringCollateIgnore(const wchar_t *pszA, const wchar_t *pszB) - { - #ifdef _MSC_VER - return _wcsicoll(pszA, pszB); - #else - return 0; - #endif - } - - static const wchar_t* MIR_SYSCALL StringFindString(const wchar_t *pszBlock, const wchar_t *pszMatch) - { - return wcsstr(pszBlock, pszMatch); - } - - static wchar_t* MIR_SYSCALL StringFindString(wchar_t *pszBlock, const wchar_t *pszMatch) - { - return const_cast<wchar_t*>(wcsstr(pszBlock, pszMatch)); - } - - static const wchar_t* MIR_SYSCALL StringFindChar(const wchar_t *pszBlock, wchar_t chMatch) - { - return wcschr(pszBlock, chMatch); - } - - static const wchar_t* MIR_SYSCALL StringFindCharRev(const wchar_t *psz, wchar_t ch) - { - return wcsrchr(psz, ch); - } - - static const wchar_t* MIR_SYSCALL StringScanSet(const wchar_t *pszBlock, const wchar_t *pszMatch) - { - return wcspbrk(pszBlock, pszMatch); - } - - static int MIR_SYSCALL StringSpanIncluding(const wchar_t *pszBlock, const wchar_t *pszSet) - { - return (int)wcsspn(pszBlock, pszSet); - } - - static int MIR_SYSCALL StringSpanExcluding(const wchar_t *pszBlock, const wchar_t *pszSet) - { - return (int)wcscspn(pszBlock, pszSet); - } - - static wchar_t* MIR_SYSCALL StringUppercase(wchar_t *psz) - { - #ifdef _MSC_VER - CharUpperBuffW(psz, (uint32_t)wcslen(psz)); - #endif - return psz; - } - - static wchar_t* MIR_SYSCALL StringLowercase(wchar_t *psz) - { - #ifdef _MSC_VER - CharLowerBuffW(psz, (uint32_t)wcslen(psz)); - #endif - return psz; - } - - static wchar_t* MIR_SYSCALL StringUppercase(wchar_t *psz, size_t len) - { - #ifdef _MSC_VER - CharUpperBuffW(psz, (uint32_t)len); - #endif - return psz; - } - - static wchar_t* MIR_SYSCALL StringLowercase(wchar_t *psz, size_t len) - { - #ifdef _MSC_VER - CharLowerBuffW(psz, (uint32_t)len); - #endif - return psz; - } - - static wchar_t* MIR_SYSCALL StringReverse(wchar_t *psz) - { - #ifdef _MSC_VER - return _wcsrev(psz); - #else - return psz; - #endif - } - - static int MIR_SYSCALL GetFormattedLength(_Printf_format_string_ const wchar_t *pszFormat, va_list args) - { - #ifdef _MSC_VER - return _vscwprintf(pszFormat, args); - #else - return 0; - #endif - } - - static int MIR_SYSCALL Format(wchar_t *pszBuffer, _Printf_format_string_ const wchar_t *pszFormat, va_list args) - { - #pragma warning(push) - #pragma warning(disable : 4996) - - #ifdef _MSC_VER - return vswprintf(pszBuffer, pszFormat, args); - #else - return 0; - #endif - #pragma warning(pop) - } - - static int MIR_SYSCALL Format(wchar_t *pszBuffer, size_t nLength, _Printf_format_string_ const wchar_t *pszFormat, va_list args) - { - #pragma warning(push) - #pragma warning(disable : 4996) - - #ifdef _MSC_VER - return _vsnwprintf(pszBuffer, nLength, pszFormat, args); - #else - return 0; - #endif - - #pragma warning(pop) - } - - static int MIR_SYSCALL GetBaseTypeLength(const char *pszSrc) - { - // Returns required buffer size in wchar_ts - #ifdef _MSC_VER - return ::MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, nullptr, 0)-1; - #else - return 0; - #endif - } - - static int MIR_SYSCALL GetBaseTypeLength(const char *pszSrc, int nLength) - { - // Returns required buffer size in wchar_ts - #ifdef _MSC_VER - return ::MultiByteToWideChar(CP_ACP, 0, pszSrc, nLength, nullptr, 0); - #else - return 0; - #endif - } - - static int MIR_SYSCALL GetBaseTypeLength(const wchar_t *pszSrc) - { - // Returns required buffer size in wchar_ts - return (int)wcslen(pszSrc); - } - - static int MIR_SYSCALL GetBaseTypeLength(const wchar_t *pszSrc, int nLength) - { - (void)pszSrc; - // Returns required buffer size in wchar_ts - return nLength; - } - - static void MIR_SYSCALL ConvertToBaseType(wchar_t *pszDest, int nDestLength, const char *pszSrc, int nSrcLength = -1) - { - // nLen is in wchar_ts - #ifdef _MSC_VER - ::MultiByteToWideChar(CP_ACP, 0, pszSrc, nSrcLength, pszDest, nDestLength); - #endif - } - - static void MIR_SYSCALL ConvertToBaseType(wchar_t *pszDest, int nDestLength, const wchar_t *pszSrc, int nSrcLength = -1) - { - if (nSrcLength == -1) { nSrcLength=1 + GetBaseTypeLength(pszSrc); } - // nLen is in wchar_ts - #if _MSC_VER >= 1400 - wmemcpy_s(pszDest, nDestLength, pszSrc, nSrcLength); - #else - wmemcpy(pszDest, pszSrc, nDestLength); - #endif - } - - static void MIR_SYSCALL FloodCharacters(wchar_t ch, int nLength, wchar_t *psz) - { - // nLength is in XCHARs - for (int i = 0; i < nLength; i++) - { - psz[i] = ch; - } - } - - static int MIR_SYSCALL SafeStringLen(const char *psz) - { - // returns length in bytes - return (psz != nullptr) ? (int)strlen(psz) : 0; - } - - static int MIR_SYSCALL SafeStringLen(const wchar_t *psz) - { - // returns length in wchar_ts - return (psz != nullptr) ? (int)wcslen(psz) : 0; - } - - static int MIR_SYSCALL GetCharLen(const wchar_t* pch) - { - (void)pch; - // returns char length - return 1; - } - - static int MIR_SYSCALL GetCharLen(const char* pch) - { - // returns char length - #ifdef _MSC_VER - return (int)(_mbclen(reinterpret_cast< const unsigned char* >(pch))); - #else - return mblen(pch, strlen(pch)); - #endif - } - - static uint32_t MIR_SYSCALL GetEnvironmentVariable(const wchar_t *pszVar, wchar_t *pszBuffer, uint32_t dwSize) - { - return _GetEnvironmentVariableW(pszVar, pszBuffer, dwSize); - } - - static void MIR_SYSCALL ConvertToOem(wchar_t* /*psz*/) - { - } - - static void MIR_SYSCALL ConvertToAnsi(wchar_t* /*psz*/) - { - } - - static void MIR_SYSCALL ConvertToOem(wchar_t* /*psz*/, size_t) - { - } - - static void MIR_SYSCALL ConvertToAnsi(wchar_t* /*psz*/, size_t) - { - } - - static wchar_t* MirCopy(const wchar_t *pstrString, size_t size) - { - return mir_wstrndup(pstrString, size); - } -}; - -template< typename BaseType, class StringTraits > -class MIR_CORE_EXPORT CMStringT : public CMSimpleStringT< BaseType > -{ -public: - typedef CMSimpleStringT< BaseType> CThisSimpleString; - typedef typename CThisSimpleString::XCHAR XCHAR; - typedef typename CThisSimpleString::PXSTR PXSTR; - typedef typename CThisSimpleString::PCXSTR PCXSTR; - typedef typename CThisSimpleString::YCHAR YCHAR; - typedef typename CThisSimpleString::PYSTR PYSTR; - typedef typename CThisSimpleString::PCYSTR PCYSTR; - -public: - CMStringT(); - - // Copy constructor - CMStringT(const CMStringT& strSrc); - - CMStringT(const XCHAR* pszSrc); - CMStringT(CMStringDataFormat, _Printf_format_string_ const XCHAR* pszFormat, ...); - - CMStringT(const YCHAR* pszSrc); - CMStringT(const unsigned char* pszSrc); - - CMStringT(char ch, int nLength = 1); - CMStringT(wchar_t ch, int nLength = 1); - - CMStringT(const XCHAR* pch, int nLength); - CMStringT(const YCHAR* pch, int nLength); - - // Destructor - ~CMStringT(); - - // Assignment operators - CMStringT& operator=(const CMStringT& strSrc); - CMStringT& operator=(PCXSTR pszSrc); - CMStringT& operator=(PCYSTR pszSrc); - CMStringT& operator=(const unsigned char* pszSrc); - CMStringT& operator=(char ch); - CMStringT& operator=(wchar_t ch); - - CMStringT& operator+=(const CMStringT& str); - CMStringT& operator+=(const CThisSimpleString& str); - CMStringT& operator+=(PCXSTR pszSrc); - CMStringT& operator+=(PCYSTR pszSrc); - CMStringT& operator+=(char ch); - CMStringT& operator+=(unsigned char ch); - CMStringT& operator+=(wchar_t ch); - - // Comparison - - int Compare(PCXSTR psz) const; - int CompareNoCase(PCXSTR psz) const; - int Collate(PCXSTR psz) const; - int CollateNoCase(PCXSTR psz) const; - - // Advanced manipulation - - // Delete 'nCount' characters, starting at index 'iIndex' - int Delete(int iIndex, int nCount = 1); - - // Insert character 'ch' before index 'iIndex' - int Insert(int iIndex, XCHAR ch); - - // Insert string 'psz' before index 'iIndex' - int Insert(int iIndex, PCXSTR psz); - - // Replace all occurrences of character 'chOld' with character 'chNew' - int Replace(XCHAR chOld, XCHAR chNew); - - // Replace all occurrences of string 'pszOld' with string 'pszNew' - int Replace(PCXSTR pszOld, PCXSTR pszNew); - - // Remove all occurrences of character 'chRemove' - int Remove(XCHAR chRemove); - - CMStringT Tokenize(PCXSTR pszTokens, int& iStart) const; - - // find routines - - // Find the first occurrence of character 'ch', starting at index 'iStart' - int Find(XCHAR ch, int iStart = 0) const; - - // look for a specific sub-string - - // Find the first occurrence of string 'pszSub', starting at index 'iStart' - int Find(PCXSTR pszSub, int iStart = 0) const; - - // Find the first occurrence of any of the characters in string 'pszCharSet' - int FindOneOf(PCXSTR pszCharSet) const; - - // Find the last occurrence of character 'ch' - int ReverseFind(XCHAR ch) const; - - // manipulation - - // Convert the string to uppercase - CMStringT& MakeUpper(); - - // Convert the string to lowercase - CMStringT& MakeLower(); - - // Reverse the string - CMStringT& MakeReverse(); - - // trimming - - // Remove all trailing whitespace - CMStringT& TrimRight(); - - // Remove all leading whitespace - CMStringT& TrimLeft(); - - // Remove all leading and trailing whitespace - CMStringT& Trim(); - - // Remove all leading and trailing occurrences of character 'chTarget' - CMStringT& Trim(XCHAR chTarget); - - // Remove all leading and trailing occurrences of any of the characters in the string 'pszTargets' - CMStringT& Trim(PCXSTR pszTargets); - - // trimming anything (either side) - - // Remove all trailing occurrences of character 'chTarget' - CMStringT& TrimRight(XCHAR chTarget); - - // Remove all trailing occurrences of any of the characters in string 'pszTargets' - CMStringT& TrimRight(PCXSTR pszTargets); - - // Remove all leading occurrences of character 'chTarget' - CMStringT& TrimLeft(XCHAR chTarget); - - // Remove all leading occurrences of any of the characters in string 'pszTargets' - CMStringT& TrimLeft(PCXSTR pszTargets); - - // Convert the string to the OEM character set - void AnsiToOem(); - - // Convert the string to the ANSI character set - void OemToAnsi(); - - // Very simple sub-string extraction - - // Return the substring starting at index 'iFirst' - CMStringT Mid(int iFirst) const; - - // Return the substring starting at index 'iFirst', with length 'nCount' - CMStringT Mid(int iFirst, int nCount) const; - - // Return the substring consisting of the rightmost 'nCount' characters - CMStringT Right(int nCount) const; - - // Return the substring consisting of the leftmost 'nCount' characters - CMStringT Left(int nCount) const; - - // Return the substring consisting of the leftmost characters in the set 'pszCharSet' - CMStringT SpanIncluding(PCXSTR pszCharSet) const; - - // Return the substring consisting of the leftmost characters not in the set 'pszCharSet' - CMStringT SpanExcluding(PCXSTR pszCharSet) const; - - // Format data using format string 'pszFormat' - PCXSTR Format(PCXSTR _Printf_format_string_ pszFormat, ...); - PCXSTR FormatV(PCXSTR _Printf_format_string_ pszFormat, va_list args); - - // Append formatted data using format string 'pszFormat' - PCXSTR AppendFormat(PCXSTR _Printf_format_string_ pszFormat, ...); - void AppendFormatV(PCXSTR _Printf_format_string_ pszFormat, va_list args); - - // return a copy of string to be freed by mir_free() - PXSTR Detach() const; - - // Set the string to the value of environment variable 'pszVar' - BOOL GetEnvironmentVariable(PCXSTR pszVar); - - friend bool __forceinline operator==(const CMStringT& str1, const CMStringT& str2) { return str1.Compare(str2) == 0; } - friend bool __forceinline operator==(const CMStringT& str1, PCXSTR psz2) { return str1.Compare(psz2) == 0; } - friend bool __forceinline operator==(PCXSTR psz1, const CMStringT& str2) { return str2.Compare(psz1) == 0; } - friend bool __forceinline operator==(const CMStringT& str1, PCYSTR psz2) { return str1 == CMStringT(psz2); } - friend bool __forceinline operator==(PCYSTR psz1, const CMStringT& str2) { return CMStringT(psz1) == str2; } - - friend bool __forceinline operator!=(const CMStringT& str1, const CMStringT& str2) { return str1.Compare(str2) != 0; } - friend bool __forceinline operator!=(const CMStringT& str1, PCXSTR psz2) { return str1.Compare(psz2) != 0; } - friend bool __forceinline operator!=(PCXSTR psz1, const CMStringT& str2) { return str2.Compare(psz1) != 0; } - friend bool __forceinline operator!=(const CMStringT& str1, PCYSTR psz2) { return str1 != CMStringT(psz2); } - friend bool __forceinline operator!=(PCYSTR psz1, const CMStringT& str2) { return CMStringT(psz1) != str2; } - - friend bool __forceinline operator<(const CMStringT& str1, const CMStringT& str2) { return str1.Compare(str2) < 0; } - friend bool __forceinline operator<(const CMStringT& str1, PCXSTR psz2) { return str1.Compare(psz2) < 0; } - friend bool __forceinline operator<(PCXSTR psz1, const CMStringT& str2) { return str2.Compare(psz1) > 0; } - - friend bool __forceinline operator>(const CMStringT& str1, const CMStringT& str2) { return str1.Compare(str2) > 0; } - friend bool __forceinline operator>(const CMStringT& str1, PCXSTR psz2) { return str1.Compare(psz2) > 0; } - friend bool __forceinline operator>(PCXSTR psz1, const CMStringT& str2) { return str2.Compare(psz1) < 0; } - - friend bool __forceinline operator<=(const CMStringT& str1, const CMStringT& str2) { return str1.Compare(str2) <= 0; } - friend bool __forceinline operator<=(const CMStringT& str1, PCXSTR psz2) { return str1.Compare(psz2) <= 0; } - friend bool __forceinline operator<=(PCXSTR psz1, const CMStringT& str2) { return str2.Compare(psz1) >= 0; } - - friend bool __forceinline operator>=(const CMStringT& str1, const CMStringT& str2) { return str1.Compare(str2) >= 0; } - friend bool __forceinline operator>=(const CMStringT& str1, PCXSTR psz2) { return str1.Compare(psz2) >= 0; } - friend bool __forceinline operator>=(PCXSTR psz1, const CMStringT& str2) { return str2.Compare(psz1) <= 0; } - - friend bool __forceinline operator==(XCHAR ch1, const CMStringT& str2) { return (str2.GetLength() == 1) && (str2[0] == ch1); } - friend bool __forceinline operator==(const CMStringT& str1, XCHAR ch2) { return (str1.GetLength() == 1) && (str1[0] == ch2); } - - friend bool __forceinline operator!=(XCHAR ch1, const CMStringT& str2) { return (str2.GetLength() != 1) || (str2[0] != ch1); } - friend bool __forceinline operator!=(const CMStringT& str1, XCHAR ch2) { return (str1.GetLength() != 1) || (str1[0] != ch2); } -}; - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, const CMStringT<BaseType, StringTraits>& str2); - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, typename CMStringT<BaseType, StringTraits>::PCXSTR psz2); - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(typename CMStringT<BaseType, StringTraits>::PCXSTR psz1, const CMStringT<BaseType, StringTraits>& str2); - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, wchar_t ch2); - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, char ch2); - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator + (wchar_t ch1, const CMStringT<BaseType, StringTraits>& str2); - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(char ch1, const CMStringT<BaseType, StringTraits>& str2); - -typedef CMStringT< wchar_t, ChTraitsCRT< wchar_t > > CMStringW; -typedef CMStringT< char, ChTraitsCRT< char > > CMStringA; - -#endif // M_STRING_H__ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#pragma once
+
+#ifndef M_STRING_H__
+#define M_STRING_H__
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _MSC_VER
+ #include <mbstring.h>
+#else
+ #include <ctype.h>
+#endif // _WINDOWS
+#include <wchar.h>
+
+#include <m_core.h>
+
+#ifdef __MINGW32__
+#include <limits.h>
+
+__inline size_t strnlen(const char *string, size_t maxlen)
+{
+ const char *end = (const char *)memchr ((const void *)string, '\0', maxlen);
+ return end ? (size_t) (end - string) : maxlen;
+}
+__inline size_t wcsnlen(const wchar_t *string, size_t maxlen)
+{
+ const wchar_t *end = wmemchr (string, L'\0', maxlen);
+ return end ? (size_t) (end - string) : maxlen;
+}
+
+/* FIXME: This may be wrong assumption about Langpack_GetDefaultCodePage */
+#define Langpack_GetDefaultCodePage() CP_THREAD_ACP
+/* FIXME: This is unsafe */
+#define memcpy_s(dest,size,src,count) memcpy(dest,src,count)
+/* FIXME: This is quite silly implementation of _mbsstr */
+#define _mbsstr(str,search) strstr((const char *)str,(const char *)search)
+#define __max(x,y) (((x)<(y))?(y):(x))
+#endif /* __MINGW32__ */
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+struct CMStringData;
+
+MIR_CORE_DLL(CMStringData*) mirstr_allocate(int nChars, int nCharSize);
+MIR_CORE_DLL(void) mirstr_free(CMStringData *pData);
+MIR_CORE_DLL(CMStringData*) mirstr_realloc(CMStringData* pData, int nChars, int nCharSize);
+MIR_CORE_DLL(CMStringData*) mirstr_getNil();
+
+MIR_CORE_DLL(void) mirstr_lock(CMStringData* pThis);
+MIR_CORE_DLL(void) mirstr_release(CMStringData* pThis);
+MIR_CORE_DLL(void) mirstr_unlock(CMStringData* pThis);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+enum CMStringDataFormat { FORMAT };
+
+struct CMStringData
+{
+ int nDataLength; // Length of currently used data in XCHARs (not including terminating null)
+ int nAllocLength; // Length of allocated data in XCHARs (not including terminating null)
+ long nRefs; // Reference count: negative == locked
+
+ __forceinline void* data() { return (this + 1); }
+ __forceinline void AddRef() { InterlockedIncrement(&nRefs); }
+ __forceinline bool IsLocked() const { return nRefs < 0; }
+ __forceinline bool IsShared() const { return nRefs > 1; }
+
+ __forceinline void Lock() { mirstr_lock(this); }
+ __forceinline void Release() { mirstr_release(this); }
+ __forceinline void Unlock() { mirstr_unlock(this); }
+};
+
+template< typename BaseType = char >
+class ChTraitsBase
+{
+public:
+ typedef char XCHAR;
+ typedef LPSTR PXSTR;
+ typedef LPCSTR PCXSTR;
+ typedef wchar_t YCHAR;
+ typedef LPWSTR PYSTR;
+ typedef LPCWSTR PCYSTR;
+};
+
+template<>
+class ChTraitsBase< wchar_t >
+{
+public:
+ typedef wchar_t XCHAR;
+ typedef LPWSTR PXSTR;
+ typedef LPCWSTR PCXSTR;
+ typedef char YCHAR;
+ typedef LPSTR PYSTR;
+ typedef LPCSTR PCYSTR;
+};
+
+template< typename BaseType >
+class CMSimpleStringT
+{
+public:
+ typedef typename ChTraitsBase< BaseType >::XCHAR XCHAR;
+ typedef typename ChTraitsBase< BaseType >::PXSTR PXSTR;
+ typedef typename ChTraitsBase< BaseType >::PCXSTR PCXSTR;
+ typedef typename ChTraitsBase< BaseType >::YCHAR YCHAR;
+ typedef typename ChTraitsBase< BaseType >::PYSTR PYSTR;
+ typedef typename ChTraitsBase< BaseType >::PCYSTR PCYSTR;
+
+public:
+ explicit CMSimpleStringT();
+
+ CMSimpleStringT(const CMSimpleStringT& strSrc);
+ CMSimpleStringT(PCXSTR pszSrc);
+ CMSimpleStringT(const XCHAR* pchSrc, int nLength);
+ ~CMSimpleStringT();
+
+ CMSimpleStringT& operator=(const CMSimpleStringT& strSrc);
+
+ __forceinline CMSimpleStringT& operator=(PCXSTR pszSrc)
+ { SetString(pszSrc);
+ return *this;
+ }
+
+ __forceinline CMSimpleStringT& operator+=(const CMSimpleStringT& strSrc)
+ { Append(strSrc);
+ return *this;
+ }
+
+ __forceinline CMSimpleStringT& operator+=(PCXSTR pszSrc)
+ { Append(pszSrc);
+ return *this;
+ }
+
+ __forceinline CMSimpleStringT& operator+=(char ch)
+ { AppendChar(XCHAR(ch));
+ return *this;
+ }
+
+ __forceinline CMSimpleStringT& operator+=(unsigned char ch)
+ { AppendChar(XCHAR(ch));
+ return *this;
+ }
+
+ __forceinline CMSimpleStringT& operator+=(wchar_t ch)
+ { AppendChar(XCHAR(ch));
+ return *this;
+ }
+
+ __forceinline XCHAR operator[](int iChar) const
+ { return m_pszData[iChar];
+ }
+
+ __forceinline operator PCXSTR() const
+ { return m_pszData;
+ }
+
+ __forceinline PCXSTR c_str() const
+ { return m_pszData;
+ }
+
+ __forceinline int GetAllocLength() const
+ { return GetData()->nAllocLength;
+ }
+
+ __forceinline XCHAR GetAt(int iChar) const
+ { return m_pszData[iChar];
+ }
+
+ __forceinline PXSTR GetBuffer(int nMinBufferLength)
+ { return PrepareWrite(nMinBufferLength);
+ }
+
+ __forceinline int GetLength() const
+ { return GetData()->nDataLength;
+ }
+
+ __forceinline PCXSTR GetString() const
+ { return m_pszData;
+ }
+
+ __forceinline PCXSTR GetTail() const
+ { return m_pszData + GetData()->nDataLength;
+ }
+
+ __forceinline bool IsEmpty() const
+ { return GetLength() == 0;
+ }
+
+ __forceinline void Preallocate(int nLength)
+ { PrepareWrite(nLength);
+ }
+
+ __forceinline void ReleaseBufferSetLength(int nNewLength)
+ { SetLength(nNewLength);
+ }
+
+ void Append(PCXSTR pszSrc);
+ void Append(PCXSTR pszSrc, int nLength);
+ void AppendChar(XCHAR ch);
+ void Append(const CMSimpleStringT& strSrc);
+
+ void Empty();
+ void FreeExtra();
+
+ PXSTR GetBuffer();
+ PXSTR GetBufferSetLength(int nLength);
+
+ PXSTR LockBuffer();
+ void UnlockBuffer();
+
+ void ReleaseBuffer(int nNewLength = -1);
+
+ void Truncate(int nNewLength);
+ void SetAt(int iChar, XCHAR ch);
+ void SetString(PCXSTR pszSrc);
+ void SetString(PCXSTR pszSrc, int nLength);
+
+public:
+ template <typename Basetype>
+ friend CMSimpleStringT<BaseType> operator+(const CMSimpleStringT<BaseType> &str1, const CMSimpleStringT<BaseType> &str2);
+
+ template <typename Basetype>
+ friend CMSimpleStringT<BaseType> operator+(const CMSimpleStringT<BaseType> &str1, PCXSTR psz2);
+
+ template <typename Basetype>
+ friend CMSimpleStringT<BaseType> operator+(PCXSTR psz1, const CMSimpleStringT<BaseType> &str2);
+
+ static void MIR_SYSCALL CopyChars(XCHAR* pchDest, const XCHAR* pchSrc, int nChars);
+ static void MIR_SYSCALL CopyChars(XCHAR* pchDest, size_t nDestLen, const XCHAR* pchSrc, int nChars);
+ static void MIR_SYSCALL CopyCharsOverlapped(XCHAR* pchDest, const XCHAR* pchSrc, int nChars);
+ static void MIR_SYSCALL CopyCharsOverlapped(XCHAR* pchDest, size_t nDestLen, const XCHAR* pchSrc, int nChars);
+ static int MIR_SYSCALL StringLength(const char* psz);
+ static int MIR_SYSCALL StringLength(const wchar_t* psz);
+ static int MIR_SYSCALL StringLengthN(const char* psz, size_t sizeInXChar);
+ static int MIR_SYSCALL StringLengthN(const wchar_t* psz, size_t sizeInXChar);
+ static void MIR_SYSCALL Concatenate(CMSimpleStringT& strResult, PCXSTR psz1, int nLength1, PCXSTR psz2, int nLength2);
+
+ // Implementation
+private:
+ __forceinline CMStringData* GetData() const
+ { return (reinterpret_cast<CMStringData *>(m_pszData)-1);
+ }
+
+ void Attach(CMStringData* pData);
+ void Fork(int nLength);
+ PXSTR PrepareWrite(int nLength);
+ void PrepareWrite2(int nLength);
+ void Reallocate(int nLength);
+ void SetLength(int nLength);
+ static CMStringData* MIR_SYSCALL CloneData(CMStringData* pData);
+
+private:
+ PXSTR m_pszData;
+};
+
+
+template< typename _CharType = char >
+class ChTraitsCRT : public ChTraitsBase < _CharType >
+{
+public:
+ static char* MIR_SYSCALL CharNext(const char *p)
+ {
+ #ifdef _MSC_VER
+ return reinterpret_cast<char*>(_mbsinc(reinterpret_cast<const unsigned char*>(p)));
+ #else
+ return reinterpret_cast<char*>(p+1);
+ #endif
+ }
+
+ static int MIR_SYSCALL IsDigit(char ch)
+ {
+ #ifdef _MSC_VER
+ return _ismbcdigit(ch);
+ #else
+ return isdigit(ch);
+ #endif
+ }
+
+ static int MIR_SYSCALL IsSpace(char ch)
+ {
+ #ifdef _MSC_VER
+ return _ismbcspace(ch);
+ #else
+ return isspace(ch);
+ #endif
+ }
+
+ static int MIR_SYSCALL StringCompare(const char *pszA, const char *pszB)
+ {
+ #ifdef _MSC_VER
+ return _mbscmp(reinterpret_cast<const unsigned char*>(pszA), reinterpret_cast<const unsigned char*>(pszB));
+ #else
+ return strcmp(pszA, pszB);
+ #endif
+ }
+
+ static int MIR_SYSCALL StringCompareIgnore(const char *pszA, const char *pszB)
+ {
+ #ifdef _MSC_VER
+ return _mbsicmp(reinterpret_cast<const unsigned char*>(pszA), reinterpret_cast<const unsigned char*>(pszB));
+ #else
+ return strcasecmp(pszA, pszB);
+ #endif
+ }
+
+ static int MIR_SYSCALL StringCollate(const char *pszA, const char *pszB)
+ {
+ #ifdef _MSC_VER
+ return _mbscoll(reinterpret_cast<const unsigned char*>(pszA), reinterpret_cast<const unsigned char*>(pszB));
+ #else
+ return strcoll(pszA, pszB);
+ #endif
+ }
+
+ static int MIR_SYSCALL StringCollateIgnore(const char *pszA, const char *pszB)
+ {
+ #ifdef _MSC_VER
+ return _mbsicoll(reinterpret_cast<const unsigned char*>(pszA), reinterpret_cast<const unsigned char*>(pszB));
+ #else
+ return strcoll(pszA, pszB);
+ #endif
+ }
+
+ static const char* MIR_SYSCALL StringFindString(const char *pszBlock, const char *pszMatch)
+ {
+ #ifdef _MSC_VER
+ return reinterpret_cast<const char*>(_mbsstr(reinterpret_cast<const unsigned char*>(pszBlock),
+ reinterpret_cast<const unsigned char*>(pszMatch)));
+ #else
+ return strstr(pszBlock, pszMatch);
+ #endif
+ }
+
+ static char* MIR_SYSCALL StringFindString(char *pszBlock, const char *pszMatch)
+ {
+ return const_cast<char*>(StringFindString(const_cast<const char*>(pszBlock), pszMatch));
+ }
+
+ static const char* MIR_SYSCALL StringFindChar(const char *pszBlock, char chMatch)
+ {
+ #ifdef _MSC_VER
+ return reinterpret_cast<const char*>(_mbschr(reinterpret_cast<const unsigned char*>(pszBlock), (unsigned char)chMatch));
+ #else
+ return strchr(pszBlock, chMatch);
+ #endif
+ }
+
+ static const char* MIR_SYSCALL StringFindCharRev(const char *psz, char ch)
+ {
+ #ifdef _MSC_VER
+ return reinterpret_cast<const char*>(_mbsrchr(reinterpret_cast<const unsigned char*>(psz), (unsigned char)ch));
+ #else
+ return strrchr(psz, ch);
+ #endif
+ }
+
+ static const char* MIR_SYSCALL StringScanSet(const char *pszBlock, const char *pszMatch)
+ {
+ #ifdef _MSC_VER
+ return reinterpret_cast<const char*>(_mbspbrk(reinterpret_cast<const unsigned char*>(pszBlock),
+ reinterpret_cast<const unsigned char*>(pszMatch)));
+ #else
+ return strpbrk(pszBlock, pszMatch);
+ #endif
+ }
+
+ static int MIR_SYSCALL StringSpanIncluding(const char *pszBlock, const char *pszSet)
+ {
+ #ifdef _MSC_VER
+ return (int)_mbsspn(reinterpret_cast<const unsigned char*>(pszBlock), reinterpret_cast<const unsigned char*>(pszSet));
+ #else
+ return (int)strspn(pszBlock, pszSet);
+ #endif
+ }
+
+ static int MIR_SYSCALL StringSpanExcluding(const char *pszBlock, const char *pszSet)
+ {
+ #ifdef _MSC_VER
+ return (int)_mbscspn(reinterpret_cast<const unsigned char*>(pszBlock), reinterpret_cast<const unsigned char*>(pszSet));
+ #else
+ return (int)strcspn(pszBlock, pszSet);
+ #endif
+ }
+
+ static char* MIR_SYSCALL StringUppercase(char *psz)
+ {
+ #ifdef _MSC_VER
+ CharUpperBuffA(psz, (uint32_t)strlen(psz));
+ #else
+ strupr(psz);
+ #endif
+ return psz;
+ }
+
+ static char* MIR_SYSCALL StringLowercase(char *psz)
+ {
+ #ifdef _MSC_VER
+ CharLowerBuffA(psz, (uint32_t)strlen(psz));
+ #else
+ strlwr(psz);
+ #endif
+ return psz;
+ }
+
+ static char* MIR_SYSCALL StringUppercase(char *psz, size_t size)
+ {
+ #ifdef _MSC_VER
+ CharUpperBuffA(psz, (uint32_t)size);
+ #else
+
+ #endif
+ return psz;
+ }
+
+ static char* MIR_SYSCALL StringLowercase(char *psz, size_t size)
+ {
+ #ifdef _MSC_VER
+ CharLowerBuffA(psz, (uint32_t)size);
+ #endif
+ return psz;
+ }
+
+ static char* MIR_SYSCALL StringReverse(char *psz)
+ {
+ #ifdef _MSC_VER
+ return reinterpret_cast<LPSTR>(_mbsrev(reinterpret_cast<unsigned char*>(psz)));
+ #else
+ return strrev(psz);
+ #endif
+ }
+
+ static int MIR_SYSCALL GetFormattedLength(_Printf_format_string_ const char *pszFormat, va_list args)
+ {
+ #ifdef _MSC_VER
+ return _vscprintf(pszFormat, args);
+ #else
+ return 0; // !!!!!!!!!!
+ #endif
+ }
+
+ static int MIR_SYSCALL Format(char *pszBuffer, size_t nlength, _Printf_format_string_ const char *pszFormat, va_list args)
+ {
+ #ifdef _MSC_VER
+ return vsprintf_s(pszBuffer, nlength, pszFormat, args);
+ #else
+ return 0; // !!!!!!!!!!
+ #endif
+ }
+
+ static int MIR_SYSCALL GetBaseTypeLength(const char *pszSrc)
+ {
+ // Returns required buffer length in XCHARs
+ return int(strlen(pszSrc));
+ }
+
+ static int MIR_SYSCALL GetBaseTypeLength(const char *pszSrc, int nLength)
+ {
+ (void)pszSrc;
+ // Returns required buffer length in XCHARs
+ return nLength;
+ }
+
+ static int MIR_SYSCALL GetBaseTypeLength(const wchar_t *pszSource)
+ {
+ // Returns required buffer length in XCHARs
+ #ifdef _MSC_VER
+ return ::WideCharToMultiByte(Langpack_GetDefaultCodePage(), 0, pszSource, -1, NULL, 0, NULL, NULL) - 1;
+ #else
+ return 0;
+ #endif
+ }
+
+ static int MIR_SYSCALL GetBaseTypeLength(const wchar_t *pszSource, int nLength)
+ {
+ // Returns required buffer length in XCHARs
+ #ifdef _MSC_VER
+ return ::WideCharToMultiByte(Langpack_GetDefaultCodePage(), 0, pszSource, nLength, NULL, 0, NULL, NULL);
+ #else
+ return 0;
+ #endif
+ }
+
+ static void MIR_SYSCALL ConvertToBaseType(char*pszDest, int nDestLength, const char *pszSrc, int nSrcLength = -1)
+ {
+ if (nSrcLength == -1) { nSrcLength = 1 + GetBaseTypeLength(pszSrc); }
+ // nLen is in XCHARs
+ memcpy_s(pszDest, nDestLength*sizeof(char), pszSrc, nSrcLength*sizeof(char));
+ }
+
+ static void MIR_SYSCALL ConvertToBaseType(char*pszDest, int nDestLength, const wchar_t *pszSrc, int nSrcLength = -1)
+ {
+ // nLen is in XCHARs
+ #ifdef _MSC_VER
+ ::WideCharToMultiByte(Langpack_GetDefaultCodePage(), 0, pszSrc, nSrcLength, pszDest, nDestLength, NULL, NULL);
+ #endif
+ }
+
+ static void ConvertToOem(_CharType* pstrString)
+ {
+ #ifdef _MSC_VER
+ bool fSuccess = ::CharToOemA(pstrString, pstrString);
+ #endif // _MSC_VER
+ }
+
+ static void ConvertToAnsi(_CharType* pstrString)
+ {
+ #ifdef _MSC_VER
+ bool fSuccess = ::OemToCharA(pstrString, pstrString);
+ #endif
+ }
+
+ static void ConvertToOem(_CharType* pstrString, size_t size)
+ {
+ #ifdef _MSC_VER
+ uint32_t dwSize = static_cast<uint32_t>(size);
+ ::CharToOemBuffA(pstrString, pstrString, dwSize);
+ #endif
+ }
+
+ static void ConvertToAnsi(_CharType* pstrString, size_t size)
+ {
+ #ifdef _MSC_VER
+ uint32_t dwSize = static_cast<uint32_t>(size);
+ ::OemToCharBuffA(pstrString, pstrString, dwSize);
+ #endif
+ }
+
+ static void MIR_SYSCALL FloodCharacters(char ch, int nLength, char* pch)
+ {
+ // nLength is in XCHARs
+ memset(pch, ch, nLength);
+ }
+
+ static int MIR_SYSCALL SafeStringLen(const char *psz)
+ {
+ // returns length in bytes
+ return (psz != NULL) ? int(strlen(psz)) : 0;
+ }
+
+ static int MIR_SYSCALL SafeStringLen(const wchar_t *psz)
+ {
+ // returns length in wchar_ts
+ return (psz != NULL) ? int(wcslen(psz)) : 0;
+ }
+
+ static int MIR_SYSCALL GetCharLen(const wchar_t *pch)
+ {
+ // returns char length
+ return 1;
+ }
+
+ static int MIR_SYSCALL GetCharLen(const char *pch)
+ {
+ // returns char length
+ #ifdef _MSC_VER
+ return int(_mbclen(reinterpret_cast<const unsigned char*>(pch)));
+ #else
+ return mblen(pch, strlen(pch));
+ #endif
+ }
+
+ static uint32_t MIR_SYSCALL GetEnvironmentVariable(const char *pszVar, char*pszBuffer, uint32_t dwSize)
+ {
+ #ifdef _MSC_VER
+ return ::GetEnvironmentVariableA(pszVar, pszBuffer, dwSize);
+ #else
+ return 0; // !!!!!!!!!!
+ #endif
+ }
+
+ static char* MirCopy(const char *pstrString, size_t size)
+ {
+ return mir_strndup(pstrString, size);
+ }
+};
+
+// specialization for wchar_t
+template<>
+class ChTraitsCRT< wchar_t > : public ChTraitsBase< wchar_t >
+{
+ static uint32_t MIR_SYSCALL _GetEnvironmentVariableW(const wchar_t *pszName, wchar_t *pszBuffer, uint32_t nSize)
+ {
+ #ifdef _MSC_VER
+ return ::GetEnvironmentVariableW(pszName, pszBuffer, nSize);
+ #else
+ return 0; // !!!!!!!!!!
+ #endif
+ }
+
+public:
+ static wchar_t* MIR_SYSCALL CharNext(const wchar_t *psz)
+ {
+ return const_cast<wchar_t*>(psz+1);
+ }
+
+ static int MIR_SYSCALL IsDigit(wchar_t ch)
+ {
+ #ifdef _MSC_VER
+ return iswdigit(static_cast<unsigned short>(ch));
+ #else
+ return 0;
+ #endif
+ }
+
+ static int MIR_SYSCALL IsSpace(wchar_t ch)
+ {
+ #ifdef _MSC_VER
+ return iswspace(static_cast<unsigned short>(ch));
+ #else
+ return 0;
+ #endif
+ }
+
+ static int MIR_SYSCALL StringCompare(const wchar_t *pszA, const wchar_t *pszB)
+ {
+ return wcscmp(pszA, pszB);
+ }
+
+ static int MIR_SYSCALL StringCompareIgnore(const wchar_t *pszA, const wchar_t *pszB)
+ {
+ #ifdef _MSC_VER
+ return _wcsicmp(pszA, pszB);
+ #else
+ return 0;
+ #endif
+ }
+
+ static int MIR_SYSCALL StringCollate(const wchar_t *pszA, const wchar_t *pszB)
+ {
+ return wcscoll(pszA, pszB);
+ }
+
+ static int MIR_SYSCALL StringCollateIgnore(const wchar_t *pszA, const wchar_t *pszB)
+ {
+ #ifdef _MSC_VER
+ return _wcsicoll(pszA, pszB);
+ #else
+ return 0;
+ #endif
+ }
+
+ static const wchar_t* MIR_SYSCALL StringFindString(const wchar_t *pszBlock, const wchar_t *pszMatch)
+ {
+ return wcsstr(pszBlock, pszMatch);
+ }
+
+ static wchar_t* MIR_SYSCALL StringFindString(wchar_t *pszBlock, const wchar_t *pszMatch)
+ {
+ return const_cast<wchar_t*>(wcsstr(pszBlock, pszMatch));
+ }
+
+ static const wchar_t* MIR_SYSCALL StringFindChar(const wchar_t *pszBlock, wchar_t chMatch)
+ {
+ return wcschr(pszBlock, chMatch);
+ }
+
+ static const wchar_t* MIR_SYSCALL StringFindCharRev(const wchar_t *psz, wchar_t ch)
+ {
+ return wcsrchr(psz, ch);
+ }
+
+ static const wchar_t* MIR_SYSCALL StringScanSet(const wchar_t *pszBlock, const wchar_t *pszMatch)
+ {
+ return wcspbrk(pszBlock, pszMatch);
+ }
+
+ static int MIR_SYSCALL StringSpanIncluding(const wchar_t *pszBlock, const wchar_t *pszSet)
+ {
+ return (int)wcsspn(pszBlock, pszSet);
+ }
+
+ static int MIR_SYSCALL StringSpanExcluding(const wchar_t *pszBlock, const wchar_t *pszSet)
+ {
+ return (int)wcscspn(pszBlock, pszSet);
+ }
+
+ static wchar_t* MIR_SYSCALL StringUppercase(wchar_t *psz)
+ {
+ #ifdef _MSC_VER
+ CharUpperBuffW(psz, (uint32_t)wcslen(psz));
+ #endif
+ return psz;
+ }
+
+ static wchar_t* MIR_SYSCALL StringLowercase(wchar_t *psz)
+ {
+ #ifdef _MSC_VER
+ CharLowerBuffW(psz, (uint32_t)wcslen(psz));
+ #endif
+ return psz;
+ }
+
+ static wchar_t* MIR_SYSCALL StringUppercase(wchar_t *psz, size_t len)
+ {
+ #ifdef _MSC_VER
+ CharUpperBuffW(psz, (uint32_t)len);
+ #endif
+ return psz;
+ }
+
+ static wchar_t* MIR_SYSCALL StringLowercase(wchar_t *psz, size_t len)
+ {
+ #ifdef _MSC_VER
+ CharLowerBuffW(psz, (uint32_t)len);
+ #endif
+ return psz;
+ }
+
+ static wchar_t* MIR_SYSCALL StringReverse(wchar_t *psz)
+ {
+ #ifdef _MSC_VER
+ return _wcsrev(psz);
+ #else
+ return psz;
+ #endif
+ }
+
+ static int MIR_SYSCALL GetFormattedLength(_Printf_format_string_ const wchar_t *pszFormat, va_list args)
+ {
+ #ifdef _MSC_VER
+ return _vscwprintf(pszFormat, args);
+ #else
+ return 0;
+ #endif
+ }
+
+ static int MIR_SYSCALL Format(wchar_t *pszBuffer, _Printf_format_string_ const wchar_t *pszFormat, va_list args)
+ {
+ #pragma warning(push)
+ #pragma warning(disable : 4996)
+
+ #ifdef _MSC_VER
+ return vswprintf(pszBuffer, pszFormat, args);
+ #else
+ return 0;
+ #endif
+ #pragma warning(pop)
+ }
+
+ static int MIR_SYSCALL Format(wchar_t *pszBuffer, size_t nLength, _Printf_format_string_ const wchar_t *pszFormat, va_list args)
+ {
+ #pragma warning(push)
+ #pragma warning(disable : 4996)
+
+ #ifdef _MSC_VER
+ return _vsnwprintf(pszBuffer, nLength, pszFormat, args);
+ #else
+ return 0;
+ #endif
+
+ #pragma warning(pop)
+ }
+
+ static int MIR_SYSCALL GetBaseTypeLength(const char *pszSrc)
+ {
+ // Returns required buffer size in wchar_ts
+ #ifdef _MSC_VER
+ return ::MultiByteToWideChar(CP_ACP, 0, pszSrc, -1, nullptr, 0)-1;
+ #else
+ return 0;
+ #endif
+ }
+
+ static int MIR_SYSCALL GetBaseTypeLength(const char *pszSrc, int nLength)
+ {
+ // Returns required buffer size in wchar_ts
+ #ifdef _MSC_VER
+ return ::MultiByteToWideChar(CP_ACP, 0, pszSrc, nLength, nullptr, 0);
+ #else
+ return 0;
+ #endif
+ }
+
+ static int MIR_SYSCALL GetBaseTypeLength(const wchar_t *pszSrc)
+ {
+ // Returns required buffer size in wchar_ts
+ return (int)wcslen(pszSrc);
+ }
+
+ static int MIR_SYSCALL GetBaseTypeLength(const wchar_t *pszSrc, int nLength)
+ {
+ (void)pszSrc;
+ // Returns required buffer size in wchar_ts
+ return nLength;
+ }
+
+ static void MIR_SYSCALL ConvertToBaseType(wchar_t *pszDest, int nDestLength, const char *pszSrc, int nSrcLength = -1)
+ {
+ // nLen is in wchar_ts
+ #ifdef _MSC_VER
+ ::MultiByteToWideChar(CP_ACP, 0, pszSrc, nSrcLength, pszDest, nDestLength);
+ #endif
+ }
+
+ static void MIR_SYSCALL ConvertToBaseType(wchar_t *pszDest, int nDestLength, const wchar_t *pszSrc, int nSrcLength = -1)
+ {
+ if (nSrcLength == -1) { nSrcLength=1 + GetBaseTypeLength(pszSrc); }
+ // nLen is in wchar_ts
+ #if _MSC_VER >= 1400
+ wmemcpy_s(pszDest, nDestLength, pszSrc, nSrcLength);
+ #else
+ wmemcpy(pszDest, pszSrc, nDestLength);
+ #endif
+ }
+
+ static void MIR_SYSCALL FloodCharacters(wchar_t ch, int nLength, wchar_t *psz)
+ {
+ // nLength is in XCHARs
+ for (int i = 0; i < nLength; i++)
+ {
+ psz[i] = ch;
+ }
+ }
+
+ static int MIR_SYSCALL SafeStringLen(const char *psz)
+ {
+ // returns length in bytes
+ return (psz != nullptr) ? (int)strlen(psz) : 0;
+ }
+
+ static int MIR_SYSCALL SafeStringLen(const wchar_t *psz)
+ {
+ // returns length in wchar_ts
+ return (psz != nullptr) ? (int)wcslen(psz) : 0;
+ }
+
+ static int MIR_SYSCALL GetCharLen(const wchar_t* pch)
+ {
+ (void)pch;
+ // returns char length
+ return 1;
+ }
+
+ static int MIR_SYSCALL GetCharLen(const char* pch)
+ {
+ // returns char length
+ #ifdef _MSC_VER
+ return (int)(_mbclen(reinterpret_cast< const unsigned char* >(pch)));
+ #else
+ return mblen(pch, strlen(pch));
+ #endif
+ }
+
+ static uint32_t MIR_SYSCALL GetEnvironmentVariable(const wchar_t *pszVar, wchar_t *pszBuffer, uint32_t dwSize)
+ {
+ return _GetEnvironmentVariableW(pszVar, pszBuffer, dwSize);
+ }
+
+ static void MIR_SYSCALL ConvertToOem(wchar_t* /*psz*/)
+ {
+ }
+
+ static void MIR_SYSCALL ConvertToAnsi(wchar_t* /*psz*/)
+ {
+ }
+
+ static void MIR_SYSCALL ConvertToOem(wchar_t* /*psz*/, size_t)
+ {
+ }
+
+ static void MIR_SYSCALL ConvertToAnsi(wchar_t* /*psz*/, size_t)
+ {
+ }
+
+ static wchar_t* MirCopy(const wchar_t *pstrString, size_t size)
+ {
+ return mir_wstrndup(pstrString, size);
+ }
+};
+
+template< typename BaseType, class StringTraits >
+class MIR_CORE_EXPORT CMStringT : public CMSimpleStringT< BaseType >
+{
+public:
+ typedef CMSimpleStringT< BaseType> CThisSimpleString;
+ typedef typename CThisSimpleString::XCHAR XCHAR;
+ typedef typename CThisSimpleString::PXSTR PXSTR;
+ typedef typename CThisSimpleString::PCXSTR PCXSTR;
+ typedef typename CThisSimpleString::YCHAR YCHAR;
+ typedef typename CThisSimpleString::PYSTR PYSTR;
+ typedef typename CThisSimpleString::PCYSTR PCYSTR;
+
+public:
+ CMStringT();
+
+ // Copy constructor
+ CMStringT(const CMStringT& strSrc);
+
+ CMStringT(const XCHAR* pszSrc);
+ CMStringT(CMStringDataFormat, _Printf_format_string_ const XCHAR* pszFormat, ...);
+
+ CMStringT(const YCHAR* pszSrc);
+ CMStringT(const unsigned char* pszSrc);
+
+ CMStringT(char ch, int nLength = 1);
+ CMStringT(wchar_t ch, int nLength = 1);
+
+ CMStringT(const XCHAR* pch, int nLength);
+ CMStringT(const YCHAR* pch, int nLength);
+
+ // Destructor
+ ~CMStringT();
+
+ // Assignment operators
+ CMStringT& operator=(const CMStringT& strSrc);
+ CMStringT& operator=(PCXSTR pszSrc);
+ CMStringT& operator=(PCYSTR pszSrc);
+ CMStringT& operator=(const unsigned char* pszSrc);
+ CMStringT& operator=(char ch);
+ CMStringT& operator=(wchar_t ch);
+
+ CMStringT& operator+=(const CMStringT& str);
+ CMStringT& operator+=(const CThisSimpleString& str);
+ CMStringT& operator+=(PCXSTR pszSrc);
+ CMStringT& operator+=(PCYSTR pszSrc);
+ CMStringT& operator+=(char ch);
+ CMStringT& operator+=(unsigned char ch);
+ CMStringT& operator+=(wchar_t ch);
+
+ // Comparison
+
+ int Compare(PCXSTR psz) const;
+ int CompareNoCase(PCXSTR psz) const;
+ int Collate(PCXSTR psz) const;
+ int CollateNoCase(PCXSTR psz) const;
+
+ // Advanced manipulation
+
+ // Delete 'nCount' characters, starting at index 'iIndex'
+ int Delete(int iIndex, int nCount = 1);
+
+ // Insert character 'ch' before index 'iIndex'
+ int Insert(int iIndex, XCHAR ch);
+
+ // Insert string 'psz' before index 'iIndex'
+ int Insert(int iIndex, PCXSTR psz);
+
+ // Replace all occurrences of character 'chOld' with character 'chNew'
+ int Replace(XCHAR chOld, XCHAR chNew);
+
+ // Replace all occurrences of string 'pszOld' with string 'pszNew'
+ int Replace(PCXSTR pszOld, PCXSTR pszNew);
+
+ // Remove all occurrences of character 'chRemove'
+ int Remove(XCHAR chRemove);
+
+ CMStringT Tokenize(PCXSTR pszTokens, int& iStart) const;
+
+ // find routines
+
+ // Find the first occurrence of character 'ch', starting at index 'iStart'
+ int Find(XCHAR ch, int iStart = 0) const;
+
+ // look for a specific sub-string
+
+ // Find the first occurrence of string 'pszSub', starting at index 'iStart'
+ int Find(PCXSTR pszSub, int iStart = 0) const;
+
+ // Find the first occurrence of any of the characters in string 'pszCharSet'
+ int FindOneOf(PCXSTR pszCharSet) const;
+
+ // Find the last occurrence of character 'ch'
+ int ReverseFind(XCHAR ch) const;
+
+ // manipulation
+
+ // Convert the string to uppercase
+ CMStringT& MakeUpper();
+
+ // Convert the string to lowercase
+ CMStringT& MakeLower();
+
+ // Reverse the string
+ CMStringT& MakeReverse();
+
+ // trimming
+
+ // Remove all trailing whitespace
+ CMStringT& TrimRight();
+
+ // Remove all leading whitespace
+ CMStringT& TrimLeft();
+
+ // Remove all leading and trailing whitespace
+ CMStringT& Trim();
+
+ // Remove all leading and trailing occurrences of character 'chTarget'
+ CMStringT& Trim(XCHAR chTarget);
+
+ // Remove all leading and trailing occurrences of any of the characters in the string 'pszTargets'
+ CMStringT& Trim(PCXSTR pszTargets);
+
+ // trimming anything (either side)
+
+ // Remove all trailing occurrences of character 'chTarget'
+ CMStringT& TrimRight(XCHAR chTarget);
+
+ // Remove all trailing occurrences of any of the characters in string 'pszTargets'
+ CMStringT& TrimRight(PCXSTR pszTargets);
+
+ // Remove all leading occurrences of character 'chTarget'
+ CMStringT& TrimLeft(XCHAR chTarget);
+
+ // Remove all leading occurrences of any of the characters in string 'pszTargets'
+ CMStringT& TrimLeft(PCXSTR pszTargets);
+
+ // Convert the string to the OEM character set
+ void AnsiToOem();
+
+ // Convert the string to the ANSI character set
+ void OemToAnsi();
+
+ // Very simple sub-string extraction
+
+ // Return the substring starting at index 'iFirst'
+ CMStringT Mid(int iFirst) const;
+
+ // Return the substring starting at index 'iFirst', with length 'nCount'
+ CMStringT Mid(int iFirst, int nCount) const;
+
+ // Return the substring consisting of the rightmost 'nCount' characters
+ CMStringT Right(int nCount) const;
+
+ // Return the substring consisting of the leftmost 'nCount' characters
+ CMStringT Left(int nCount) const;
+
+ // Return the substring consisting of the leftmost characters in the set 'pszCharSet'
+ CMStringT SpanIncluding(PCXSTR pszCharSet) const;
+
+ // Return the substring consisting of the leftmost characters not in the set 'pszCharSet'
+ CMStringT SpanExcluding(PCXSTR pszCharSet) const;
+
+ // Format data using format string 'pszFormat'
+ PCXSTR Format(PCXSTR _Printf_format_string_ pszFormat, ...);
+ PCXSTR FormatV(PCXSTR _Printf_format_string_ pszFormat, va_list args);
+
+ // Append formatted data using format string 'pszFormat'
+ PCXSTR AppendFormat(PCXSTR _Printf_format_string_ pszFormat, ...);
+ void AppendFormatV(PCXSTR _Printf_format_string_ pszFormat, va_list args);
+
+ // return a copy of string to be freed by mir_free()
+ PXSTR Detach() const;
+
+ // Set the string to the value of environment variable 'pszVar'
+ BOOL GetEnvironmentVariable(PCXSTR pszVar);
+
+ friend bool __forceinline operator==(const CMStringT& str1, const CMStringT& str2) { return str1.Compare(str2) == 0; }
+ friend bool __forceinline operator==(const CMStringT& str1, PCXSTR psz2) { return str1.Compare(psz2) == 0; }
+ friend bool __forceinline operator==(PCXSTR psz1, const CMStringT& str2) { return str2.Compare(psz1) == 0; }
+ friend bool __forceinline operator==(const CMStringT& str1, PCYSTR psz2) { return str1 == CMStringT(psz2); }
+ friend bool __forceinline operator==(PCYSTR psz1, const CMStringT& str2) { return CMStringT(psz1) == str2; }
+
+ friend bool __forceinline operator!=(const CMStringT& str1, const CMStringT& str2) { return str1.Compare(str2) != 0; }
+ friend bool __forceinline operator!=(const CMStringT& str1, PCXSTR psz2) { return str1.Compare(psz2) != 0; }
+ friend bool __forceinline operator!=(PCXSTR psz1, const CMStringT& str2) { return str2.Compare(psz1) != 0; }
+ friend bool __forceinline operator!=(const CMStringT& str1, PCYSTR psz2) { return str1 != CMStringT(psz2); }
+ friend bool __forceinline operator!=(PCYSTR psz1, const CMStringT& str2) { return CMStringT(psz1) != str2; }
+
+ friend bool __forceinline operator<(const CMStringT& str1, const CMStringT& str2) { return str1.Compare(str2) < 0; }
+ friend bool __forceinline operator<(const CMStringT& str1, PCXSTR psz2) { return str1.Compare(psz2) < 0; }
+ friend bool __forceinline operator<(PCXSTR psz1, const CMStringT& str2) { return str2.Compare(psz1) > 0; }
+
+ friend bool __forceinline operator>(const CMStringT& str1, const CMStringT& str2) { return str1.Compare(str2) > 0; }
+ friend bool __forceinline operator>(const CMStringT& str1, PCXSTR psz2) { return str1.Compare(psz2) > 0; }
+ friend bool __forceinline operator>(PCXSTR psz1, const CMStringT& str2) { return str2.Compare(psz1) < 0; }
+
+ friend bool __forceinline operator<=(const CMStringT& str1, const CMStringT& str2) { return str1.Compare(str2) <= 0; }
+ friend bool __forceinline operator<=(const CMStringT& str1, PCXSTR psz2) { return str1.Compare(psz2) <= 0; }
+ friend bool __forceinline operator<=(PCXSTR psz1, const CMStringT& str2) { return str2.Compare(psz1) >= 0; }
+
+ friend bool __forceinline operator>=(const CMStringT& str1, const CMStringT& str2) { return str1.Compare(str2) >= 0; }
+ friend bool __forceinline operator>=(const CMStringT& str1, PCXSTR psz2) { return str1.Compare(psz2) >= 0; }
+ friend bool __forceinline operator>=(PCXSTR psz1, const CMStringT& str2) { return str2.Compare(psz1) <= 0; }
+
+ friend bool __forceinline operator==(XCHAR ch1, const CMStringT& str2) { return (str2.GetLength() == 1) && (str2[0] == ch1); }
+ friend bool __forceinline operator==(const CMStringT& str1, XCHAR ch2) { return (str1.GetLength() == 1) && (str1[0] == ch2); }
+
+ friend bool __forceinline operator!=(XCHAR ch1, const CMStringT& str2) { return (str2.GetLength() != 1) || (str2[0] != ch1); }
+ friend bool __forceinline operator!=(const CMStringT& str1, XCHAR ch2) { return (str1.GetLength() != 1) || (str1[0] != ch2); }
+};
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, const CMStringT<BaseType, StringTraits>& str2);
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, typename CMStringT<BaseType, StringTraits>::PCXSTR psz2);
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(typename CMStringT<BaseType, StringTraits>::PCXSTR psz1, const CMStringT<BaseType, StringTraits>& str2);
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, wchar_t ch2);
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, char ch2);
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator + (wchar_t ch1, const CMStringT<BaseType, StringTraits>& str2);
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(char ch1, const CMStringT<BaseType, StringTraits>& str2);
+
+typedef CMStringT< wchar_t, ChTraitsCRT< wchar_t > > CMStringW;
+typedef CMStringT< char, ChTraitsCRT< char > > CMStringA;
+
+#endif // M_STRING_H__
diff --git a/include/m_string.inl b/include/m_string.inl index 40413810ea..7834a573bb 100644 --- a/include/m_string.inl +++ b/include/m_string.inl @@ -1,1471 +1,1471 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#pragma once - -#ifndef M_STRING_INL__ - -#ifndef _MSC_VER - #include <algorithm> - #define __max std::max -#endif - -template<typename BaseType> -CMSimpleStringT<BaseType>::CMSimpleStringT() -{ - CMStringData* pData = mirstr_getNil(); - Attach(pData); -} - -template<typename BaseType> -CMSimpleStringT<BaseType>::CMSimpleStringT(const CMSimpleStringT& strSrc) -{ - CMStringData* pSrcData = strSrc.GetData(); - CMStringData* pNewData = CloneData(pSrcData); - Attach(pNewData); -} - -template<typename BaseType> -CMSimpleStringT<BaseType>::CMSimpleStringT(PCXSTR pszSrc) -{ - int nLength = StringLength(pszSrc); - CMStringData* pData = mirstr_allocate(nLength, sizeof(XCHAR)); - if (pData != nullptr) { - Attach(pData); - SetLength(nLength); - CopyChars(m_pszData, nLength, pszSrc, nLength); - } -} - -template<typename BaseType> -CMSimpleStringT<BaseType>::CMSimpleStringT(const XCHAR* pchSrc, int nLength) -{ - CMStringData* pData = mirstr_allocate(nLength, sizeof(XCHAR)); - if (pData != nullptr) { - Attach(pData); - SetLength(nLength); - CopyChars(m_pszData, nLength, pchSrc, nLength); - } -} - -template<typename BaseType> -CMSimpleStringT<BaseType>::~CMSimpleStringT() -{ - CMStringData* pData = GetData(); - pData->Release(); -} - -template<typename BaseType> -CMSimpleStringT<BaseType>& CMSimpleStringT<BaseType>::operator=(const CMSimpleStringT& strSrc) -{ - CMStringData* pSrcData = strSrc.GetData(); - CMStringData* pOldData = GetData(); - if (pSrcData != pOldData) { - if (pOldData->IsLocked()) - SetString(strSrc.GetString(), strSrc.GetLength()); - else { - CMStringData* pNewData = CloneData(pSrcData); - pOldData->Release(); - Attach(pNewData); - } - } - - return *this; -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::Append(PCXSTR pszSrc) -{ - Append(pszSrc, StringLength(pszSrc)); -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::Append(PCXSTR pszSrc, int nLength) -{ - // See comment in SetString() about why we do this - UINT_PTR nOffset = UINT_PTR(pszSrc - GetString()); - - int nOldLength = GetLength(); - if (nOldLength < 0) { - // protects from underflow - nOldLength = 0; - } - - //Make sure we don't read pass end of the terminating NULL - int nSrcLength = StringLength(pszSrc); - nLength = nLength > nSrcLength ? nSrcLength : nLength; - - int nNewLength = nOldLength + nLength; - PXSTR pszBuffer = GetBuffer(nNewLength); - if (nOffset <= UINT_PTR(nOldLength)) { - pszSrc = pszBuffer + nOffset; - // No need to call CopyCharsOverlapped, since the destination is - // beyond the end of the original buffer - } - CopyChars(pszBuffer + nOldLength, nLength, pszSrc, nLength); - ReleaseBufferSetLength(nNewLength); -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::AppendChar(XCHAR ch) -{ - UINT nOldLength = GetLength(); - int nNewLength = nOldLength + 1; - PXSTR pszBuffer = GetBuffer(nNewLength); - pszBuffer[nOldLength] = ch; - ReleaseBufferSetLength(nNewLength); -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::Append(const CMSimpleStringT<BaseType>& strSrc) -{ - Append(strSrc.GetString(), strSrc.GetLength()); -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::Empty() -{ - CMStringData* pOldData = GetData(); - if (pOldData->nDataLength == 0) - return; - - if (pOldData->IsLocked()) { - // Don't reallocate a locked buffer that's shrinking - SetLength(0); - } - else { - pOldData->Release(); - CMStringData* pNewData = mirstr_getNil(); - Attach(pNewData); - } -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::FreeExtra() -{ - CMStringData* pOldData = GetData(); - int nLength = pOldData->nDataLength; - if (pOldData->nAllocLength == nLength) - return; - - if (!pOldData->IsLocked()) { // Don't reallocate a locked buffer that's shrinking - CMStringData* pNewData = mirstr_allocate(nLength, sizeof(XCHAR)); - if (pNewData == nullptr) { - SetLength(nLength); - return; - } - - CopyChars(PXSTR(pNewData->data()), nLength, PCXSTR(pOldData->data()), nLength); - - pOldData->Release(); - Attach(pNewData); - SetLength(nLength); - } -} - -template<typename BaseType> -typename CMSimpleStringT<BaseType>::PXSTR CMSimpleStringT<BaseType>::GetBuffer() -{ - CMStringData* pData = GetData(); - if (pData->IsShared()) - Fork(pData->nDataLength); - - return m_pszData; -} - -template<typename BaseType> -typename CMSimpleStringT<BaseType>::PXSTR CMSimpleStringT<BaseType>::GetBufferSetLength(int nLength) -{ - PXSTR pszBuffer = GetBuffer(nLength); - SetLength(nLength); - - return pszBuffer; -} - -template<typename BaseType> -typename CMSimpleStringT<BaseType>::PXSTR CMSimpleStringT<BaseType>::LockBuffer() -{ - CMStringData* pData = GetData(); - if (pData->IsShared()) { - Fork(pData->nDataLength); - pData = GetData(); // Do it again, because the fork might have changed it - } - pData->Lock(); - - return m_pszData; -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::UnlockBuffer() -{ - CMStringData* pData = GetData(); - pData->Unlock(); -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::ReleaseBuffer(int nNewLength) -{ - if (nNewLength == -1) { - int nAlloc = GetData()->nAllocLength; - nNewLength = StringLengthN(m_pszData, nAlloc); - } - SetLength(nNewLength); -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::Truncate(int nNewLength) -{ - GetBuffer(nNewLength); - ReleaseBufferSetLength(nNewLength); -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::SetAt(int iChar, XCHAR ch) -{ - int nLength = GetLength(); - PXSTR pszBuffer = GetBuffer(); - pszBuffer[iChar] = ch; - ReleaseBufferSetLength(nLength); - -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::SetString(PCXSTR pszSrc) -{ - SetString(pszSrc, StringLength(pszSrc)); -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::SetString(PCXSTR pszSrc, int nLength) -{ - if (nLength == 0) - Empty(); - else { - UINT nOldLength = GetLength(); - UINT_PTR nOffset = pszSrc - GetString(); - - PXSTR pszBuffer = GetBuffer(nLength); - if (nOffset <= nOldLength) - CopyCharsOverlapped(pszBuffer, GetAllocLength(), pszBuffer + nOffset, nLength); - else - CopyChars(pszBuffer, GetAllocLength(), pszSrc, nLength); - - ReleaseBufferSetLength(nLength); - } -} - -template<typename BaseType> -class CMSimpleStringT<BaseType> operator+(const CMSimpleStringT<BaseType>& str1, const CMSimpleStringT<BaseType>& str2) -{ - CMSimpleStringT<BaseType> s; - Concatenate(s, str1, str1.GetLength(), str2, str2.GetLength()); - return s; -} - -template<typename BaseType> -class CMSimpleStringT<BaseType> operator+(const CMSimpleStringT<BaseType>& str1, typename CMSimpleStringT<BaseType>::PCXSTR psz2) -{ - CMSimpleStringT<BaseType> s; - Concatenate(s, str1, str1.GetLength(), psz2, StringLength(psz2)); - return s; -} - -template<typename BaseType> -CMSimpleStringT<BaseType> operator+(typename CMSimpleStringT<BaseType>::PCXSTR psz1, const CMSimpleStringT<BaseType>& str2) -{ - CMSimpleStringT<BaseType> s; - Concatenate(s, psz1, StringLength(psz1), str2, str2.GetLength()); - return s; -} - -template<typename BaseType> -void MIR_SYSCALL CMSimpleStringT<BaseType>::CopyChars(XCHAR* pchDest, const XCHAR* pchSrc, int nChars) -{ - #pragma warning (push) - #pragma warning(disable : 4996) - memcpy(pchDest, pchSrc, nChars * sizeof(XCHAR)); - #pragma warning (pop) -} - -template<typename BaseType> -void MIR_SYSCALL CMSimpleStringT<BaseType>::CopyChars(XCHAR* pchDest, size_t nDestLen, const XCHAR* pchSrc, int nChars) -{ - memcpy_s(pchDest, nDestLen * sizeof(XCHAR), pchSrc, nChars * sizeof(XCHAR)); -} - -template<typename BaseType> -void MIR_SYSCALL CMSimpleStringT<BaseType>::CopyCharsOverlapped(XCHAR* pchDest, const XCHAR* pchSrc, int nChars) -{ - #pragma warning (push) - #pragma warning(disable : 4996) - memmove(pchDest, pchSrc, nChars * sizeof(XCHAR)); - #pragma warning (pop) -} - -template<typename BaseType> -void MIR_SYSCALL CMSimpleStringT<BaseType>::CopyCharsOverlapped(XCHAR* pchDest, size_t nDestLen, const XCHAR* pchSrc, int nChars) -{ - memmove_s(pchDest, nDestLen * sizeof(XCHAR), pchSrc, nChars * sizeof(XCHAR)); -} - -template<typename BaseType> -int MIR_SYSCALL CMSimpleStringT<BaseType>::StringLength(const char* psz) -{ - if (psz == nullptr) - return(0); - - return (int(strlen(psz))); -} - -template<typename BaseType> -int MIR_SYSCALL CMSimpleStringT<BaseType>::StringLength(const wchar_t* psz) -{ - if (psz == nullptr) - return 0; - - return int(wcslen(psz)); -} - -template<typename BaseType> -int MIR_SYSCALL CMSimpleStringT<BaseType>::StringLengthN(const char* psz, size_t sizeInXChar) -{ - if (psz == nullptr) - return 0; - - return int(strnlen(psz, sizeInXChar)); -} - -template<typename BaseType> -int MIR_SYSCALL CMSimpleStringT<BaseType>::StringLengthN(const wchar_t* psz, size_t sizeInXChar) -{ - if (psz == nullptr) - return 0; - - return int(wcsnlen(psz, sizeInXChar)); -} - -template<typename BaseType> -void MIR_SYSCALL CMSimpleStringT<BaseType>::Concatenate(CMSimpleStringT<BaseType>& strResult, PCXSTR psz1, int nLength1, PCXSTR psz2, int nLength2) -{ - int nNewLength = nLength1 + nLength2; - PXSTR pszBuffer = strResult.GetBuffer(nNewLength); - CopyChars(pszBuffer, nLength1, psz1, nLength1); - CopyChars(pszBuffer + nLength1, nLength2, psz2, nLength2); - strResult.ReleaseBufferSetLength(nNewLength); -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::Attach(CMStringData* pData) -{ - m_pszData = static_cast<PXSTR>(pData->data()); -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::Fork(int nLength) -{ - CMStringData* pOldData = GetData(); - int nOldLength = pOldData->nDataLength; - CMStringData* pNewData = mirstr_allocate(nLength, sizeof(XCHAR)); - if (pNewData != nullptr) { - int nCharsToCopy = ((nOldLength < nLength) ? nOldLength : nLength) + 1; // Copy '\0' - CopyChars(PXSTR(pNewData->data()), nCharsToCopy, PCXSTR(pOldData->data()), nCharsToCopy); - pNewData->nDataLength = nOldLength; - pOldData->Release(); - Attach(pNewData); - } -} - -template<typename BaseType> -typename CMSimpleStringT<BaseType>::PXSTR CMSimpleStringT<BaseType>::PrepareWrite(int nLength) -{ - CMStringData* pOldData = GetData(); - int nShared = 1 - pOldData->nRefs; // nShared < 0 means true, >= 0 means false - int nTooShort = pOldData->nAllocLength - nLength; // nTooShort < 0 means true, >= 0 means false - if ((nShared | nTooShort) < 0) // If either sign bit is set (i.e. either is less than zero), we need to copy data - PrepareWrite2(nLength); - - return m_pszData; -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::PrepareWrite2(int nLength) -{ - CMStringData* pOldData = GetData(); - if (pOldData->nDataLength > nLength) - nLength = pOldData->nDataLength; - - if (pOldData->IsShared()) { - Fork(nLength); - } - else if (pOldData->nAllocLength < nLength) { - // Grow exponentially, until we hit 1K. - int nNewLength = pOldData->nAllocLength; - if (nNewLength > 1024) - nNewLength += 1024; - else - nNewLength *= 2; - - if (nNewLength < nLength) - nNewLength = nLength; - - Reallocate(nNewLength); - } -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::Reallocate(int nLength) -{ - CMStringData* pOldData = GetData(); - if (pOldData->nAllocLength >= nLength || nLength <= 0) - return; - - CMStringData* pNewData = mirstr_realloc(pOldData, nLength, sizeof(XCHAR)); - if (pNewData != nullptr) - Attach(pNewData); -} - -template<typename BaseType> -void CMSimpleStringT<BaseType>::SetLength(int nLength) -{ - GetData()->nDataLength = nLength; - m_pszData[nLength] = 0; -} - -template<typename BaseType> -CMStringData* MIR_SYSCALL CMSimpleStringT<BaseType>::CloneData(CMStringData* pData) -{ - CMStringData* pNewData = nullptr; - - if (!pData->IsLocked()) { - pNewData = pData; - pNewData->AddRef(); - } - - return pNewData; -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>::CMStringT() : - CThisSimpleString() -{ -} - -// Copy constructor -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>::CMStringT(const CMStringT<BaseType, StringTraits>& strSrc) : - CThisSimpleString(strSrc) -{ -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>::CMStringT(const XCHAR* pszSrc) : - CThisSimpleString() -{ - *this = pszSrc; -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>::CMStringT(CMStringDataFormat, const XCHAR* pszFormat, ...) : - CThisSimpleString() -{ - va_list args; - va_start(args, pszFormat); - FormatV(pszFormat, args); -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>::CMStringT(const YCHAR* pszSrc) : - CThisSimpleString() -{ - *this = pszSrc; -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>::CMStringT(const unsigned char* pszSrc) : - CThisSimpleString() -{ - *this = reinterpret_cast<const char*>(pszSrc); -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>::CMStringT(char ch, int nLength) : - CThisSimpleString() -{ - if (nLength > 0) { - PXSTR pszBuffer = this->GetBuffer(nLength); - StringTraits::FloodCharacters(XCHAR(ch), nLength, pszBuffer); - this->ReleaseBufferSetLength(nLength); - } -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>::CMStringT(wchar_t ch, int nLength) : - CThisSimpleString() -{ - if (nLength > 0) { - //Convert ch to the BaseType - wchar_t pszCh[2] = { ch, 0 }; - int nBaseTypeCharLen = 1; - - if (ch != L'\0') - nBaseTypeCharLen = StringTraits::GetBaseTypeLength(pszCh); - - XCHAR *buffBaseTypeChar = new XCHAR[nBaseTypeCharLen + 1]; - StringTraits::ConvertToBaseType(buffBaseTypeChar, nBaseTypeCharLen + 1, pszCh, 1); - //allocate enough characters in String and flood (replicate) with the (converted character)*nLength - PXSTR pszBuffer = this->GetBuffer(nLength*nBaseTypeCharLen); - if (nBaseTypeCharLen == 1) //Optimization for a common case - wide char translates to 1 ansi/wide char. - StringTraits::FloodCharacters(buffBaseTypeChar[0], nLength, pszBuffer); - else { - XCHAR* p = pszBuffer; - for (int i = 0; i < nLength; i++) { - for (int j = 0; j < nBaseTypeCharLen; ++j) { - *p = buffBaseTypeChar[j]; - ++p; - } - } - } - this->ReleaseBufferSetLength(nLength*nBaseTypeCharLen); - delete[] buffBaseTypeChar; - } -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>::CMStringT(const XCHAR* pch, int nLength) : - CThisSimpleString(pch, nLength) -{ -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>::CMStringT(const YCHAR* pch, int nLength) : - CThisSimpleString() -{ - if (nLength > 0) { - int nDestLength = StringTraits::GetBaseTypeLength(pch, nLength); - PXSTR pszBuffer = this->GetBuffer(nDestLength); - StringTraits::ConvertToBaseType(pszBuffer, nDestLength, pch, nLength); - this->ReleaseBufferSetLength(nDestLength); - } -} - -// Destructor -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>::~CMStringT() -{ -} - -// Assignment operators -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator=(const CMStringT& strSrc) -{ - CThisSimpleString::operator=(strSrc); - return *this; -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator=(PCXSTR pszSrc) -{ - CThisSimpleString::operator=(pszSrc); - return *this; -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator=(PCYSTR pszSrc) -{ - // nDestLength is in XCHARs - int nDestLength = (pszSrc != nullptr) ? StringTraits::GetBaseTypeLength(pszSrc) : 0; - if (nDestLength > 0) { - PXSTR pszBuffer = this->GetBuffer(nDestLength); - StringTraits::ConvertToBaseType(pszBuffer, nDestLength, pszSrc); - this->ReleaseBufferSetLength(nDestLength); - } - else this->Empty(); - - return *this; -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator=(const unsigned char* pszSrc) -{ - return operator=(reinterpret_cast<const char*>(pszSrc)); -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator=(char ch) -{ - char ach[2] = { ch, 0 }; - return operator=(ach); -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator=(wchar_t ch) -{ - wchar_t ach[2] = { ch, 0 }; - return operator=(ach); -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(const CMStringT& str) -{ - CThisSimpleString::operator+=(str); - return *this; -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(const CThisSimpleString& str) -{ - CThisSimpleString::operator+=(str); - return *this; -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(PCXSTR pszSrc) -{ - CThisSimpleString::operator+=(pszSrc); - return *this; -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(PCYSTR pszSrc) -{ - CMStringT str(pszSrc); - return operator+=(str); -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(char ch) -{ - CThisSimpleString::operator+=(ch); - return *this; -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(unsigned char ch) -{ - CThisSimpleString::operator+=(ch); - return *this; -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(wchar_t ch) -{ - CThisSimpleString::operator+=(ch); - return *this; -} - -// Comparison - -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::Compare(PCXSTR psz) const -{ - return StringTraits::StringCompare(this->GetString(), psz); -} - -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::CompareNoCase(PCXSTR psz) const -{ - return StringTraits::StringCompareIgnore(this->GetString(), psz); -} - -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::Collate(PCXSTR psz) const -{ - return StringTraits::StringCollate(this->GetString(), psz); -} - -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::CollateNoCase(PCXSTR psz) const -{ - return StringTraits::StringCollateIgnore(this->GetString(), psz); -} - -// Advanced manipulation - -// Delete 'nCount' characters, starting at index 'iIndex' -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::Delete(int iIndex, int nCount) -{ - if (iIndex < 0) - iIndex = 0; - - if (nCount < 0) - nCount = 0; - - int nLength = this->GetLength(); - if (nCount + iIndex > nLength) - nCount = nLength - iIndex; - - if (nCount > 0) { - int nNewLength = nLength - nCount; - int nXCHARsToCopy = nLength - (iIndex + nCount) + 1; - PXSTR pszBuffer = this->GetBuffer(); -#if _MSC_VER >= 1400 - memmove_s(pszBuffer + iIndex, nXCHARsToCopy*sizeof(XCHAR), pszBuffer + iIndex + nCount, nXCHARsToCopy*sizeof(XCHAR)); -#else - memmove(pszBuffer+iIndex, pszBuffer+iIndex+nCount, nXCHARsToCopy*sizeof(XCHAR)); -#endif - this->ReleaseBufferSetLength(nNewLength); - } - - return this->GetLength(); -} - -// Insert character 'ch' before index 'iIndex' -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::Insert(int iIndex, XCHAR ch) -{ - if (iIndex < 0) - iIndex = 0; - - if (iIndex > this->GetLength()) - iIndex = this->GetLength(); - - int nNewLength = this->GetLength() + 1; - - PXSTR pszBuffer = this->GetBuffer(nNewLength); - - // move existing bytes down -#if _MSC_VER >= 1400 - memmove_s(pszBuffer + iIndex + 1, (nNewLength - iIndex)*sizeof(XCHAR), pszBuffer + iIndex, (nNewLength - iIndex)*sizeof(XCHAR)); -#else - memmove(pszBuffer+iIndex+1, pszBuffer+iIndex, (nNewLength-iIndex)*sizeof(XCHAR)); -#endif - pszBuffer[iIndex] = ch; - - this->ReleaseBufferSetLength(nNewLength); - return nNewLength; -} - -// Insert string 'psz' before index 'iIndex' -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::Insert(int iIndex, PCXSTR psz) -{ - if (iIndex < 0) - iIndex = 0; - - if (iIndex > this->GetLength()) - iIndex = this->GetLength(); - - // nInsertLength and nNewLength are in XCHARs - int nInsertLength = StringTraits::SafeStringLen(psz); - int nNewLength = this->GetLength(); - if (nInsertLength > 0) { - nNewLength += nInsertLength; - - PXSTR pszBuffer = this->GetBuffer(nNewLength); - // move existing bytes down -#if _MSC_VER >= 1400 - memmove_s(pszBuffer + iIndex + nInsertLength, (nNewLength - iIndex - nInsertLength + 1)*sizeof(XCHAR), pszBuffer + iIndex, (nNewLength - iIndex - nInsertLength + 1)*sizeof(XCHAR)); - memcpy_s(pszBuffer + iIndex, nInsertLength*sizeof(XCHAR), psz, nInsertLength*sizeof(XCHAR)); -#else - memmove(pszBuffer+iIndex+nInsertLength, pszBuffer+iIndex, (nNewLength-iIndex-nInsertLength+1)*sizeof(XCHAR)); - memcpy(pszBuffer+iIndex, psz, nInsertLength*sizeof(XCHAR)); -#endif - this->ReleaseBufferSetLength(nNewLength); - } - - return nNewLength; -} - -// Replace all occurrences of character 'chOld' with character 'chNew' -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::Replace(XCHAR chOld, XCHAR chNew) -{ - int nCount = 0; - - // short-circuit the nop case - if (chOld != chNew) { - // otherwise modify each character that matches in the string - bool bCopied = false; - PXSTR pszBuffer = const_cast<PXSTR>(this->GetString()); // We don't actually write to pszBuffer until we've called GetBuffer(). - - int nLength = this->GetLength(); - int iChar = 0; - while (iChar < nLength) { - // replace instances of the specified character only - if (pszBuffer[iChar] == chOld) { - if (!bCopied) { - bCopied = true; - pszBuffer = this->GetBuffer(nLength); - } - pszBuffer[iChar] = chNew; - nCount++; - } - iChar = int(StringTraits::CharNext(pszBuffer + iChar) - pszBuffer); - } - - if (bCopied) - this->ReleaseBufferSetLength(nLength); - } - - return nCount; -} - -// Replace all occurrences of string 'pszOld' with string 'pszNew' -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::Replace(PCXSTR pszOld, PCXSTR pszNew) -{ - // can't have empty or NULL lpszOld - - // nSourceLen is in XCHARs - int nSourceLen = StringTraits::SafeStringLen(pszOld); - if (nSourceLen == 0) - return 0; - // nReplacementLen is in XCHARs - int nReplacementLen = StringTraits::SafeStringLen(pszNew); - - // loop once to figure out the size of the result string - int nCount = 0; - { - PCXSTR pszStart = this->GetString(); - PCXSTR pszEnd = pszStart + this->GetLength(); - while (pszStart < pszEnd) { - PCXSTR pszTarget; - while ((pszTarget = StringTraits::StringFindString(pszStart, pszOld)) != nullptr) { - nCount++; - pszStart = pszTarget + nSourceLen; - } - pszStart += StringTraits::SafeStringLen(pszStart) + 1; - } - } - - // if any changes were made, make them - if (nCount > 0) { - // if the buffer is too small, just - // allocate a new buffer (slow but sure) - int nOldLength = this->GetLength(); - int nNewLength = nOldLength + (nReplacementLen - nSourceLen)*nCount; - - PXSTR pszBuffer = this->GetBuffer(__max(nNewLength, nOldLength)); - - PXSTR pszStart = pszBuffer; - PXSTR pszEnd = pszStart + nOldLength; - - // loop again to actually do the work - while (pszStart < pszEnd) { - PXSTR pszTarget; - while ((pszTarget = StringTraits::StringFindString(pszStart, pszOld)) != nullptr) { - int nBalance = nOldLength - int(pszTarget - pszBuffer + nSourceLen); - memmove_s(pszTarget + nReplacementLen, nBalance*sizeof(XCHAR), - pszTarget + nSourceLen, nBalance*sizeof(XCHAR)); - memcpy_s(pszTarget, nReplacementLen*sizeof(XCHAR), - pszNew, nReplacementLen*sizeof(XCHAR)); - pszStart = pszTarget + nReplacementLen; - pszTarget[nReplacementLen + nBalance] = 0; - nOldLength += (nReplacementLen - nSourceLen); - } - pszStart += StringTraits::SafeStringLen(pszStart) + 1; - } - this->ReleaseBufferSetLength(nNewLength); - } - - return nCount; -} - -// Remove all occurrences of character 'chRemove' -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::Remove(XCHAR chRemove) -{ - int nLength = this->GetLength(); - PXSTR pszBuffer = this->GetBuffer(nLength); - - PXSTR pszSource = pszBuffer; - PXSTR pszDest = pszBuffer; - PXSTR pszEnd = pszBuffer + nLength; - - while (pszSource < pszEnd) { - PXSTR pszNewSource = StringTraits::CharNext(pszSource); - if (*pszSource != chRemove) { - // Copy the source to the destination. Remember to copy all bytes of an MBCS character - size_t NewSourceGap = (pszNewSource - pszSource); - PXSTR pszNewDest = pszDest + NewSourceGap; - for (size_t i = 0; pszDest != pszNewDest && i < NewSourceGap; i++) { - *pszDest = *pszSource; - pszSource++; - pszDest++; - } - } - pszSource = pszNewSource; - } - *pszDest = 0; - int nCount = int(pszSource - pszDest); - this->ReleaseBufferSetLength(nLength - nCount); - - return nCount; -} - -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::Tokenize(PCXSTR pszTokens, int& iStart) const -{ - if ((pszTokens == nullptr) || (*pszTokens == (XCHAR)0)) { - if (iStart < this->GetLength()) - return CMStringT(this->GetString() + iStart); - } - else { - PCXSTR pszPlace = this->GetString() + iStart; - PCXSTR pszEnd = this->GetString() + this->GetLength(); - if (pszPlace < pszEnd) { - int nIncluding = StringTraits::StringSpanIncluding(pszPlace, pszTokens); - - if ((pszPlace + nIncluding) < pszEnd) { - pszPlace += nIncluding; - int nExcluding = StringTraits::StringSpanExcluding(pszPlace, pszTokens); - - int iFrom = iStart + nIncluding; - int nUntil = nExcluding; - iStart = iFrom + nUntil + 1; - - return Mid(iFrom, nUntil); - } - } - } - - // return empty string, done tokenizing - iStart = -1; - - return CMStringT(); -} - -// find routines - -// Find the first occurrence of character 'ch', starting at index 'iStart' -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::Find(XCHAR ch, int iStart) const -{ - // nLength is in XCHARs - int nLength = this->GetLength(); - if (iStart < 0 || iStart >= nLength) - return -1; - - // find first single character - PCXSTR psz = StringTraits::StringFindChar(this->GetString() + iStart, ch); - - // return -1 if not found and index otherwise - return (psz == nullptr) ? -1 : int(psz - this->GetString()); -} - -// look for a specific sub-string - -// Find the first occurrence of string 'pszSub', starting at index 'iStart' -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::Find(PCXSTR pszSub, int iStart) const -{ - // iStart is in XCHARs - if (pszSub == nullptr) - return -1; - - // nLength is in XCHARs - int nLength = this->GetLength(); - if (iStart < 0 || iStart > nLength) - return -1; - - // find first matching substring - PCXSTR psz = StringTraits::StringFindString(this->GetString() + iStart, pszSub); - - // return -1 for not found, distance from beginning otherwise - return (psz == nullptr) ? -1 : int(psz - this->GetString()); -} - -// Find the first occurrence of any of the characters in string 'pszCharSet' -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::FindOneOf(PCXSTR pszCharSet) const -{ - PCXSTR psz = StringTraits::StringScanSet(this->GetString(), pszCharSet); - return (psz == nullptr) ? -1 : int(psz - this->GetString()); -} - -// Find the last occurrence of character 'ch' -template< typename BaseType, class StringTraits > -int CMStringT<BaseType, StringTraits>::ReverseFind(XCHAR ch) const -{ - // find last single character - PCXSTR psz = StringTraits::StringFindCharRev(this->GetString(), ch); - - // return -1 if not found, distance from beginning otherwise - return (psz == nullptr) ? -1 : int(psz - this->GetString()); -} - -// manipulation - -// Convert the string to uppercase -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::MakeUpper() -{ - int nLength = this->GetLength(); - PXSTR pszBuffer = this->GetBuffer(nLength); - StringTraits::StringUppercase(pszBuffer, nLength + 1); - this->ReleaseBufferSetLength(nLength); - - return *this; -} - -// Convert the string to lowercase -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::MakeLower() -{ - int nLength = this->GetLength(); - PXSTR pszBuffer = this->GetBuffer(nLength); - StringTraits::StringLowercase(pszBuffer, nLength + 1); - this->ReleaseBufferSetLength(nLength); - - return *this; -} - -// Reverse the string -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::MakeReverse() -{ - int nLength = this->GetLength(); - PXSTR pszBuffer = this->GetBuffer(nLength); - StringTraits::StringReverse(pszBuffer); - this->ReleaseBufferSetLength(nLength); - - return *this; -} - -// trimming - -// Remove all trailing whitespace -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::TrimRight() -{ - // find beginning of trailing spaces by starting - // at beginning (DBCS aware) - - PCXSTR psz = this->GetString(); - PCXSTR pszLast = nullptr; - - while (*psz != 0) { - if (StringTraits::IsSpace(*psz)) { - if (pszLast == nullptr) - pszLast = psz; - } - else pszLast = nullptr; - - psz = StringTraits::CharNext(psz); - } - - if (pszLast != nullptr) { - // truncate at trailing space start - int iLast = int(pszLast - this->GetString()); - - this->Truncate(iLast); - } - - return *this; -} - -// Remove all leading whitespace -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::TrimLeft() -{ - // find first non-space character - - PCXSTR psz = this->GetString(); - while (StringTraits::IsSpace(*psz)) - psz = StringTraits::CharNext(psz); - - if (psz != this->GetString()) { - // fix up data and length - int iFirst = int(psz - this->GetString()); - PXSTR pszBuffer = this->GetBuffer(this->GetLength()); - psz = pszBuffer + iFirst; - int nDataLength = this->GetLength() - iFirst; - memmove_s(pszBuffer, (this->GetLength() + 1)*sizeof(XCHAR), - psz, (nDataLength + 1)*sizeof(XCHAR)); - this->ReleaseBufferSetLength(nDataLength); - } - - return *this; -} - -// Remove all leading and trailing whitespace -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::Trim() -{ - return TrimRight().TrimLeft(); -} - -// Remove all leading and trailing occurrences of character 'chTarget' -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::Trim(XCHAR chTarget) -{ - return TrimRight(chTarget).TrimLeft(chTarget); -} - -// Remove all leading and trailing occurrences of any of the characters in the string 'pszTargets' -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::Trim(PCXSTR pszTargets) -{ - return TrimRight(pszTargets).TrimLeft(pszTargets); -} - -// trimming anything (either side) - -// Remove all trailing occurrences of character 'chTarget' -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::TrimRight(XCHAR chTarget) -{ - // find beginning of trailing matches - // by starting at beginning (DBCS aware) - - PCXSTR psz = this->GetString(); - PCXSTR pszLast = nullptr; - - while (*psz != 0) { - if (*psz == chTarget) { - if (pszLast == nullptr) - pszLast = psz; - } - else pszLast = nullptr; - - psz = StringTraits::CharNext(psz); - } - - if (pszLast != nullptr) { - // truncate at left-most matching character - int iLast = int(pszLast - this->GetString()); - this->Truncate(iLast); - } - - return *this; -} - -// Remove all trailing occurrences of any of the characters in string 'pszTargets' -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::TrimRight(PCXSTR pszTargets) -{ - // if we're not trimming anything, we're not doing any work - if ((pszTargets == nullptr) || (*pszTargets == 0)) { - return *this; - } - - // find beginning of trailing matches - // by starting at beginning (DBCS aware) - - PCXSTR psz = this->GetString(); - PCXSTR pszLast = nullptr; - - while (*psz != 0) { - if (StringTraits::StringFindChar(pszTargets, *psz) != nullptr) { - if (pszLast == nullptr) { - pszLast = psz; - } - } - else { - pszLast = nullptr; - } - psz = StringTraits::CharNext(psz); - } - - if (pszLast != nullptr) { - // truncate at left-most matching character - int iLast = int(pszLast - this->GetString()); - this->Truncate(iLast); - } - - return *this; -} - -// Remove all leading occurrences of character 'chTarget' -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::TrimLeft(XCHAR chTarget) -{ - // find first non-matching character - PCXSTR psz = this->GetString(); - - while (chTarget == *psz) { - psz = StringTraits::CharNext(psz); - } - - if (psz != this->GetString()) { - // fix up data and length - int iFirst = int(psz - this->GetString()); - PXSTR pszBuffer = this->GetBuffer(this->GetLength()); - psz = pszBuffer + iFirst; - int nDataLength = this->GetLength() - iFirst; - memmove_s(pszBuffer, (this->GetLength() + 1)*sizeof(XCHAR), - psz, (nDataLength + 1)*sizeof(XCHAR)); - this->ReleaseBufferSetLength(nDataLength); - } - - return *this; -} - -// Remove all leading occurrences of any of the characters in string 'pszTargets' -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::TrimLeft(PCXSTR pszTargets) -{ - // if we're not trimming anything, we're not doing any work - if ((pszTargets == nullptr) || (*pszTargets == 0)) { - return *this; - } - - PCXSTR psz = this->GetString(); - while ((*psz != 0) && (StringTraits::StringFindChar(pszTargets, *psz) != nullptr)) { - psz = StringTraits::CharNext(psz); - } - - if (psz != this->GetString()) { - // fix up data and length - int iFirst = int(psz - this->GetString()); - PXSTR pszBuffer = this->GetBuffer(this->GetLength()); - psz = pszBuffer + iFirst; - int nDataLength = this->GetLength() - iFirst; - memmove_s(pszBuffer, (this->GetLength() + 1)*sizeof(XCHAR), - psz, (nDataLength + 1)*sizeof(XCHAR)); - this->ReleaseBufferSetLength(nDataLength); - } - - return *this; -} - -// Convert the string to the OEM character set -template< typename BaseType, class StringTraits > -void CMStringT<BaseType, StringTraits>::AnsiToOem() -{ - int nLength = this->GetLength(); - PXSTR pszBuffer = this->GetBuffer(nLength); - StringTraits::ConvertToOem(pszBuffer, nLength + 1); - this->ReleaseBufferSetLength(nLength); -} - -// Convert the string to the ANSI character set -template< typename BaseType, class StringTraits > -void CMStringT<BaseType, StringTraits>::OemToAnsi() -{ - int nLength = this->GetLength(); - PXSTR pszBuffer = this->GetBuffer(nLength); - StringTraits::ConvertToAnsi(pszBuffer, nLength + 1); - this->ReleaseBufferSetLength(nLength); -} - -// Very simple sub-string extraction - -// Return the substring starting at index 'iFirst' -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::Mid(int iFirst) const -{ - return Mid(iFirst, this->GetLength() - iFirst); -} - -// Return the substring starting at index 'iFirst', with length 'nCount' -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::Mid(int iFirst, int nCount) const -{ - // nCount is in XCHARs - - // out-of-bounds requests return sensible things - if (iFirst < 0) - iFirst = 0; - if (nCount < 0) - nCount = 0; - - if ((iFirst + nCount) > this->GetLength()) - nCount = this->GetLength() - iFirst; - - if (iFirst > this->GetLength()) - nCount = 0; - - // optimize case of returning entire string - if ((iFirst == 0) && ((iFirst + nCount) == this->GetLength())) - return *this; - - return CMStringT(this->GetString() + iFirst, nCount); -} - -// Return the substring consisting of the rightmost 'nCount' characters -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::Right(int nCount) const -{ - // nCount is in XCHARs - if (nCount < 0) - nCount = 0; - - int nLength = this->GetLength(); - if (nCount >= nLength) - return *this; - - return CMStringT(this->GetString() + nLength - nCount, nCount); -} - -// Return the substring consisting of the leftmost 'nCount' characters -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::Left(int nCount) const -{ - // nCount is in XCHARs - if (nCount < 0) - nCount = 0; - - int nLength = this->GetLength(); - if (nCount >= nLength) - return *this; - - return CMStringT(this->GetString(), nCount); -} - -// Return the substring consisting of the leftmost characters in the set 'pszCharSet' -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::SpanIncluding(PCXSTR pszCharSet) const -{ - return Left(StringTraits::StringSpanIncluding(this->GetString(), pszCharSet)); -} - -// Return the substring consisting of the leftmost characters not in the set 'pszCharSet' -template< typename BaseType, class StringTraits > -CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::SpanExcluding(PCXSTR pszCharSet) const -{ - return Left(StringTraits::StringSpanExcluding(this->GetString(), pszCharSet)); -} - -// Format data using format string 'pszFormat' -template< typename BaseType, class StringTraits > -typename CMStringT<BaseType, StringTraits>::PCXSTR CMStringT<BaseType, StringTraits>::Format(PCXSTR pszFormat, ...) -{ - va_list argList; - va_start(argList, pszFormat); - FormatV(pszFormat, argList); - va_end(argList); - return this->GetString(); -} - -// Append formatted data using format string 'pszFormat' -template< typename BaseType, class StringTraits > -typename CMStringT<BaseType, StringTraits>::PCXSTR CMStringT<BaseType, StringTraits>::AppendFormat(PCXSTR pszFormat, ...) -{ - va_list argList; - va_start(argList, pszFormat); - AppendFormatV(pszFormat, argList); - va_end(argList); - return this->GetString(); -} - -template< typename BaseType, class StringTraits > -void CMStringT<BaseType, StringTraits>::AppendFormatV(PCXSTR pszFormat, va_list args) -{ - int nCurrentLength = this->GetLength(); - int nAppendLength = StringTraits::GetFormattedLength(pszFormat, args); - PXSTR pszBuffer = this->GetBuffer(nCurrentLength + nAppendLength); - StringTraits::Format(pszBuffer + nCurrentLength, nAppendLength + 1, pszFormat, args); - this->ReleaseBufferSetLength(nCurrentLength + nAppendLength); -} - -template< typename BaseType, class StringTraits > -typename CMStringT<BaseType, StringTraits>::PCXSTR CMStringT<BaseType, StringTraits>::FormatV(PCXSTR pszFormat, va_list args) -{ - int nLength = StringTraits::GetFormattedLength(pszFormat, args); - PXSTR pszBuffer = this->GetBuffer(nLength); - StringTraits::Format(pszBuffer, nLength + 1, pszFormat, args); - this->ReleaseBufferSetLength(nLength); - return this->GetString(); -} - -// Set the string to the value of environment variable 'pszVar' -template< typename BaseType, class StringTraits > -BOOL CMStringT<BaseType, StringTraits>::GetEnvironmentVariable(PCXSTR pszVar) -{ - int nLength = StringTraits::GetEnvironmentVariable(pszVar, nullptr, 0); - BOOL bRetVal = FALSE; - - if (nLength == 0) - this->Empty(); - else { - PXSTR pszBuffer = this->GetBuffer(nLength); - StringTraits::GetEnvironmentVariable(pszVar, pszBuffer, nLength); - this->ReleaseBuffer(); - bRetVal = TRUE; - } - - return bRetVal; -} - -// Set the string to the value of environment variable 'pszVar' -template< typename BaseType, class StringTraits > -typename CMStringT<BaseType, StringTraits>::PXSTR CMStringT<BaseType, StringTraits>::Detach() const -{ - return StringTraits::MirCopy(CMStringT<BaseType, StringTraits>::GetString(), this->GetLength()); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, const CMStringT<BaseType, StringTraits>& str2) -{ - CMStringT<BaseType, StringTraits> strResult; - CMStringT<BaseType, StringTraits>::Concatenate(strResult, str1, str1.GetLength(), str2, str2.GetLength()); - return strResult; -} - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, typename CMStringT<BaseType, StringTraits>::PCXSTR psz2) -{ - CMStringT<BaseType, StringTraits> strResult; - CMStringT<BaseType, StringTraits>::Concatenate(strResult, str1, str1.GetLength(), psz2, CMStringT<BaseType, StringTraits>::StringLength(psz2)); - return strResult; -} - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(typename CMStringT<BaseType, StringTraits>::PCXSTR psz1, const CMStringT<BaseType, StringTraits>& str2) -{ - CMStringT<BaseType, StringTraits> strResult; - CMStringT<BaseType, StringTraits>::Concatenate(strResult, psz1, CMStringT<BaseType, StringTraits>::StringLength(psz1), str2, str2.GetLength()); - return strResult; -} - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, wchar_t ch2) -{ - CMStringT<BaseType, StringTraits> strResult; - typename CMStringT<BaseType, StringTraits>::XCHAR chTemp = typename CMStringT<BaseType, StringTraits>::XCHAR(ch2); - CMStringT<BaseType, StringTraits>::Concatenate(strResult, str1, str1.GetLength(), &chTemp, 1); - return strResult; -} - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, char ch2) -{ - CMStringT<BaseType, StringTraits> strResult; - typename CMStringT<BaseType, StringTraits>::XCHAR chTemp = typename CMStringT<BaseType, StringTraits>::XCHAR(ch2); - CMStringT<BaseType, StringTraits>::Concatenate(strResult, str1, str1.GetLength(), &chTemp, 1); - return strResult; -} - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(wchar_t ch1, const CMStringT<BaseType, StringTraits>& str2) -{ - CMStringT<BaseType, StringTraits> strResult; - typename CMStringT<BaseType, StringTraits>::XCHAR chTemp = typename CMStringT<BaseType, StringTraits>::XCHAR(ch1); - CMStringT<BaseType, StringTraits>::Concatenate(strResult, &chTemp, 1, str2, str2.GetLength()); - return strResult; -} - -template< typename BaseType, class StringTraits > -MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(char ch1, const CMStringT<BaseType, StringTraits>& str2) -{ - CMStringT<BaseType, StringTraits> strResult; - typename CMStringT<BaseType, StringTraits>::XCHAR chTemp = typename CMStringT<BaseType, StringTraits>::XCHAR(ch1); - CMStringT<BaseType, StringTraits>::Concatenate(strResult, &chTemp, 1, str2, str2.GetLength()); - return strResult; -} - -#endif // M_STRING_INL__ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#pragma once
+
+#ifndef M_STRING_INL__
+
+#ifndef _MSC_VER
+ #include <algorithm>
+ #define __max std::max
+#endif
+
+template<typename BaseType>
+CMSimpleStringT<BaseType>::CMSimpleStringT()
+{
+ CMStringData* pData = mirstr_getNil();
+ Attach(pData);
+}
+
+template<typename BaseType>
+CMSimpleStringT<BaseType>::CMSimpleStringT(const CMSimpleStringT& strSrc)
+{
+ CMStringData* pSrcData = strSrc.GetData();
+ CMStringData* pNewData = CloneData(pSrcData);
+ Attach(pNewData);
+}
+
+template<typename BaseType>
+CMSimpleStringT<BaseType>::CMSimpleStringT(PCXSTR pszSrc)
+{
+ int nLength = StringLength(pszSrc);
+ CMStringData* pData = mirstr_allocate(nLength, sizeof(XCHAR));
+ if (pData != nullptr) {
+ Attach(pData);
+ SetLength(nLength);
+ CopyChars(m_pszData, nLength, pszSrc, nLength);
+ }
+}
+
+template<typename BaseType>
+CMSimpleStringT<BaseType>::CMSimpleStringT(const XCHAR* pchSrc, int nLength)
+{
+ CMStringData* pData = mirstr_allocate(nLength, sizeof(XCHAR));
+ if (pData != nullptr) {
+ Attach(pData);
+ SetLength(nLength);
+ CopyChars(m_pszData, nLength, pchSrc, nLength);
+ }
+}
+
+template<typename BaseType>
+CMSimpleStringT<BaseType>::~CMSimpleStringT()
+{
+ CMStringData* pData = GetData();
+ pData->Release();
+}
+
+template<typename BaseType>
+CMSimpleStringT<BaseType>& CMSimpleStringT<BaseType>::operator=(const CMSimpleStringT& strSrc)
+{
+ CMStringData* pSrcData = strSrc.GetData();
+ CMStringData* pOldData = GetData();
+ if (pSrcData != pOldData) {
+ if (pOldData->IsLocked())
+ SetString(strSrc.GetString(), strSrc.GetLength());
+ else {
+ CMStringData* pNewData = CloneData(pSrcData);
+ pOldData->Release();
+ Attach(pNewData);
+ }
+ }
+
+ return *this;
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::Append(PCXSTR pszSrc)
+{
+ Append(pszSrc, StringLength(pszSrc));
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::Append(PCXSTR pszSrc, int nLength)
+{
+ // See comment in SetString() about why we do this
+ UINT_PTR nOffset = UINT_PTR(pszSrc - GetString());
+
+ int nOldLength = GetLength();
+ if (nOldLength < 0) {
+ // protects from underflow
+ nOldLength = 0;
+ }
+
+ //Make sure we don't read pass end of the terminating NULL
+ int nSrcLength = StringLength(pszSrc);
+ nLength = nLength > nSrcLength ? nSrcLength : nLength;
+
+ int nNewLength = nOldLength + nLength;
+ PXSTR pszBuffer = GetBuffer(nNewLength);
+ if (nOffset <= UINT_PTR(nOldLength)) {
+ pszSrc = pszBuffer + nOffset;
+ // No need to call CopyCharsOverlapped, since the destination is
+ // beyond the end of the original buffer
+ }
+ CopyChars(pszBuffer + nOldLength, nLength, pszSrc, nLength);
+ ReleaseBufferSetLength(nNewLength);
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::AppendChar(XCHAR ch)
+{
+ UINT nOldLength = GetLength();
+ int nNewLength = nOldLength + 1;
+ PXSTR pszBuffer = GetBuffer(nNewLength);
+ pszBuffer[nOldLength] = ch;
+ ReleaseBufferSetLength(nNewLength);
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::Append(const CMSimpleStringT<BaseType>& strSrc)
+{
+ Append(strSrc.GetString(), strSrc.GetLength());
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::Empty()
+{
+ CMStringData* pOldData = GetData();
+ if (pOldData->nDataLength == 0)
+ return;
+
+ if (pOldData->IsLocked()) {
+ // Don't reallocate a locked buffer that's shrinking
+ SetLength(0);
+ }
+ else {
+ pOldData->Release();
+ CMStringData* pNewData = mirstr_getNil();
+ Attach(pNewData);
+ }
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::FreeExtra()
+{
+ CMStringData* pOldData = GetData();
+ int nLength = pOldData->nDataLength;
+ if (pOldData->nAllocLength == nLength)
+ return;
+
+ if (!pOldData->IsLocked()) { // Don't reallocate a locked buffer that's shrinking
+ CMStringData* pNewData = mirstr_allocate(nLength, sizeof(XCHAR));
+ if (pNewData == nullptr) {
+ SetLength(nLength);
+ return;
+ }
+
+ CopyChars(PXSTR(pNewData->data()), nLength, PCXSTR(pOldData->data()), nLength);
+
+ pOldData->Release();
+ Attach(pNewData);
+ SetLength(nLength);
+ }
+}
+
+template<typename BaseType>
+typename CMSimpleStringT<BaseType>::PXSTR CMSimpleStringT<BaseType>::GetBuffer()
+{
+ CMStringData* pData = GetData();
+ if (pData->IsShared())
+ Fork(pData->nDataLength);
+
+ return m_pszData;
+}
+
+template<typename BaseType>
+typename CMSimpleStringT<BaseType>::PXSTR CMSimpleStringT<BaseType>::GetBufferSetLength(int nLength)
+{
+ PXSTR pszBuffer = GetBuffer(nLength);
+ SetLength(nLength);
+
+ return pszBuffer;
+}
+
+template<typename BaseType>
+typename CMSimpleStringT<BaseType>::PXSTR CMSimpleStringT<BaseType>::LockBuffer()
+{
+ CMStringData* pData = GetData();
+ if (pData->IsShared()) {
+ Fork(pData->nDataLength);
+ pData = GetData(); // Do it again, because the fork might have changed it
+ }
+ pData->Lock();
+
+ return m_pszData;
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::UnlockBuffer()
+{
+ CMStringData* pData = GetData();
+ pData->Unlock();
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::ReleaseBuffer(int nNewLength)
+{
+ if (nNewLength == -1) {
+ int nAlloc = GetData()->nAllocLength;
+ nNewLength = StringLengthN(m_pszData, nAlloc);
+ }
+ SetLength(nNewLength);
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::Truncate(int nNewLength)
+{
+ GetBuffer(nNewLength);
+ ReleaseBufferSetLength(nNewLength);
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::SetAt(int iChar, XCHAR ch)
+{
+ int nLength = GetLength();
+ PXSTR pszBuffer = GetBuffer();
+ pszBuffer[iChar] = ch;
+ ReleaseBufferSetLength(nLength);
+
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::SetString(PCXSTR pszSrc)
+{
+ SetString(pszSrc, StringLength(pszSrc));
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::SetString(PCXSTR pszSrc, int nLength)
+{
+ if (nLength == 0)
+ Empty();
+ else {
+ UINT nOldLength = GetLength();
+ UINT_PTR nOffset = pszSrc - GetString();
+
+ PXSTR pszBuffer = GetBuffer(nLength);
+ if (nOffset <= nOldLength)
+ CopyCharsOverlapped(pszBuffer, GetAllocLength(), pszBuffer + nOffset, nLength);
+ else
+ CopyChars(pszBuffer, GetAllocLength(), pszSrc, nLength);
+
+ ReleaseBufferSetLength(nLength);
+ }
+}
+
+template<typename BaseType>
+class CMSimpleStringT<BaseType> operator+(const CMSimpleStringT<BaseType>& str1, const CMSimpleStringT<BaseType>& str2)
+{
+ CMSimpleStringT<BaseType> s;
+ Concatenate(s, str1, str1.GetLength(), str2, str2.GetLength());
+ return s;
+}
+
+template<typename BaseType>
+class CMSimpleStringT<BaseType> operator+(const CMSimpleStringT<BaseType>& str1, typename CMSimpleStringT<BaseType>::PCXSTR psz2)
+{
+ CMSimpleStringT<BaseType> s;
+ Concatenate(s, str1, str1.GetLength(), psz2, StringLength(psz2));
+ return s;
+}
+
+template<typename BaseType>
+CMSimpleStringT<BaseType> operator+(typename CMSimpleStringT<BaseType>::PCXSTR psz1, const CMSimpleStringT<BaseType>& str2)
+{
+ CMSimpleStringT<BaseType> s;
+ Concatenate(s, psz1, StringLength(psz1), str2, str2.GetLength());
+ return s;
+}
+
+template<typename BaseType>
+void MIR_SYSCALL CMSimpleStringT<BaseType>::CopyChars(XCHAR* pchDest, const XCHAR* pchSrc, int nChars)
+{
+ #pragma warning (push)
+ #pragma warning(disable : 4996)
+ memcpy(pchDest, pchSrc, nChars * sizeof(XCHAR));
+ #pragma warning (pop)
+}
+
+template<typename BaseType>
+void MIR_SYSCALL CMSimpleStringT<BaseType>::CopyChars(XCHAR* pchDest, size_t nDestLen, const XCHAR* pchSrc, int nChars)
+{
+ memcpy_s(pchDest, nDestLen * sizeof(XCHAR), pchSrc, nChars * sizeof(XCHAR));
+}
+
+template<typename BaseType>
+void MIR_SYSCALL CMSimpleStringT<BaseType>::CopyCharsOverlapped(XCHAR* pchDest, const XCHAR* pchSrc, int nChars)
+{
+ #pragma warning (push)
+ #pragma warning(disable : 4996)
+ memmove(pchDest, pchSrc, nChars * sizeof(XCHAR));
+ #pragma warning (pop)
+}
+
+template<typename BaseType>
+void MIR_SYSCALL CMSimpleStringT<BaseType>::CopyCharsOverlapped(XCHAR* pchDest, size_t nDestLen, const XCHAR* pchSrc, int nChars)
+{
+ memmove_s(pchDest, nDestLen * sizeof(XCHAR), pchSrc, nChars * sizeof(XCHAR));
+}
+
+template<typename BaseType>
+int MIR_SYSCALL CMSimpleStringT<BaseType>::StringLength(const char* psz)
+{
+ if (psz == nullptr)
+ return(0);
+
+ return (int(strlen(psz)));
+}
+
+template<typename BaseType>
+int MIR_SYSCALL CMSimpleStringT<BaseType>::StringLength(const wchar_t* psz)
+{
+ if (psz == nullptr)
+ return 0;
+
+ return int(wcslen(psz));
+}
+
+template<typename BaseType>
+int MIR_SYSCALL CMSimpleStringT<BaseType>::StringLengthN(const char* psz, size_t sizeInXChar)
+{
+ if (psz == nullptr)
+ return 0;
+
+ return int(strnlen(psz, sizeInXChar));
+}
+
+template<typename BaseType>
+int MIR_SYSCALL CMSimpleStringT<BaseType>::StringLengthN(const wchar_t* psz, size_t sizeInXChar)
+{
+ if (psz == nullptr)
+ return 0;
+
+ return int(wcsnlen(psz, sizeInXChar));
+}
+
+template<typename BaseType>
+void MIR_SYSCALL CMSimpleStringT<BaseType>::Concatenate(CMSimpleStringT<BaseType>& strResult, PCXSTR psz1, int nLength1, PCXSTR psz2, int nLength2)
+{
+ int nNewLength = nLength1 + nLength2;
+ PXSTR pszBuffer = strResult.GetBuffer(nNewLength);
+ CopyChars(pszBuffer, nLength1, psz1, nLength1);
+ CopyChars(pszBuffer + nLength1, nLength2, psz2, nLength2);
+ strResult.ReleaseBufferSetLength(nNewLength);
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::Attach(CMStringData* pData)
+{
+ m_pszData = static_cast<PXSTR>(pData->data());
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::Fork(int nLength)
+{
+ CMStringData* pOldData = GetData();
+ int nOldLength = pOldData->nDataLength;
+ CMStringData* pNewData = mirstr_allocate(nLength, sizeof(XCHAR));
+ if (pNewData != nullptr) {
+ int nCharsToCopy = ((nOldLength < nLength) ? nOldLength : nLength) + 1; // Copy '\0'
+ CopyChars(PXSTR(pNewData->data()), nCharsToCopy, PCXSTR(pOldData->data()), nCharsToCopy);
+ pNewData->nDataLength = nOldLength;
+ pOldData->Release();
+ Attach(pNewData);
+ }
+}
+
+template<typename BaseType>
+typename CMSimpleStringT<BaseType>::PXSTR CMSimpleStringT<BaseType>::PrepareWrite(int nLength)
+{
+ CMStringData* pOldData = GetData();
+ int nShared = 1 - pOldData->nRefs; // nShared < 0 means true, >= 0 means false
+ int nTooShort = pOldData->nAllocLength - nLength; // nTooShort < 0 means true, >= 0 means false
+ if ((nShared | nTooShort) < 0) // If either sign bit is set (i.e. either is less than zero), we need to copy data
+ PrepareWrite2(nLength);
+
+ return m_pszData;
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::PrepareWrite2(int nLength)
+{
+ CMStringData* pOldData = GetData();
+ if (pOldData->nDataLength > nLength)
+ nLength = pOldData->nDataLength;
+
+ if (pOldData->IsShared()) {
+ Fork(nLength);
+ }
+ else if (pOldData->nAllocLength < nLength) {
+ // Grow exponentially, until we hit 1K.
+ int nNewLength = pOldData->nAllocLength;
+ if (nNewLength > 1024)
+ nNewLength += 1024;
+ else
+ nNewLength *= 2;
+
+ if (nNewLength < nLength)
+ nNewLength = nLength;
+
+ Reallocate(nNewLength);
+ }
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::Reallocate(int nLength)
+{
+ CMStringData* pOldData = GetData();
+ if (pOldData->nAllocLength >= nLength || nLength <= 0)
+ return;
+
+ CMStringData* pNewData = mirstr_realloc(pOldData, nLength, sizeof(XCHAR));
+ if (pNewData != nullptr)
+ Attach(pNewData);
+}
+
+template<typename BaseType>
+void CMSimpleStringT<BaseType>::SetLength(int nLength)
+{
+ GetData()->nDataLength = nLength;
+ m_pszData[nLength] = 0;
+}
+
+template<typename BaseType>
+CMStringData* MIR_SYSCALL CMSimpleStringT<BaseType>::CloneData(CMStringData* pData)
+{
+ CMStringData* pNewData = nullptr;
+
+ if (!pData->IsLocked()) {
+ pNewData = pData;
+ pNewData->AddRef();
+ }
+
+ return pNewData;
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>::CMStringT() :
+ CThisSimpleString()
+{
+}
+
+// Copy constructor
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>::CMStringT(const CMStringT<BaseType, StringTraits>& strSrc) :
+ CThisSimpleString(strSrc)
+{
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>::CMStringT(const XCHAR* pszSrc) :
+ CThisSimpleString()
+{
+ *this = pszSrc;
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>::CMStringT(CMStringDataFormat, const XCHAR* pszFormat, ...) :
+ CThisSimpleString()
+{
+ va_list args;
+ va_start(args, pszFormat);
+ FormatV(pszFormat, args);
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>::CMStringT(const YCHAR* pszSrc) :
+ CThisSimpleString()
+{
+ *this = pszSrc;
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>::CMStringT(const unsigned char* pszSrc) :
+ CThisSimpleString()
+{
+ *this = reinterpret_cast<const char*>(pszSrc);
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>::CMStringT(char ch, int nLength) :
+ CThisSimpleString()
+{
+ if (nLength > 0) {
+ PXSTR pszBuffer = this->GetBuffer(nLength);
+ StringTraits::FloodCharacters(XCHAR(ch), nLength, pszBuffer);
+ this->ReleaseBufferSetLength(nLength);
+ }
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>::CMStringT(wchar_t ch, int nLength) :
+ CThisSimpleString()
+{
+ if (nLength > 0) {
+ //Convert ch to the BaseType
+ wchar_t pszCh[2] = { ch, 0 };
+ int nBaseTypeCharLen = 1;
+
+ if (ch != L'\0')
+ nBaseTypeCharLen = StringTraits::GetBaseTypeLength(pszCh);
+
+ XCHAR *buffBaseTypeChar = new XCHAR[nBaseTypeCharLen + 1];
+ StringTraits::ConvertToBaseType(buffBaseTypeChar, nBaseTypeCharLen + 1, pszCh, 1);
+ //allocate enough characters in String and flood (replicate) with the (converted character)*nLength
+ PXSTR pszBuffer = this->GetBuffer(nLength*nBaseTypeCharLen);
+ if (nBaseTypeCharLen == 1) //Optimization for a common case - wide char translates to 1 ansi/wide char.
+ StringTraits::FloodCharacters(buffBaseTypeChar[0], nLength, pszBuffer);
+ else {
+ XCHAR* p = pszBuffer;
+ for (int i = 0; i < nLength; i++) {
+ for (int j = 0; j < nBaseTypeCharLen; ++j) {
+ *p = buffBaseTypeChar[j];
+ ++p;
+ }
+ }
+ }
+ this->ReleaseBufferSetLength(nLength*nBaseTypeCharLen);
+ delete[] buffBaseTypeChar;
+ }
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>::CMStringT(const XCHAR* pch, int nLength) :
+ CThisSimpleString(pch, nLength)
+{
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>::CMStringT(const YCHAR* pch, int nLength) :
+ CThisSimpleString()
+{
+ if (nLength > 0) {
+ int nDestLength = StringTraits::GetBaseTypeLength(pch, nLength);
+ PXSTR pszBuffer = this->GetBuffer(nDestLength);
+ StringTraits::ConvertToBaseType(pszBuffer, nDestLength, pch, nLength);
+ this->ReleaseBufferSetLength(nDestLength);
+ }
+}
+
+// Destructor
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>::~CMStringT()
+{
+}
+
+// Assignment operators
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator=(const CMStringT& strSrc)
+{
+ CThisSimpleString::operator=(strSrc);
+ return *this;
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator=(PCXSTR pszSrc)
+{
+ CThisSimpleString::operator=(pszSrc);
+ return *this;
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator=(PCYSTR pszSrc)
+{
+ // nDestLength is in XCHARs
+ int nDestLength = (pszSrc != nullptr) ? StringTraits::GetBaseTypeLength(pszSrc) : 0;
+ if (nDestLength > 0) {
+ PXSTR pszBuffer = this->GetBuffer(nDestLength);
+ StringTraits::ConvertToBaseType(pszBuffer, nDestLength, pszSrc);
+ this->ReleaseBufferSetLength(nDestLength);
+ }
+ else this->Empty();
+
+ return *this;
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator=(const unsigned char* pszSrc)
+{
+ return operator=(reinterpret_cast<const char*>(pszSrc));
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator=(char ch)
+{
+ char ach[2] = { ch, 0 };
+ return operator=(ach);
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator=(wchar_t ch)
+{
+ wchar_t ach[2] = { ch, 0 };
+ return operator=(ach);
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(const CMStringT& str)
+{
+ CThisSimpleString::operator+=(str);
+ return *this;
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(const CThisSimpleString& str)
+{
+ CThisSimpleString::operator+=(str);
+ return *this;
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(PCXSTR pszSrc)
+{
+ CThisSimpleString::operator+=(pszSrc);
+ return *this;
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(PCYSTR pszSrc)
+{
+ CMStringT str(pszSrc);
+ return operator+=(str);
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(char ch)
+{
+ CThisSimpleString::operator+=(ch);
+ return *this;
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(unsigned char ch)
+{
+ CThisSimpleString::operator+=(ch);
+ return *this;
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::operator+=(wchar_t ch)
+{
+ CThisSimpleString::operator+=(ch);
+ return *this;
+}
+
+// Comparison
+
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::Compare(PCXSTR psz) const
+{
+ return StringTraits::StringCompare(this->GetString(), psz);
+}
+
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::CompareNoCase(PCXSTR psz) const
+{
+ return StringTraits::StringCompareIgnore(this->GetString(), psz);
+}
+
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::Collate(PCXSTR psz) const
+{
+ return StringTraits::StringCollate(this->GetString(), psz);
+}
+
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::CollateNoCase(PCXSTR psz) const
+{
+ return StringTraits::StringCollateIgnore(this->GetString(), psz);
+}
+
+// Advanced manipulation
+
+// Delete 'nCount' characters, starting at index 'iIndex'
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::Delete(int iIndex, int nCount)
+{
+ if (iIndex < 0)
+ iIndex = 0;
+
+ if (nCount < 0)
+ nCount = 0;
+
+ int nLength = this->GetLength();
+ if (nCount + iIndex > nLength)
+ nCount = nLength - iIndex;
+
+ if (nCount > 0) {
+ int nNewLength = nLength - nCount;
+ int nXCHARsToCopy = nLength - (iIndex + nCount) + 1;
+ PXSTR pszBuffer = this->GetBuffer();
+#if _MSC_VER >= 1400
+ memmove_s(pszBuffer + iIndex, nXCHARsToCopy*sizeof(XCHAR), pszBuffer + iIndex + nCount, nXCHARsToCopy*sizeof(XCHAR));
+#else
+ memmove(pszBuffer+iIndex, pszBuffer+iIndex+nCount, nXCHARsToCopy*sizeof(XCHAR));
+#endif
+ this->ReleaseBufferSetLength(nNewLength);
+ }
+
+ return this->GetLength();
+}
+
+// Insert character 'ch' before index 'iIndex'
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::Insert(int iIndex, XCHAR ch)
+{
+ if (iIndex < 0)
+ iIndex = 0;
+
+ if (iIndex > this->GetLength())
+ iIndex = this->GetLength();
+
+ int nNewLength = this->GetLength() + 1;
+
+ PXSTR pszBuffer = this->GetBuffer(nNewLength);
+
+ // move existing bytes down
+#if _MSC_VER >= 1400
+ memmove_s(pszBuffer + iIndex + 1, (nNewLength - iIndex)*sizeof(XCHAR), pszBuffer + iIndex, (nNewLength - iIndex)*sizeof(XCHAR));
+#else
+ memmove(pszBuffer+iIndex+1, pszBuffer+iIndex, (nNewLength-iIndex)*sizeof(XCHAR));
+#endif
+ pszBuffer[iIndex] = ch;
+
+ this->ReleaseBufferSetLength(nNewLength);
+ return nNewLength;
+}
+
+// Insert string 'psz' before index 'iIndex'
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::Insert(int iIndex, PCXSTR psz)
+{
+ if (iIndex < 0)
+ iIndex = 0;
+
+ if (iIndex > this->GetLength())
+ iIndex = this->GetLength();
+
+ // nInsertLength and nNewLength are in XCHARs
+ int nInsertLength = StringTraits::SafeStringLen(psz);
+ int nNewLength = this->GetLength();
+ if (nInsertLength > 0) {
+ nNewLength += nInsertLength;
+
+ PXSTR pszBuffer = this->GetBuffer(nNewLength);
+ // move existing bytes down
+#if _MSC_VER >= 1400
+ memmove_s(pszBuffer + iIndex + nInsertLength, (nNewLength - iIndex - nInsertLength + 1)*sizeof(XCHAR), pszBuffer + iIndex, (nNewLength - iIndex - nInsertLength + 1)*sizeof(XCHAR));
+ memcpy_s(pszBuffer + iIndex, nInsertLength*sizeof(XCHAR), psz, nInsertLength*sizeof(XCHAR));
+#else
+ memmove(pszBuffer+iIndex+nInsertLength, pszBuffer+iIndex, (nNewLength-iIndex-nInsertLength+1)*sizeof(XCHAR));
+ memcpy(pszBuffer+iIndex, psz, nInsertLength*sizeof(XCHAR));
+#endif
+ this->ReleaseBufferSetLength(nNewLength);
+ }
+
+ return nNewLength;
+}
+
+// Replace all occurrences of character 'chOld' with character 'chNew'
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::Replace(XCHAR chOld, XCHAR chNew)
+{
+ int nCount = 0;
+
+ // short-circuit the nop case
+ if (chOld != chNew) {
+ // otherwise modify each character that matches in the string
+ bool bCopied = false;
+ PXSTR pszBuffer = const_cast<PXSTR>(this->GetString()); // We don't actually write to pszBuffer until we've called GetBuffer().
+
+ int nLength = this->GetLength();
+ int iChar = 0;
+ while (iChar < nLength) {
+ // replace instances of the specified character only
+ if (pszBuffer[iChar] == chOld) {
+ if (!bCopied) {
+ bCopied = true;
+ pszBuffer = this->GetBuffer(nLength);
+ }
+ pszBuffer[iChar] = chNew;
+ nCount++;
+ }
+ iChar = int(StringTraits::CharNext(pszBuffer + iChar) - pszBuffer);
+ }
+
+ if (bCopied)
+ this->ReleaseBufferSetLength(nLength);
+ }
+
+ return nCount;
+}
+
+// Replace all occurrences of string 'pszOld' with string 'pszNew'
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::Replace(PCXSTR pszOld, PCXSTR pszNew)
+{
+ // can't have empty or NULL lpszOld
+
+ // nSourceLen is in XCHARs
+ int nSourceLen = StringTraits::SafeStringLen(pszOld);
+ if (nSourceLen == 0)
+ return 0;
+ // nReplacementLen is in XCHARs
+ int nReplacementLen = StringTraits::SafeStringLen(pszNew);
+
+ // loop once to figure out the size of the result string
+ int nCount = 0;
+ {
+ PCXSTR pszStart = this->GetString();
+ PCXSTR pszEnd = pszStart + this->GetLength();
+ while (pszStart < pszEnd) {
+ PCXSTR pszTarget;
+ while ((pszTarget = StringTraits::StringFindString(pszStart, pszOld)) != nullptr) {
+ nCount++;
+ pszStart = pszTarget + nSourceLen;
+ }
+ pszStart += StringTraits::SafeStringLen(pszStart) + 1;
+ }
+ }
+
+ // if any changes were made, make them
+ if (nCount > 0) {
+ // if the buffer is too small, just
+ // allocate a new buffer (slow but sure)
+ int nOldLength = this->GetLength();
+ int nNewLength = nOldLength + (nReplacementLen - nSourceLen)*nCount;
+
+ PXSTR pszBuffer = this->GetBuffer(__max(nNewLength, nOldLength));
+
+ PXSTR pszStart = pszBuffer;
+ PXSTR pszEnd = pszStart + nOldLength;
+
+ // loop again to actually do the work
+ while (pszStart < pszEnd) {
+ PXSTR pszTarget;
+ while ((pszTarget = StringTraits::StringFindString(pszStart, pszOld)) != nullptr) {
+ int nBalance = nOldLength - int(pszTarget - pszBuffer + nSourceLen);
+ memmove_s(pszTarget + nReplacementLen, nBalance*sizeof(XCHAR),
+ pszTarget + nSourceLen, nBalance*sizeof(XCHAR));
+ memcpy_s(pszTarget, nReplacementLen*sizeof(XCHAR),
+ pszNew, nReplacementLen*sizeof(XCHAR));
+ pszStart = pszTarget + nReplacementLen;
+ pszTarget[nReplacementLen + nBalance] = 0;
+ nOldLength += (nReplacementLen - nSourceLen);
+ }
+ pszStart += StringTraits::SafeStringLen(pszStart) + 1;
+ }
+ this->ReleaseBufferSetLength(nNewLength);
+ }
+
+ return nCount;
+}
+
+// Remove all occurrences of character 'chRemove'
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::Remove(XCHAR chRemove)
+{
+ int nLength = this->GetLength();
+ PXSTR pszBuffer = this->GetBuffer(nLength);
+
+ PXSTR pszSource = pszBuffer;
+ PXSTR pszDest = pszBuffer;
+ PXSTR pszEnd = pszBuffer + nLength;
+
+ while (pszSource < pszEnd) {
+ PXSTR pszNewSource = StringTraits::CharNext(pszSource);
+ if (*pszSource != chRemove) {
+ // Copy the source to the destination. Remember to copy all bytes of an MBCS character
+ size_t NewSourceGap = (pszNewSource - pszSource);
+ PXSTR pszNewDest = pszDest + NewSourceGap;
+ for (size_t i = 0; pszDest != pszNewDest && i < NewSourceGap; i++) {
+ *pszDest = *pszSource;
+ pszSource++;
+ pszDest++;
+ }
+ }
+ pszSource = pszNewSource;
+ }
+ *pszDest = 0;
+ int nCount = int(pszSource - pszDest);
+ this->ReleaseBufferSetLength(nLength - nCount);
+
+ return nCount;
+}
+
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::Tokenize(PCXSTR pszTokens, int& iStart) const
+{
+ if ((pszTokens == nullptr) || (*pszTokens == (XCHAR)0)) {
+ if (iStart < this->GetLength())
+ return CMStringT(this->GetString() + iStart);
+ }
+ else {
+ PCXSTR pszPlace = this->GetString() + iStart;
+ PCXSTR pszEnd = this->GetString() + this->GetLength();
+ if (pszPlace < pszEnd) {
+ int nIncluding = StringTraits::StringSpanIncluding(pszPlace, pszTokens);
+
+ if ((pszPlace + nIncluding) < pszEnd) {
+ pszPlace += nIncluding;
+ int nExcluding = StringTraits::StringSpanExcluding(pszPlace, pszTokens);
+
+ int iFrom = iStart + nIncluding;
+ int nUntil = nExcluding;
+ iStart = iFrom + nUntil + 1;
+
+ return Mid(iFrom, nUntil);
+ }
+ }
+ }
+
+ // return empty string, done tokenizing
+ iStart = -1;
+
+ return CMStringT();
+}
+
+// find routines
+
+// Find the first occurrence of character 'ch', starting at index 'iStart'
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::Find(XCHAR ch, int iStart) const
+{
+ // nLength is in XCHARs
+ int nLength = this->GetLength();
+ if (iStart < 0 || iStart >= nLength)
+ return -1;
+
+ // find first single character
+ PCXSTR psz = StringTraits::StringFindChar(this->GetString() + iStart, ch);
+
+ // return -1 if not found and index otherwise
+ return (psz == nullptr) ? -1 : int(psz - this->GetString());
+}
+
+// look for a specific sub-string
+
+// Find the first occurrence of string 'pszSub', starting at index 'iStart'
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::Find(PCXSTR pszSub, int iStart) const
+{
+ // iStart is in XCHARs
+ if (pszSub == nullptr)
+ return -1;
+
+ // nLength is in XCHARs
+ int nLength = this->GetLength();
+ if (iStart < 0 || iStart > nLength)
+ return -1;
+
+ // find first matching substring
+ PCXSTR psz = StringTraits::StringFindString(this->GetString() + iStart, pszSub);
+
+ // return -1 for not found, distance from beginning otherwise
+ return (psz == nullptr) ? -1 : int(psz - this->GetString());
+}
+
+// Find the first occurrence of any of the characters in string 'pszCharSet'
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::FindOneOf(PCXSTR pszCharSet) const
+{
+ PCXSTR psz = StringTraits::StringScanSet(this->GetString(), pszCharSet);
+ return (psz == nullptr) ? -1 : int(psz - this->GetString());
+}
+
+// Find the last occurrence of character 'ch'
+template< typename BaseType, class StringTraits >
+int CMStringT<BaseType, StringTraits>::ReverseFind(XCHAR ch) const
+{
+ // find last single character
+ PCXSTR psz = StringTraits::StringFindCharRev(this->GetString(), ch);
+
+ // return -1 if not found, distance from beginning otherwise
+ return (psz == nullptr) ? -1 : int(psz - this->GetString());
+}
+
+// manipulation
+
+// Convert the string to uppercase
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::MakeUpper()
+{
+ int nLength = this->GetLength();
+ PXSTR pszBuffer = this->GetBuffer(nLength);
+ StringTraits::StringUppercase(pszBuffer, nLength + 1);
+ this->ReleaseBufferSetLength(nLength);
+
+ return *this;
+}
+
+// Convert the string to lowercase
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::MakeLower()
+{
+ int nLength = this->GetLength();
+ PXSTR pszBuffer = this->GetBuffer(nLength);
+ StringTraits::StringLowercase(pszBuffer, nLength + 1);
+ this->ReleaseBufferSetLength(nLength);
+
+ return *this;
+}
+
+// Reverse the string
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::MakeReverse()
+{
+ int nLength = this->GetLength();
+ PXSTR pszBuffer = this->GetBuffer(nLength);
+ StringTraits::StringReverse(pszBuffer);
+ this->ReleaseBufferSetLength(nLength);
+
+ return *this;
+}
+
+// trimming
+
+// Remove all trailing whitespace
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::TrimRight()
+{
+ // find beginning of trailing spaces by starting
+ // at beginning (DBCS aware)
+
+ PCXSTR psz = this->GetString();
+ PCXSTR pszLast = nullptr;
+
+ while (*psz != 0) {
+ if (StringTraits::IsSpace(*psz)) {
+ if (pszLast == nullptr)
+ pszLast = psz;
+ }
+ else pszLast = nullptr;
+
+ psz = StringTraits::CharNext(psz);
+ }
+
+ if (pszLast != nullptr) {
+ // truncate at trailing space start
+ int iLast = int(pszLast - this->GetString());
+
+ this->Truncate(iLast);
+ }
+
+ return *this;
+}
+
+// Remove all leading whitespace
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::TrimLeft()
+{
+ // find first non-space character
+
+ PCXSTR psz = this->GetString();
+ while (StringTraits::IsSpace(*psz))
+ psz = StringTraits::CharNext(psz);
+
+ if (psz != this->GetString()) {
+ // fix up data and length
+ int iFirst = int(psz - this->GetString());
+ PXSTR pszBuffer = this->GetBuffer(this->GetLength());
+ psz = pszBuffer + iFirst;
+ int nDataLength = this->GetLength() - iFirst;
+ memmove_s(pszBuffer, (this->GetLength() + 1)*sizeof(XCHAR),
+ psz, (nDataLength + 1)*sizeof(XCHAR));
+ this->ReleaseBufferSetLength(nDataLength);
+ }
+
+ return *this;
+}
+
+// Remove all leading and trailing whitespace
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::Trim()
+{
+ return TrimRight().TrimLeft();
+}
+
+// Remove all leading and trailing occurrences of character 'chTarget'
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::Trim(XCHAR chTarget)
+{
+ return TrimRight(chTarget).TrimLeft(chTarget);
+}
+
+// Remove all leading and trailing occurrences of any of the characters in the string 'pszTargets'
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::Trim(PCXSTR pszTargets)
+{
+ return TrimRight(pszTargets).TrimLeft(pszTargets);
+}
+
+// trimming anything (either side)
+
+// Remove all trailing occurrences of character 'chTarget'
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::TrimRight(XCHAR chTarget)
+{
+ // find beginning of trailing matches
+ // by starting at beginning (DBCS aware)
+
+ PCXSTR psz = this->GetString();
+ PCXSTR pszLast = nullptr;
+
+ while (*psz != 0) {
+ if (*psz == chTarget) {
+ if (pszLast == nullptr)
+ pszLast = psz;
+ }
+ else pszLast = nullptr;
+
+ psz = StringTraits::CharNext(psz);
+ }
+
+ if (pszLast != nullptr) {
+ // truncate at left-most matching character
+ int iLast = int(pszLast - this->GetString());
+ this->Truncate(iLast);
+ }
+
+ return *this;
+}
+
+// Remove all trailing occurrences of any of the characters in string 'pszTargets'
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::TrimRight(PCXSTR pszTargets)
+{
+ // if we're not trimming anything, we're not doing any work
+ if ((pszTargets == nullptr) || (*pszTargets == 0)) {
+ return *this;
+ }
+
+ // find beginning of trailing matches
+ // by starting at beginning (DBCS aware)
+
+ PCXSTR psz = this->GetString();
+ PCXSTR pszLast = nullptr;
+
+ while (*psz != 0) {
+ if (StringTraits::StringFindChar(pszTargets, *psz) != nullptr) {
+ if (pszLast == nullptr) {
+ pszLast = psz;
+ }
+ }
+ else {
+ pszLast = nullptr;
+ }
+ psz = StringTraits::CharNext(psz);
+ }
+
+ if (pszLast != nullptr) {
+ // truncate at left-most matching character
+ int iLast = int(pszLast - this->GetString());
+ this->Truncate(iLast);
+ }
+
+ return *this;
+}
+
+// Remove all leading occurrences of character 'chTarget'
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::TrimLeft(XCHAR chTarget)
+{
+ // find first non-matching character
+ PCXSTR psz = this->GetString();
+
+ while (chTarget == *psz) {
+ psz = StringTraits::CharNext(psz);
+ }
+
+ if (psz != this->GetString()) {
+ // fix up data and length
+ int iFirst = int(psz - this->GetString());
+ PXSTR pszBuffer = this->GetBuffer(this->GetLength());
+ psz = pszBuffer + iFirst;
+ int nDataLength = this->GetLength() - iFirst;
+ memmove_s(pszBuffer, (this->GetLength() + 1)*sizeof(XCHAR),
+ psz, (nDataLength + 1)*sizeof(XCHAR));
+ this->ReleaseBufferSetLength(nDataLength);
+ }
+
+ return *this;
+}
+
+// Remove all leading occurrences of any of the characters in string 'pszTargets'
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits>& CMStringT<BaseType, StringTraits>::TrimLeft(PCXSTR pszTargets)
+{
+ // if we're not trimming anything, we're not doing any work
+ if ((pszTargets == nullptr) || (*pszTargets == 0)) {
+ return *this;
+ }
+
+ PCXSTR psz = this->GetString();
+ while ((*psz != 0) && (StringTraits::StringFindChar(pszTargets, *psz) != nullptr)) {
+ psz = StringTraits::CharNext(psz);
+ }
+
+ if (psz != this->GetString()) {
+ // fix up data and length
+ int iFirst = int(psz - this->GetString());
+ PXSTR pszBuffer = this->GetBuffer(this->GetLength());
+ psz = pszBuffer + iFirst;
+ int nDataLength = this->GetLength() - iFirst;
+ memmove_s(pszBuffer, (this->GetLength() + 1)*sizeof(XCHAR),
+ psz, (nDataLength + 1)*sizeof(XCHAR));
+ this->ReleaseBufferSetLength(nDataLength);
+ }
+
+ return *this;
+}
+
+// Convert the string to the OEM character set
+template< typename BaseType, class StringTraits >
+void CMStringT<BaseType, StringTraits>::AnsiToOem()
+{
+ int nLength = this->GetLength();
+ PXSTR pszBuffer = this->GetBuffer(nLength);
+ StringTraits::ConvertToOem(pszBuffer, nLength + 1);
+ this->ReleaseBufferSetLength(nLength);
+}
+
+// Convert the string to the ANSI character set
+template< typename BaseType, class StringTraits >
+void CMStringT<BaseType, StringTraits>::OemToAnsi()
+{
+ int nLength = this->GetLength();
+ PXSTR pszBuffer = this->GetBuffer(nLength);
+ StringTraits::ConvertToAnsi(pszBuffer, nLength + 1);
+ this->ReleaseBufferSetLength(nLength);
+}
+
+// Very simple sub-string extraction
+
+// Return the substring starting at index 'iFirst'
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::Mid(int iFirst) const
+{
+ return Mid(iFirst, this->GetLength() - iFirst);
+}
+
+// Return the substring starting at index 'iFirst', with length 'nCount'
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::Mid(int iFirst, int nCount) const
+{
+ // nCount is in XCHARs
+
+ // out-of-bounds requests return sensible things
+ if (iFirst < 0)
+ iFirst = 0;
+ if (nCount < 0)
+ nCount = 0;
+
+ if ((iFirst + nCount) > this->GetLength())
+ nCount = this->GetLength() - iFirst;
+
+ if (iFirst > this->GetLength())
+ nCount = 0;
+
+ // optimize case of returning entire string
+ if ((iFirst == 0) && ((iFirst + nCount) == this->GetLength()))
+ return *this;
+
+ return CMStringT(this->GetString() + iFirst, nCount);
+}
+
+// Return the substring consisting of the rightmost 'nCount' characters
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::Right(int nCount) const
+{
+ // nCount is in XCHARs
+ if (nCount < 0)
+ nCount = 0;
+
+ int nLength = this->GetLength();
+ if (nCount >= nLength)
+ return *this;
+
+ return CMStringT(this->GetString() + nLength - nCount, nCount);
+}
+
+// Return the substring consisting of the leftmost 'nCount' characters
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::Left(int nCount) const
+{
+ // nCount is in XCHARs
+ if (nCount < 0)
+ nCount = 0;
+
+ int nLength = this->GetLength();
+ if (nCount >= nLength)
+ return *this;
+
+ return CMStringT(this->GetString(), nCount);
+}
+
+// Return the substring consisting of the leftmost characters in the set 'pszCharSet'
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::SpanIncluding(PCXSTR pszCharSet) const
+{
+ return Left(StringTraits::StringSpanIncluding(this->GetString(), pszCharSet));
+}
+
+// Return the substring consisting of the leftmost characters not in the set 'pszCharSet'
+template< typename BaseType, class StringTraits >
+CMStringT<BaseType, StringTraits> CMStringT<BaseType, StringTraits>::SpanExcluding(PCXSTR pszCharSet) const
+{
+ return Left(StringTraits::StringSpanExcluding(this->GetString(), pszCharSet));
+}
+
+// Format data using format string 'pszFormat'
+template< typename BaseType, class StringTraits >
+typename CMStringT<BaseType, StringTraits>::PCXSTR CMStringT<BaseType, StringTraits>::Format(PCXSTR pszFormat, ...)
+{
+ va_list argList;
+ va_start(argList, pszFormat);
+ FormatV(pszFormat, argList);
+ va_end(argList);
+ return this->GetString();
+}
+
+// Append formatted data using format string 'pszFormat'
+template< typename BaseType, class StringTraits >
+typename CMStringT<BaseType, StringTraits>::PCXSTR CMStringT<BaseType, StringTraits>::AppendFormat(PCXSTR pszFormat, ...)
+{
+ va_list argList;
+ va_start(argList, pszFormat);
+ AppendFormatV(pszFormat, argList);
+ va_end(argList);
+ return this->GetString();
+}
+
+template< typename BaseType, class StringTraits >
+void CMStringT<BaseType, StringTraits>::AppendFormatV(PCXSTR pszFormat, va_list args)
+{
+ int nCurrentLength = this->GetLength();
+ int nAppendLength = StringTraits::GetFormattedLength(pszFormat, args);
+ PXSTR pszBuffer = this->GetBuffer(nCurrentLength + nAppendLength);
+ StringTraits::Format(pszBuffer + nCurrentLength, nAppendLength + 1, pszFormat, args);
+ this->ReleaseBufferSetLength(nCurrentLength + nAppendLength);
+}
+
+template< typename BaseType, class StringTraits >
+typename CMStringT<BaseType, StringTraits>::PCXSTR CMStringT<BaseType, StringTraits>::FormatV(PCXSTR pszFormat, va_list args)
+{
+ int nLength = StringTraits::GetFormattedLength(pszFormat, args);
+ PXSTR pszBuffer = this->GetBuffer(nLength);
+ StringTraits::Format(pszBuffer, nLength + 1, pszFormat, args);
+ this->ReleaseBufferSetLength(nLength);
+ return this->GetString();
+}
+
+// Set the string to the value of environment variable 'pszVar'
+template< typename BaseType, class StringTraits >
+BOOL CMStringT<BaseType, StringTraits>::GetEnvironmentVariable(PCXSTR pszVar)
+{
+ int nLength = StringTraits::GetEnvironmentVariable(pszVar, nullptr, 0);
+ BOOL bRetVal = FALSE;
+
+ if (nLength == 0)
+ this->Empty();
+ else {
+ PXSTR pszBuffer = this->GetBuffer(nLength);
+ StringTraits::GetEnvironmentVariable(pszVar, pszBuffer, nLength);
+ this->ReleaseBuffer();
+ bRetVal = TRUE;
+ }
+
+ return bRetVal;
+}
+
+// Set the string to the value of environment variable 'pszVar'
+template< typename BaseType, class StringTraits >
+typename CMStringT<BaseType, StringTraits>::PXSTR CMStringT<BaseType, StringTraits>::Detach() const
+{
+ return StringTraits::MirCopy(CMStringT<BaseType, StringTraits>::GetString(), this->GetLength());
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, const CMStringT<BaseType, StringTraits>& str2)
+{
+ CMStringT<BaseType, StringTraits> strResult;
+ CMStringT<BaseType, StringTraits>::Concatenate(strResult, str1, str1.GetLength(), str2, str2.GetLength());
+ return strResult;
+}
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, typename CMStringT<BaseType, StringTraits>::PCXSTR psz2)
+{
+ CMStringT<BaseType, StringTraits> strResult;
+ CMStringT<BaseType, StringTraits>::Concatenate(strResult, str1, str1.GetLength(), psz2, CMStringT<BaseType, StringTraits>::StringLength(psz2));
+ return strResult;
+}
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(typename CMStringT<BaseType, StringTraits>::PCXSTR psz1, const CMStringT<BaseType, StringTraits>& str2)
+{
+ CMStringT<BaseType, StringTraits> strResult;
+ CMStringT<BaseType, StringTraits>::Concatenate(strResult, psz1, CMStringT<BaseType, StringTraits>::StringLength(psz1), str2, str2.GetLength());
+ return strResult;
+}
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, wchar_t ch2)
+{
+ CMStringT<BaseType, StringTraits> strResult;
+ typename CMStringT<BaseType, StringTraits>::XCHAR chTemp = typename CMStringT<BaseType, StringTraits>::XCHAR(ch2);
+ CMStringT<BaseType, StringTraits>::Concatenate(strResult, str1, str1.GetLength(), &chTemp, 1);
+ return strResult;
+}
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(const CMStringT<BaseType, StringTraits>& str1, char ch2)
+{
+ CMStringT<BaseType, StringTraits> strResult;
+ typename CMStringT<BaseType, StringTraits>::XCHAR chTemp = typename CMStringT<BaseType, StringTraits>::XCHAR(ch2);
+ CMStringT<BaseType, StringTraits>::Concatenate(strResult, str1, str1.GetLength(), &chTemp, 1);
+ return strResult;
+}
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(wchar_t ch1, const CMStringT<BaseType, StringTraits>& str2)
+{
+ CMStringT<BaseType, StringTraits> strResult;
+ typename CMStringT<BaseType, StringTraits>::XCHAR chTemp = typename CMStringT<BaseType, StringTraits>::XCHAR(ch1);
+ CMStringT<BaseType, StringTraits>::Concatenate(strResult, &chTemp, 1, str2, str2.GetLength());
+ return strResult;
+}
+
+template< typename BaseType, class StringTraits >
+MIR_CORE_EXPORT CMStringT<BaseType, StringTraits> CALLBACK operator+(char ch1, const CMStringT<BaseType, StringTraits>& str2)
+{
+ CMStringT<BaseType, StringTraits> strResult;
+ typename CMStringT<BaseType, StringTraits>::XCHAR chTemp = typename CMStringT<BaseType, StringTraits>::XCHAR(ch1);
+ CMStringT<BaseType, StringTraits>::Concatenate(strResult, &chTemp, 1, str2, str2.GetLength());
+ return strResult;
+}
+
+#endif // M_STRING_INL__
diff --git a/include/m_system.h b/include/m_system.h index 706820f8fc..2c00e048f2 100644 --- a/include/m_system.h +++ b/include/m_system.h @@ -1,662 +1,662 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-08 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#pragma once - -#ifndef M_SYSTEM_H__ -#define M_SYSTEM_H__ 1 - -#ifndef MIRANDANAME - #define MIRANDANAME "Miranda NG" -#endif -#ifndef MIRANDACLASS - #define MIRANDACLASS "Miranda" -#endif - -// set the default compatibility lever for Miranda 0.4.x -#ifndef MIRANDA_VER - #define MIRANDA_VER 0x0A00 -#endif - -#ifdef _MSC_VER - #pragma warning(disable:4244 4245) -#endif - -#define NEWSTR_ALLOCA(A) (A == NULL)?NULL:strcpy((char*)alloca(strlen(A)+1), A) -#define NEWWSTR_ALLOCA(A) ((A==NULL)?NULL:wcscpy((wchar_t*)alloca(sizeof(wchar_t)*(wcslen(A)+1)),A)) - -#include <m_core.h> - -// miranda/system/modulesloaded -// called after all modules have been successfully initialised -// wParam = lParam = 0 -// used to resolve double-dependencies in the module load order -#define ME_SYSTEM_MODULESLOADED "Miranda/System/ModulesLoaded" - -// miranda/system/shutdown event -// called just before the application terminates -// the database is still guaranteed to be running during this hook. -// wParam = lParam = 0 -#define ME_SYSTEM_SHUTDOWN "Miranda/System/Shutdown" - -// restarts miranda (0.8+) -// wParam = 0 or 1. 1 - restart with current profile, 0 - restart in default profile or profile manager -// lParam = (wchar_t*)path to a new miranda32.exe binary or NULL to use current -#define MS_SYSTEM_RESTART "Miranda/System/Restart" - -// miranda/system/oktoexit event -// called before the app goes into shutdown routine to make sure everyone is -// happy to exit -// wParam = lParam = 0 -// return nonzero to stop the exit cycle -#define ME_SYSTEM_OKTOEXIT "Miranda/System/OkToExitEvent" - -// gets the version number of Miranda encoded as a uint32_t -// returns the version number, encoded as one version per byte, therefore -// version 1.2.3.10 is 0x0102030a -EXTERN_C MIR_APP_DLL(uint32_t) Miranda_GetVersion(void); - -// gets the version number of Miranda encoded as four WORDs v0.92.2+ -// returns the version number, encoded as one version per word, therefore -// version 1.2.3.3210 is 0x0001, 0x0002, 0x0003, 0x0C8a -typedef uint16_t MFileVersion[4]; -EXTERN_C MIR_APP_DLL(void) Miranda_GetFileVersion(MFileVersion*); - -// gets the version of Miranda encoded as text -// cch is the size of the buffer pointed to by pszVersion, in bytes -// may return a build qualifier, such as "0.1.0.1 alpha" -// returns 0 on success, nonzero on failure -EXTERN_C MIR_APP_DLL(void) Miranda_GetVersionText(char *pDest, size_t cbSize); - -// returns a system window that can handle global timers -// a usual practice is to use a unique pointer as a timer id -EXTERN_C MIR_APP_DLL(class CDlgBase *) Miranda_GetSystemWindow(); - -// Adds an event to the list to be checked in the main message loop -// when a handle gets triggered, an appopriate stub gets called -typedef void (CALLBACK *MWaitableStub)(void); -typedef void (CALLBACK *MWaitableStubEx)(void*); - -EXTERN_C MIR_CORE_DLL(void) Miranda_WaitOnHandle(MWaitableStub pFunc, HANDLE hEvent = nullptr); -EXTERN_C MIR_CORE_DLL(void) Miranda_WaitOnHandleEx(MWaitableStubEx pFunc, void *pInfo); - -// wParam = 0 (ignored) -// lParam = 0 (ignored) -// -// This hook is fired just before the thread unwind stack is used, -// it allows MT plugins to shutdown threads if they have any special -// processing to do, etc. -#define ME_SYSTEM_PRESHUTDOWN "Miranda/System/PShutdown" - -// Returns true when Miranda has got WM_QUIT and is in the process of shutting down -EXTERN_C MIR_CORE_DLL(bool) Miranda_IsTerminated(void); - -// Enables termination flag -EXTERN_C MIR_CORE_DLL(void) Miranda_SetTerminated(void); - -// Check if everyone is happy to exit -// if everyone acknowleges OK to exit then returns true, otherwise false -EXTERN_C MIR_APP_DLL(bool) Miranda_OkToExit(void); - -// Used by contact lists inside CloseAction -// Waits for a permission to exit and destroys contact list -EXTERN_C MIR_APP_DLL(void) Miranda_Close(void); - -// returns the last window tick where a monitored event was seen, currently WM_CHAR/WM_MOUSEMOVE -EXTERN_C MIR_CORE_DLL(uint32_t) Miranda_GetIdle(void); - -/////////////////////////////////////////////////////////////////////////////// - -#if defined(__cplusplus) - -#ifndef M_STRING_H__ - #include <m_string.h> -#endif - -/////////////////////////////////////////////////////////////////////////////// -// general lists' templates - -struct MIR_CORE_EXPORT MNonCopyable -{ - __inline MNonCopyable() {} - - MNonCopyable(const MNonCopyable &) = delete; - MNonCopyable &operator=(const MNonCopyable &) = delete; -}; - -/////////////////////////////////////////////////////////////////////////////// -// mir_ptr - automatic pointer for buffers, allocated using mir_alloc/mir_calloc - -template<class T> class mir_ptr -{ -protected: - T *data; - -public: - __inline explicit mir_ptr() : data(nullptr) {} - __inline explicit mir_ptr(T *_p) : data(_p) {} - __inline ~mir_ptr() { mir_free(data); } - __inline T *get() const { return data; } - __inline T *operator=(T *_p) { if (data) mir_free(data); data = _p; return data; } - __inline T *operator->() const { return data; } - __inline operator T *() const { return data; } - __inline operator INT_PTR() const { return (INT_PTR)data; } - __inline T *detach() { T *res = data; data = nullptr; return res; } -}; - -typedef mir_ptr<char> ptrA; -typedef mir_ptr<wchar_t> ptrW; - -/////////////////////////////////////////////////////////////////////////////// -// mir_cs - simple wrapper for the critical sections - -class MIR_CORE_EXPORT mir_cs : public MNonCopyable -{ - #ifdef _MSC_VER - CRITICAL_SECTION m_cs; - #endif - -public: - mir_cs(); - ~mir_cs(); - - void Lock(); - void Unlock(); -}; - -/////////////////////////////////////////////////////////////////////////////// -// mir_cslock - simple locker for the critical sections - -class mir_cslock : public MNonCopyable -{ - mir_cs &cs; - -public: - __inline mir_cslock(mir_cs &_cs) : cs(_cs) { cs.Lock(); } - __inline ~mir_cslock() { cs.Unlock(); } -}; - -class mir_cslockfull : public MNonCopyable -{ - mir_cs &cs; - bool bIsLocked = false; - -public: - __inline void lock() { bIsLocked = true; cs.Lock(); } - __inline void unlock() { bIsLocked = false; cs.Unlock(); } - - __inline mir_cslockfull(mir_cs &_cs) : cs(_cs) { lock(); } - __inline ~mir_cslockfull() { if (bIsLocked) unlock(); } -}; - -////////////////////////////////////////////////////////////////////////////// -//pass_ptrA, pass_ptrW and pass_ptrT - automatic pointer for passwords - -class pass_ptrA : public mir_ptr<char> -{ -public: - __inline explicit pass_ptrA() : mir_ptr() {} - __inline explicit pass_ptrA(char *_p) : mir_ptr(_p) {} - __inline ~pass_ptrA() { zero(); } - __inline char *operator=(char *_p) { zero(); return mir_ptr::operator=(_p); } - __inline void zero() - { - if (data) SecureZeroMemory(data, mir_strlen(data)); - } -}; - -class pass_ptrW : public mir_ptr<wchar_t> -{ -public: - __inline explicit pass_ptrW() : mir_ptr() {} - __inline explicit pass_ptrW(wchar_t *_p) : mir_ptr(_p) {} - __inline ~pass_ptrW() { zero(); } - __inline wchar_t *operator=(wchar_t *_p) { zero(); return mir_ptr::operator=(_p); } - __inline void zero() - { - if (data) SecureZeroMemory(data, mir_wstrlen(data) * sizeof(wchar_t)); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// basic class for classes that should be cleared inside new() - -class MZeroedObject -{ -public: - __inline void *operator new(size_t size) - { - return calloc(1, size); - } - - __inline void operator delete(void *p) - { - free(p); - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// general lists' templates - -#define NumericKeySortT -1 -#define HandleKeySortT -2 -#define PtrKeySortT -3 - -template<class T> struct LIST -{ - typedef int (*FTSortFunc)(const T *p1, const T *p2); - - __inline LIST(int aincr, FTSortFunc afunc = nullptr) - { - memset(this, 0, sizeof(*this)); - increment = aincr; - sortFunc = afunc; - } - - __inline LIST(int aincr, INT_PTR id) - { - memset(this, 0, sizeof(*this)); - increment = aincr; - sortFunc = FTSortFunc(id); - } - - __inline LIST(const LIST &x) - { - items = nullptr; - List_Copy((SortedList *)&x, (SortedList *)this, sizeof(T)); - } - - __inline LIST &operator = (const LIST &x) - { - destroy(); - List_Copy((SortedList *)&x, (SortedList *)this, sizeof(T)); - return *this; - } - - __inline ~LIST() - { - destroy(); - } - - __inline T *operator[](int idx) const { return (idx >= 0 && idx < count) ? items[idx] : nullptr; } - __inline int getCount(void) const { return count; } - __inline T **getArray(void) const { return items; } - - __inline int getIndex(T *p) const - { - int idx; - return (!List_GetIndex((SortedList *)this, p, &idx)) ? -1 : idx; - } - - class reverse_iterator - { - int index; - T **base; - - public: - reverse_iterator(const LIST &_lst) : - index(_lst.getCount() - 1), - base(_lst.getArray()) - { - } - - class iterator - { - T **ptr; - - public: - iterator(T **_p) : ptr(_p) {} - iterator operator++() { --ptr; return *this; } - bool operator!=(const iterator &p) { return ptr != p.ptr; } - operator T **() const { return ptr; } - }; - - __inline iterator begin() const { return iterator(base + index); } - __inline iterator end() const { return iterator(base - 1); } - __inline int indexOf(T **p) const { return int(p - base); } - }; - - __inline void destroy(void) { List_Destroy((SortedList *)this); } - __inline T* find(T *p) const { return (T *)List_Find((SortedList *)this, p); } - __inline int indexOf(T *p) const { return List_IndexOf((SortedList *)this, p); } - __inline int insert(T *p, int idx) { return List_Insert((SortedList *)this, p, idx); } - __inline int remove(int idx) { return List_Remove((SortedList *)this, idx); } - - __inline int insert(T *p) { return List_InsertPtr((SortedList *)this, p); } - __inline int remove(T *p) { return List_RemovePtr((SortedList *)this, p); } - - __inline int indexOf(T **p) const { return int(p - items); } - - __inline T* removeItem(T **p) - { - T *savePtr = *p; - List_Remove((SortedList *)this, int(p - items)); - return savePtr; - } - - __inline void put(int idx, T *p) { items[idx] = p; } - - __inline T **begin() const { return items; } - __inline T **end() const { return items + count; } - - __inline reverse_iterator rev_iter() const { return reverse_iterator(*this); } - -protected: - T **items; - int count, limit, increment; - FTSortFunc sortFunc; -}; - -template<class T> struct OBJLIST : public LIST<T> -{ - typedef int (*FTSortFunc)(const T *p1, const T *p2); - - __inline OBJLIST(int aincr, FTSortFunc afunc = nullptr) : - LIST<T>(aincr, afunc) - { - } - - __inline OBJLIST(int aincr, INT_PTR id) : - LIST<T>(aincr, (FTSortFunc)id) - { - } - - __inline OBJLIST(const OBJLIST &x) : - LIST<T>(x.increment, x.sortFunc) - { - this->items = nullptr; - List_ObjCopy((SortedList *)&x, (SortedList *)this, sizeof(T)); - } - - __inline OBJLIST &operator = (const OBJLIST &x) - { - destroy(); - List_ObjCopy((SortedList *)&x, (SortedList *)this, sizeof(T)); - return *this; - } - - ~OBJLIST() - { - destroy(); - } - - __inline void destroy(void) - { - for (int i = 0; i < this->count; i++) - delete this->items[i]; - - List_Destroy((SortedList *)this); - } - - __inline int remove(int idx) - { - delete this->items[idx]; - return List_Remove((SortedList *)this, idx); - } - - __inline int remove(T *p) - { - int i = this->getIndex(p); - if (i != -1) { - remove(i); - return 1; - } - return 0; - } - - __inline T &operator[](int idx) const { return *this->items[idx]; } -}; - -#define __A2W(s) L ## s -#define _A2W(s) __A2W(s) - -class _A2T : public ptrW -{ -public: - __inline _A2T(const char *s) : ptrW(mir_a2u(s)) {} - __inline _A2T(const char *s, int cp) : ptrW(mir_a2u_cp(s, cp)) {} -}; - -class _T2A : public ptrA -{ -public: - __forceinline _T2A(const wchar_t *s) : ptrA(mir_u2a(s)) {} - __forceinline _T2A(const wchar_t *s, int cp) : ptrA(mir_u2a_cp(s, cp)) {} -}; - -class T2Utf : public ptrA -{ -public: - __forceinline T2Utf(const wchar_t *str) : ptrA(mir_utf8encodeW(str)) {} - __forceinline operator uint8_t*() const { return (uint8_t*)data; } -#ifdef _XSTRING_ - std::string str() const { return std::string(data); } -#endif -}; - -class Utf2T : public ptrW -{ -public: - __forceinline Utf2T(const char *str) : ptrW(mir_utf8decodeW(str)) {} - __forceinline operator wchar_t *() const { return data; } -#ifdef _XSTRING_ - std::wstring str() const { return std::wstring(data); } -#endif -}; - -/////////////////////////////////////////////////////////////////////////////// -// basic class for classes that should be cleared inside new() - -class MIR_CORE_EXPORT MBinBuffer -{ - uint8_t *m_buf = nullptr; - -public: - MBinBuffer(); - MBinBuffer(size_t preAlloc); - MBinBuffer(const MBinBuffer &orig); - ~MBinBuffer(); - MBinBuffer& operator=(MBinBuffer &&) noexcept; - - __forceinline uint8_t* data() const { return m_buf; } - __forceinline bool isEmpty() const { return m_buf == nullptr; } - size_t length() const; - - // adds a buffer to the end - void append(const void *pBuf, size_t bufLen); - - __forceinline void append(const MBinBuffer &buf) - { append(buf.data(), buf.length()); - } - - // adds a buffer to the beginning - void appendBefore(const void *pBuf, size_t bufLen); - - __forceinline void appendBefore(const MBinBuffer &buf) - { appendBefore(buf.data(), buf.length()); - } - - // replaces buffer contents - void assign(const void *pBuf, size_t bufLen); - - // drops a part of buffer - void remove(size_t sz); -}; - -/////////////////////////////////////////////////////////////////////////////// -// thread handle controller - -class MThreadLock -{ - HANDLE &m_pHandle; - -public: - __forceinline MThreadLock(HANDLE &pHandle) : - m_pHandle(pHandle) - { - } - - __forceinline ~MThreadLock() - { - m_pHandle = nullptr; - } -}; - -/////////////////////////////////////////////////////////////////////////////// -// parameter classes for XML, JSON & HTTP requests - -struct PARAM -{ - const char *szName; - __forceinline PARAM(const char *_name) : szName(_name) - { - } -}; - -struct BOOL_PARAM : public PARAM -{ - bool bValue; - __forceinline BOOL_PARAM(const char *_name, bool _value) : - PARAM(_name), bValue(_value) - { - } -}; - -struct INT_PARAM : public PARAM -{ - int32_t iValue; - __forceinline INT_PARAM(const char *_name, int32_t _value) : - PARAM(_name), iValue(_value) - { - } -}; - -struct INT64_PARAM : public PARAM -{ - int64_t iValue; - __forceinline INT64_PARAM(const char *_name, int64_t _value) : - PARAM(_name), iValue(_value) - { - } -}; - -struct SINT64_PARAM : public PARAM -{ - int64_t iValue; - __forceinline SINT64_PARAM(const char *_name, int64_t _value) : - PARAM(_name), iValue(_value) - { - } -}; - -struct CHAR_PARAM : public PARAM -{ - const char *szValue; - __forceinline CHAR_PARAM(const char *_name, const char *_value) : - PARAM(_name), szValue(_value) - { - } -}; - -struct WCHAR_PARAM : public PARAM -{ - const wchar_t *wszValue; - __forceinline WCHAR_PARAM(const char *_name, const wchar_t *_value) : - PARAM(_name), wszValue(_value) - { - } -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Callbacks - -class CCallbackImp -{ - struct CDummy - { - int foo; - }; - - typedef void (CDummy:: *TFnCallback)(void *argument); - - CDummy *m_object; - TFnCallback m_func; - -protected: - template<typename TClass, typename TArgument> - __inline CCallbackImp(TClass *object, void (TClass:: *func)(TArgument *argument)) : - m_object((CDummy *)object), - m_func((TFnCallback)func) - { - } - - __inline void Invoke(void *argument) const { if (m_func && m_object) (m_object->*m_func)(argument); } - -public: - __inline CCallbackImp() : m_object(nullptr), m_func(nullptr) {} - - __inline CCallbackImp(const CCallbackImp &other) : m_object(other.m_object), m_func(other.m_func) {} - __inline CCallbackImp &operator=(const CCallbackImp &other) { m_object = other.m_object; m_func = other.m_func; return *this; } - - __inline bool operator==(const CCallbackImp &other) const { return (m_object == other.m_object) && (m_func == other.m_func); } - __inline bool operator!=(const CCallbackImp &other) const { return (m_object != other.m_object) || (m_func != other.m_func); } - - __inline operator bool() const { return m_object && m_func; } -}; - -template<typename TArgument> -struct CCallback : public CCallbackImp -{ - typedef CCallbackImp CSuper; - -public: - __inline CCallback() {} - - template<typename TClass> - __inline CCallback(TClass *object, void (TClass:: *func)(TArgument *argument)) : CCallbackImp(object, func) {} - - __inline CCallback &operator=(const CCallbackImp &x) { CSuper::operator =(x); return *this; } - - __inline void operator()(TArgument *argument) const { Invoke((void *)argument); } -}; - -template<typename TClass, typename TArgument> -__inline CCallback<TArgument> Callback(TClass *object, void (TClass:: *func)(TArgument *argument)) -{ - return CCallback<TArgument>(object, func); -} - -/////////////////////////////////////////////////////////////////////////////// -// http support - -// works inline, in the same buffer, thus destroying its contents -// returns the address of buffer passed - -MIR_CORE_DLL(char *) mir_urlDecode(char *szUrl); - -MIR_CORE_DLL(CMStringA) mir_urlEncode(const char *szUrl); - -#endif // __cpluscplus - -#endif // M_SYSTEM_H +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-08 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#pragma once
+
+#ifndef M_SYSTEM_H__
+#define M_SYSTEM_H__ 1
+
+#ifndef MIRANDANAME
+ #define MIRANDANAME "Miranda NG"
+#endif
+#ifndef MIRANDACLASS
+ #define MIRANDACLASS "Miranda"
+#endif
+
+// set the default compatibility lever for Miranda 0.4.x
+#ifndef MIRANDA_VER
+ #define MIRANDA_VER 0x0A00
+#endif
+
+#ifdef _MSC_VER
+ #pragma warning(disable:4244 4245)
+#endif
+
+#define NEWSTR_ALLOCA(A) (A == NULL)?NULL:strcpy((char*)alloca(strlen(A)+1), A)
+#define NEWWSTR_ALLOCA(A) ((A==NULL)?NULL:wcscpy((wchar_t*)alloca(sizeof(wchar_t)*(wcslen(A)+1)),A))
+
+#include <m_core.h>
+
+// miranda/system/modulesloaded
+// called after all modules have been successfully initialised
+// wParam = lParam = 0
+// used to resolve double-dependencies in the module load order
+#define ME_SYSTEM_MODULESLOADED "Miranda/System/ModulesLoaded"
+
+// miranda/system/shutdown event
+// called just before the application terminates
+// the database is still guaranteed to be running during this hook.
+// wParam = lParam = 0
+#define ME_SYSTEM_SHUTDOWN "Miranda/System/Shutdown"
+
+// restarts miranda (0.8+)
+// wParam = 0 or 1. 1 - restart with current profile, 0 - restart in default profile or profile manager
+// lParam = (wchar_t*)path to a new miranda32.exe binary or NULL to use current
+#define MS_SYSTEM_RESTART "Miranda/System/Restart"
+
+// miranda/system/oktoexit event
+// called before the app goes into shutdown routine to make sure everyone is
+// happy to exit
+// wParam = lParam = 0
+// return nonzero to stop the exit cycle
+#define ME_SYSTEM_OKTOEXIT "Miranda/System/OkToExitEvent"
+
+// gets the version number of Miranda encoded as a uint32_t
+// returns the version number, encoded as one version per byte, therefore
+// version 1.2.3.10 is 0x0102030a
+EXTERN_C MIR_APP_DLL(uint32_t) Miranda_GetVersion(void);
+
+// gets the version number of Miranda encoded as four WORDs v0.92.2+
+// returns the version number, encoded as one version per word, therefore
+// version 1.2.3.3210 is 0x0001, 0x0002, 0x0003, 0x0C8a
+typedef uint16_t MFileVersion[4];
+EXTERN_C MIR_APP_DLL(void) Miranda_GetFileVersion(MFileVersion*);
+
+// gets the version of Miranda encoded as text
+// cch is the size of the buffer pointed to by pszVersion, in bytes
+// may return a build qualifier, such as "0.1.0.1 alpha"
+// returns 0 on success, nonzero on failure
+EXTERN_C MIR_APP_DLL(void) Miranda_GetVersionText(char *pDest, size_t cbSize);
+
+// returns a system window that can handle global timers
+// a usual practice is to use a unique pointer as a timer id
+EXTERN_C MIR_APP_DLL(class CDlgBase *) Miranda_GetSystemWindow();
+
+// Adds an event to the list to be checked in the main message loop
+// when a handle gets triggered, an appopriate stub gets called
+typedef void (CALLBACK *MWaitableStub)(void);
+typedef void (CALLBACK *MWaitableStubEx)(void*);
+
+EXTERN_C MIR_CORE_DLL(void) Miranda_WaitOnHandle(MWaitableStub pFunc, HANDLE hEvent = nullptr);
+EXTERN_C MIR_CORE_DLL(void) Miranda_WaitOnHandleEx(MWaitableStubEx pFunc, void *pInfo);
+
+// wParam = 0 (ignored)
+// lParam = 0 (ignored)
+//
+// This hook is fired just before the thread unwind stack is used,
+// it allows MT plugins to shutdown threads if they have any special
+// processing to do, etc.
+#define ME_SYSTEM_PRESHUTDOWN "Miranda/System/PShutdown"
+
+// Returns true when Miranda has got WM_QUIT and is in the process of shutting down
+EXTERN_C MIR_CORE_DLL(bool) Miranda_IsTerminated(void);
+
+// Enables termination flag
+EXTERN_C MIR_CORE_DLL(void) Miranda_SetTerminated(void);
+
+// Check if everyone is happy to exit
+// if everyone acknowleges OK to exit then returns true, otherwise false
+EXTERN_C MIR_APP_DLL(bool) Miranda_OkToExit(void);
+
+// Used by contact lists inside CloseAction
+// Waits for a permission to exit and destroys contact list
+EXTERN_C MIR_APP_DLL(void) Miranda_Close(void);
+
+// returns the last window tick where a monitored event was seen, currently WM_CHAR/WM_MOUSEMOVE
+EXTERN_C MIR_CORE_DLL(uint32_t) Miranda_GetIdle(void);
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if defined(__cplusplus)
+
+#ifndef M_STRING_H__
+ #include <m_string.h>
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// general lists' templates
+
+struct MIR_CORE_EXPORT MNonCopyable
+{
+ __inline MNonCopyable() {}
+
+ MNonCopyable(const MNonCopyable &) = delete;
+ MNonCopyable &operator=(const MNonCopyable &) = delete;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// mir_ptr - automatic pointer for buffers, allocated using mir_alloc/mir_calloc
+
+template<class T> class mir_ptr
+{
+protected:
+ T *data;
+
+public:
+ __inline explicit mir_ptr() : data(nullptr) {}
+ __inline explicit mir_ptr(T *_p) : data(_p) {}
+ __inline ~mir_ptr() { mir_free(data); }
+ __inline T *get() const { return data; }
+ __inline T *operator=(T *_p) { if (data) mir_free(data); data = _p; return data; }
+ __inline T *operator->() const { return data; }
+ __inline operator T *() const { return data; }
+ __inline operator INT_PTR() const { return (INT_PTR)data; }
+ __inline T *detach() { T *res = data; data = nullptr; return res; }
+};
+
+typedef mir_ptr<char> ptrA;
+typedef mir_ptr<wchar_t> ptrW;
+
+///////////////////////////////////////////////////////////////////////////////
+// mir_cs - simple wrapper for the critical sections
+
+class MIR_CORE_EXPORT mir_cs : public MNonCopyable
+{
+ #ifdef _MSC_VER
+ CRITICAL_SECTION m_cs;
+ #endif
+
+public:
+ mir_cs();
+ ~mir_cs();
+
+ void Lock();
+ void Unlock();
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// mir_cslock - simple locker for the critical sections
+
+class mir_cslock : public MNonCopyable
+{
+ mir_cs &cs;
+
+public:
+ __inline mir_cslock(mir_cs &_cs) : cs(_cs) { cs.Lock(); }
+ __inline ~mir_cslock() { cs.Unlock(); }
+};
+
+class mir_cslockfull : public MNonCopyable
+{
+ mir_cs &cs;
+ bool bIsLocked = false;
+
+public:
+ __inline void lock() { bIsLocked = true; cs.Lock(); }
+ __inline void unlock() { bIsLocked = false; cs.Unlock(); }
+
+ __inline mir_cslockfull(mir_cs &_cs) : cs(_cs) { lock(); }
+ __inline ~mir_cslockfull() { if (bIsLocked) unlock(); }
+};
+
+//////////////////////////////////////////////////////////////////////////////
+//pass_ptrA, pass_ptrW and pass_ptrT - automatic pointer for passwords
+
+class pass_ptrA : public mir_ptr<char>
+{
+public:
+ __inline explicit pass_ptrA() : mir_ptr() {}
+ __inline explicit pass_ptrA(char *_p) : mir_ptr(_p) {}
+ __inline ~pass_ptrA() { zero(); }
+ __inline char *operator=(char *_p) { zero(); return mir_ptr::operator=(_p); }
+ __inline void zero()
+ {
+ if (data) SecureZeroMemory(data, mir_strlen(data));
+ }
+};
+
+class pass_ptrW : public mir_ptr<wchar_t>
+{
+public:
+ __inline explicit pass_ptrW() : mir_ptr() {}
+ __inline explicit pass_ptrW(wchar_t *_p) : mir_ptr(_p) {}
+ __inline ~pass_ptrW() { zero(); }
+ __inline wchar_t *operator=(wchar_t *_p) { zero(); return mir_ptr::operator=(_p); }
+ __inline void zero()
+ {
+ if (data) SecureZeroMemory(data, mir_wstrlen(data) * sizeof(wchar_t));
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// basic class for classes that should be cleared inside new()
+
+class MZeroedObject
+{
+public:
+ __inline void *operator new(size_t size)
+ {
+ return calloc(1, size);
+ }
+
+ __inline void operator delete(void *p)
+ {
+ free(p);
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// general lists' templates
+
+#define NumericKeySortT -1
+#define HandleKeySortT -2
+#define PtrKeySortT -3
+
+template<class T> struct LIST
+{
+ typedef int (*FTSortFunc)(const T *p1, const T *p2);
+
+ __inline LIST(int aincr, FTSortFunc afunc = nullptr)
+ {
+ memset(this, 0, sizeof(*this));
+ increment = aincr;
+ sortFunc = afunc;
+ }
+
+ __inline LIST(int aincr, INT_PTR id)
+ {
+ memset(this, 0, sizeof(*this));
+ increment = aincr;
+ sortFunc = FTSortFunc(id);
+ }
+
+ __inline LIST(const LIST &x)
+ {
+ items = nullptr;
+ List_Copy((SortedList *)&x, (SortedList *)this, sizeof(T));
+ }
+
+ __inline LIST &operator = (const LIST &x)
+ {
+ destroy();
+ List_Copy((SortedList *)&x, (SortedList *)this, sizeof(T));
+ return *this;
+ }
+
+ __inline ~LIST()
+ {
+ destroy();
+ }
+
+ __inline T *operator[](int idx) const { return (idx >= 0 && idx < count) ? items[idx] : nullptr; }
+ __inline int getCount(void) const { return count; }
+ __inline T **getArray(void) const { return items; }
+
+ __inline int getIndex(T *p) const
+ {
+ int idx;
+ return (!List_GetIndex((SortedList *)this, p, &idx)) ? -1 : idx;
+ }
+
+ class reverse_iterator
+ {
+ int index;
+ T **base;
+
+ public:
+ reverse_iterator(const LIST &_lst) :
+ index(_lst.getCount() - 1),
+ base(_lst.getArray())
+ {
+ }
+
+ class iterator
+ {
+ T **ptr;
+
+ public:
+ iterator(T **_p) : ptr(_p) {}
+ iterator operator++() { --ptr; return *this; }
+ bool operator!=(const iterator &p) { return ptr != p.ptr; }
+ operator T **() const { return ptr; }
+ };
+
+ __inline iterator begin() const { return iterator(base + index); }
+ __inline iterator end() const { return iterator(base - 1); }
+ __inline int indexOf(T **p) const { return int(p - base); }
+ };
+
+ __inline void destroy(void) { List_Destroy((SortedList *)this); }
+ __inline T* find(T *p) const { return (T *)List_Find((SortedList *)this, p); }
+ __inline int indexOf(T *p) const { return List_IndexOf((SortedList *)this, p); }
+ __inline int insert(T *p, int idx) { return List_Insert((SortedList *)this, p, idx); }
+ __inline int remove(int idx) { return List_Remove((SortedList *)this, idx); }
+
+ __inline int insert(T *p) { return List_InsertPtr((SortedList *)this, p); }
+ __inline int remove(T *p) { return List_RemovePtr((SortedList *)this, p); }
+
+ __inline int indexOf(T **p) const { return int(p - items); }
+
+ __inline T* removeItem(T **p)
+ {
+ T *savePtr = *p;
+ List_Remove((SortedList *)this, int(p - items));
+ return savePtr;
+ }
+
+ __inline void put(int idx, T *p) { items[idx] = p; }
+
+ __inline T **begin() const { return items; }
+ __inline T **end() const { return items + count; }
+
+ __inline reverse_iterator rev_iter() const { return reverse_iterator(*this); }
+
+protected:
+ T **items;
+ int count, limit, increment;
+ FTSortFunc sortFunc;
+};
+
+template<class T> struct OBJLIST : public LIST<T>
+{
+ typedef int (*FTSortFunc)(const T *p1, const T *p2);
+
+ __inline OBJLIST(int aincr, FTSortFunc afunc = nullptr) :
+ LIST<T>(aincr, afunc)
+ {
+ }
+
+ __inline OBJLIST(int aincr, INT_PTR id) :
+ LIST<T>(aincr, (FTSortFunc)id)
+ {
+ }
+
+ __inline OBJLIST(const OBJLIST &x) :
+ LIST<T>(x.increment, x.sortFunc)
+ {
+ this->items = nullptr;
+ List_ObjCopy((SortedList *)&x, (SortedList *)this, sizeof(T));
+ }
+
+ __inline OBJLIST &operator = (const OBJLIST &x)
+ {
+ destroy();
+ List_ObjCopy((SortedList *)&x, (SortedList *)this, sizeof(T));
+ return *this;
+ }
+
+ ~OBJLIST()
+ {
+ destroy();
+ }
+
+ __inline void destroy(void)
+ {
+ for (int i = 0; i < this->count; i++)
+ delete this->items[i];
+
+ List_Destroy((SortedList *)this);
+ }
+
+ __inline int remove(int idx)
+ {
+ delete this->items[idx];
+ return List_Remove((SortedList *)this, idx);
+ }
+
+ __inline int remove(T *p)
+ {
+ int i = this->getIndex(p);
+ if (i != -1) {
+ remove(i);
+ return 1;
+ }
+ return 0;
+ }
+
+ __inline T &operator[](int idx) const { return *this->items[idx]; }
+};
+
+#define __A2W(s) L ## s
+#define _A2W(s) __A2W(s)
+
+class _A2T : public ptrW
+{
+public:
+ __inline _A2T(const char *s) : ptrW(mir_a2u(s)) {}
+ __inline _A2T(const char *s, int cp) : ptrW(mir_a2u_cp(s, cp)) {}
+};
+
+class _T2A : public ptrA
+{
+public:
+ __forceinline _T2A(const wchar_t *s) : ptrA(mir_u2a(s)) {}
+ __forceinline _T2A(const wchar_t *s, int cp) : ptrA(mir_u2a_cp(s, cp)) {}
+};
+
+class T2Utf : public ptrA
+{
+public:
+ __forceinline T2Utf(const wchar_t *str) : ptrA(mir_utf8encodeW(str)) {}
+ __forceinline operator uint8_t*() const { return (uint8_t*)data; }
+#ifdef _XSTRING_
+ std::string str() const { return std::string(data); }
+#endif
+};
+
+class Utf2T : public ptrW
+{
+public:
+ __forceinline Utf2T(const char *str) : ptrW(mir_utf8decodeW(str)) {}
+ __forceinline operator wchar_t *() const { return data; }
+#ifdef _XSTRING_
+ std::wstring str() const { return std::wstring(data); }
+#endif
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// basic class for classes that should be cleared inside new()
+
+class MIR_CORE_EXPORT MBinBuffer
+{
+ uint8_t *m_buf = nullptr;
+
+public:
+ MBinBuffer();
+ MBinBuffer(size_t preAlloc);
+ MBinBuffer(const MBinBuffer &orig);
+ ~MBinBuffer();
+ MBinBuffer& operator=(MBinBuffer &&) noexcept;
+
+ __forceinline uint8_t* data() const { return m_buf; }
+ __forceinline bool isEmpty() const { return m_buf == nullptr; }
+ size_t length() const;
+
+ // adds a buffer to the end
+ void append(const void *pBuf, size_t bufLen);
+
+ __forceinline void append(const MBinBuffer &buf)
+ { append(buf.data(), buf.length());
+ }
+
+ // adds a buffer to the beginning
+ void appendBefore(const void *pBuf, size_t bufLen);
+
+ __forceinline void appendBefore(const MBinBuffer &buf)
+ { appendBefore(buf.data(), buf.length());
+ }
+
+ // replaces buffer contents
+ void assign(const void *pBuf, size_t bufLen);
+
+ // drops a part of buffer
+ void remove(size_t sz);
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// thread handle controller
+
+class MThreadLock
+{
+ HANDLE &m_pHandle;
+
+public:
+ __forceinline MThreadLock(HANDLE &pHandle) :
+ m_pHandle(pHandle)
+ {
+ }
+
+ __forceinline ~MThreadLock()
+ {
+ m_pHandle = nullptr;
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// parameter classes for XML, JSON & HTTP requests
+
+struct PARAM
+{
+ const char *szName;
+ __forceinline PARAM(const char *_name) : szName(_name)
+ {
+ }
+};
+
+struct BOOL_PARAM : public PARAM
+{
+ bool bValue;
+ __forceinline BOOL_PARAM(const char *_name, bool _value) :
+ PARAM(_name), bValue(_value)
+ {
+ }
+};
+
+struct INT_PARAM : public PARAM
+{
+ int32_t iValue;
+ __forceinline INT_PARAM(const char *_name, int32_t _value) :
+ PARAM(_name), iValue(_value)
+ {
+ }
+};
+
+struct INT64_PARAM : public PARAM
+{
+ int64_t iValue;
+ __forceinline INT64_PARAM(const char *_name, int64_t _value) :
+ PARAM(_name), iValue(_value)
+ {
+ }
+};
+
+struct SINT64_PARAM : public PARAM
+{
+ int64_t iValue;
+ __forceinline SINT64_PARAM(const char *_name, int64_t _value) :
+ PARAM(_name), iValue(_value)
+ {
+ }
+};
+
+struct CHAR_PARAM : public PARAM
+{
+ const char *szValue;
+ __forceinline CHAR_PARAM(const char *_name, const char *_value) :
+ PARAM(_name), szValue(_value)
+ {
+ }
+};
+
+struct WCHAR_PARAM : public PARAM
+{
+ const wchar_t *wszValue;
+ __forceinline WCHAR_PARAM(const char *_name, const wchar_t *_value) :
+ PARAM(_name), wszValue(_value)
+ {
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Callbacks
+
+class CCallbackImp
+{
+ struct CDummy
+ {
+ int foo;
+ };
+
+ typedef void (CDummy:: *TFnCallback)(void *argument);
+
+ CDummy *m_object;
+ TFnCallback m_func;
+
+protected:
+ template<typename TClass, typename TArgument>
+ __inline CCallbackImp(TClass *object, void (TClass:: *func)(TArgument *argument)) :
+ m_object((CDummy *)object),
+ m_func((TFnCallback)func)
+ {
+ }
+
+ __inline void Invoke(void *argument) const { if (m_func && m_object) (m_object->*m_func)(argument); }
+
+public:
+ __inline CCallbackImp() : m_object(nullptr), m_func(nullptr) {}
+
+ __inline CCallbackImp(const CCallbackImp &other) : m_object(other.m_object), m_func(other.m_func) {}
+ __inline CCallbackImp &operator=(const CCallbackImp &other) { m_object = other.m_object; m_func = other.m_func; return *this; }
+
+ __inline bool operator==(const CCallbackImp &other) const { return (m_object == other.m_object) && (m_func == other.m_func); }
+ __inline bool operator!=(const CCallbackImp &other) const { return (m_object != other.m_object) || (m_func != other.m_func); }
+
+ __inline operator bool() const { return m_object && m_func; }
+};
+
+template<typename TArgument>
+struct CCallback : public CCallbackImp
+{
+ typedef CCallbackImp CSuper;
+
+public:
+ __inline CCallback() {}
+
+ template<typename TClass>
+ __inline CCallback(TClass *object, void (TClass:: *func)(TArgument *argument)) : CCallbackImp(object, func) {}
+
+ __inline CCallback &operator=(const CCallbackImp &x) { CSuper::operator =(x); return *this; }
+
+ __inline void operator()(TArgument *argument) const { Invoke((void *)argument); }
+};
+
+template<typename TClass, typename TArgument>
+__inline CCallback<TArgument> Callback(TClass *object, void (TClass:: *func)(TArgument *argument))
+{
+ return CCallback<TArgument>(object, func);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// http support
+
+// works inline, in the same buffer, thus destroying its contents
+// returns the address of buffer passed
+
+MIR_CORE_DLL(char *) mir_urlDecode(char *szUrl);
+
+MIR_CORE_DLL(CMStringA) mir_urlEncode(const char *szUrl);
+
+#endif // __cpluscplus
+
+#endif // M_SYSTEM_H
diff --git a/include/m_timezones.h b/include/m_timezones.h index 5fc78c41d0..3b0d44a61f 100644 --- a/include/m_timezones.h +++ b/include/m_timezones.h @@ -1,139 +1,139 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-10 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef __M_TIMEZONES_H -#define __M_TIMEZONES_H - -#ifndef M_CORE_H__ -#include <m_core.h> -#endif - -#define MIM_TZ_NAMELEN 64 - -#define TZF_PLF_CB 1 // UI element is assumed to be a combo box -#define TZF_PLF_LB 2 // UI element is assumed to be a list box -#define TZF_DIFONLY 4 -#define TZF_KNOWNONLY 8 - -#define LOCAL_TIME_HANDLE NULL -#define UTC_TIME_HANDLE ((void*)-1) - -typedef INT_PTR mir_time; - -EXTERN_C MIR_CORE_DLL(HANDLE) TimeZone_CreateByName(LPCTSTR tszName, uint32_t dwFlags); -EXTERN_C MIR_CORE_DLL(HANDLE) TimeZone_CreateByContact(MCONTACT hContact, LPCSTR szModule, uint32_t dwFlags); - -EXTERN_C MIR_CORE_DLL(void) TimeZone_StoreByContact(MCONTACT hContact, LPCSTR szModule, HANDLE hTZ); -EXTERN_C MIR_CORE_DLL(void) TimeZone_StoreListResult(MCONTACT hContact, LPCSTR szModule, HWND hWnd, uint32_t dwFlags); - -EXTERN_C MIR_CORE_DLL(int) TimeZone_PrintDateTime(HANDLE hTZ, LPCTSTR szFormat, LPTSTR szDest, size_t cbDest, uint32_t dwFlags); -EXTERN_C MIR_CORE_DLL(int) TimeZone_PrintTimeStamp(HANDLE hTZ, mir_time ts, LPCTSTR szFormat, LPTSTR szDest, size_t cbDest, uint32_t dwFlags); - -EXTERN_C MIR_CORE_DLL(int) TimeZone_PrepareList(MCONTACT hContact, LPCSTR szModule, HWND hWnd, uint32_t dwFlags); -EXTERN_C MIR_CORE_DLL(int) TimeZone_SelectListItem(MCONTACT hContact, LPCSTR szModule, HWND hWnd, uint32_t dwFlags); - -#ifdef _MSC_VER -EXTERN_C MIR_CORE_DLL(int) TimeZone_GetTimeZoneTime(HANDLE hTZ, SYSTEMTIME *st); -EXTERN_C MIR_CORE_DLL(int) TimeZone_GetSystemTime(HANDLE hTZ, mir_time src, SYSTEMTIME *dest, uint32_t dwFlags); - -EXTERN_C MIR_CORE_DLL(LPTIME_ZONE_INFORMATION) TimeZone_GetInfo(HANDLE hTZ); -#endif -EXTERN_C MIR_CORE_DLL(mir_time) TimeZone_UtcToLocal(HANDLE hTZ, mir_time ts); - -EXTERN_C MIR_CORE_DLL(LPCTSTR) TimeZone_GetName(HANDLE hTZ); -EXTERN_C MIR_CORE_DLL(LPCTSTR) TimeZone_GetDescription(LPCTSTR TZname); - -#ifdef __cplusplus - -__forceinline int printDateTimeByContact (MCONTACT hContact, LPCTSTR szFormat, LPTSTR szDest, int cbDest, uint32_t dwFlags) -{ - return TimeZone_PrintDateTime(TimeZone_CreateByContact(hContact, nullptr, dwFlags), szFormat, szDest, cbDest, dwFlags); -} - -__forceinline int printTimeStampByContact(MCONTACT hContact, mir_time ts, LPCTSTR szFormat, LPTSTR szDest, int cbDest, uint32_t dwFlags) -{ - return TimeZone_PrintTimeStamp(TimeZone_CreateByContact(hContact, nullptr, dwFlags), ts, szFormat, szDest, cbDest, dwFlags); -} - -#ifdef _MSC_VER -__forceinline LPTIME_ZONE_INFORMATION getTziByContact(MCONTACT hContact, uint32_t dwFlags = 0) -{ - return TimeZone_GetInfo(TimeZone_CreateByContact(hContact, nullptr, dwFlags)); -} - -__forceinline int getTimeZoneTimeByContact(MCONTACT hContact, SYSTEMTIME *st, uint32_t dwFlags = 0) -{ - return TimeZone_GetTimeZoneTime(TimeZone_CreateByContact(hContact, nullptr, dwFlags), st); -} -#endif - -__forceinline mir_time timeStampToTimeZoneTimeStampByContact(MCONTACT hContact, mir_time ts, uint32_t dwFlags = 0) -{ - return TimeZone_UtcToLocal(TimeZone_CreateByContact(hContact, nullptr, dwFlags), ts); -} - -#endif - -///////////////////////////////////////////////////////////////////////////////////////// -// Time services -// -// Converts a GMT timestamp into local time -// Returns the converted value -// -// Timestamps have zero at midnight 1/1/1970 GMT, this service converts such a -// value to be based at midnight 1/1/1970 local time. -// This service does not use a simple conversion based on the current offset -// between GMT and local. Rather, it figures out whether daylight savings time -// would have been in place at the time of the stamp and gives the local time as -// it would have been at the time and date the stamp contains. -// This service isn't nearly as useful as db/time/TimestampToString below and I -// recommend avoiding its use when possible so that you don't get your timezones -// mixed up (like I did. Living at GMT makes things easier for me, but has certain -// disadvantages :-)). - -EXTERN_C MIR_CORE_DLL(uint32_t) TimeZone_ToLocal(uint32_t); - -///////////////////////////////////////////////////////////////////////////////////////// -// Converts a GMT timestamp into a customisable local time string -// Returns the destination buffer -// -// Uses db/time/timestamptolocal for the conversion so read that description to -// see what's going on. -// The string is formatted according to the current user's locale, language and -// preferences. -// szFormat can have the following special characters: -// t Time without seconds, eg hh:mm -// s Time with seconds, eg hh:mm:ss -// m Time without minutes, eg hh -// d Short date, eg dd/mm/yyyy -// D Long date, eg d mmmm yyyy -// I ISO 8061 Time yyyy-mm-ddThh:mm:ssZ -// All other characters are copied across to szDest as-is - -EXTERN_C MIR_CORE_DLL(char*) TimeZone_ToString(mir_time timeVal, const char *szFormat, char *szDest, size_t cchDest); -EXTERN_C MIR_CORE_DLL(wchar_t*) TimeZone_ToStringW(mir_time timeVal, const wchar_t *wszFormat, wchar_t *wszDest, size_t cchDest); - -#define TimeZone_ToStringT TimeZone_ToStringW - -#endif /* __M_TIMEZONES_H */ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-10 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __M_TIMEZONES_H
+#define __M_TIMEZONES_H
+
+#ifndef M_CORE_H__
+#include <m_core.h>
+#endif
+
+#define MIM_TZ_NAMELEN 64
+
+#define TZF_PLF_CB 1 // UI element is assumed to be a combo box
+#define TZF_PLF_LB 2 // UI element is assumed to be a list box
+#define TZF_DIFONLY 4
+#define TZF_KNOWNONLY 8
+
+#define LOCAL_TIME_HANDLE NULL
+#define UTC_TIME_HANDLE ((void*)-1)
+
+typedef INT_PTR mir_time;
+
+EXTERN_C MIR_CORE_DLL(HANDLE) TimeZone_CreateByName(LPCTSTR tszName, uint32_t dwFlags);
+EXTERN_C MIR_CORE_DLL(HANDLE) TimeZone_CreateByContact(MCONTACT hContact, LPCSTR szModule, uint32_t dwFlags);
+
+EXTERN_C MIR_CORE_DLL(void) TimeZone_StoreByContact(MCONTACT hContact, LPCSTR szModule, HANDLE hTZ);
+EXTERN_C MIR_CORE_DLL(void) TimeZone_StoreListResult(MCONTACT hContact, LPCSTR szModule, HWND hWnd, uint32_t dwFlags);
+
+EXTERN_C MIR_CORE_DLL(int) TimeZone_PrintDateTime(HANDLE hTZ, LPCTSTR szFormat, LPTSTR szDest, size_t cbDest, uint32_t dwFlags);
+EXTERN_C MIR_CORE_DLL(int) TimeZone_PrintTimeStamp(HANDLE hTZ, mir_time ts, LPCTSTR szFormat, LPTSTR szDest, size_t cbDest, uint32_t dwFlags);
+
+EXTERN_C MIR_CORE_DLL(int) TimeZone_PrepareList(MCONTACT hContact, LPCSTR szModule, HWND hWnd, uint32_t dwFlags);
+EXTERN_C MIR_CORE_DLL(int) TimeZone_SelectListItem(MCONTACT hContact, LPCSTR szModule, HWND hWnd, uint32_t dwFlags);
+
+#ifdef _MSC_VER
+EXTERN_C MIR_CORE_DLL(int) TimeZone_GetTimeZoneTime(HANDLE hTZ, SYSTEMTIME *st);
+EXTERN_C MIR_CORE_DLL(int) TimeZone_GetSystemTime(HANDLE hTZ, mir_time src, SYSTEMTIME *dest, uint32_t dwFlags);
+
+EXTERN_C MIR_CORE_DLL(LPTIME_ZONE_INFORMATION) TimeZone_GetInfo(HANDLE hTZ);
+#endif
+EXTERN_C MIR_CORE_DLL(mir_time) TimeZone_UtcToLocal(HANDLE hTZ, mir_time ts);
+
+EXTERN_C MIR_CORE_DLL(LPCTSTR) TimeZone_GetName(HANDLE hTZ);
+EXTERN_C MIR_CORE_DLL(LPCTSTR) TimeZone_GetDescription(LPCTSTR TZname);
+
+#ifdef __cplusplus
+
+__forceinline int printDateTimeByContact (MCONTACT hContact, LPCTSTR szFormat, LPTSTR szDest, int cbDest, uint32_t dwFlags)
+{
+ return TimeZone_PrintDateTime(TimeZone_CreateByContact(hContact, nullptr, dwFlags), szFormat, szDest, cbDest, dwFlags);
+}
+
+__forceinline int printTimeStampByContact(MCONTACT hContact, mir_time ts, LPCTSTR szFormat, LPTSTR szDest, int cbDest, uint32_t dwFlags)
+{
+ return TimeZone_PrintTimeStamp(TimeZone_CreateByContact(hContact, nullptr, dwFlags), ts, szFormat, szDest, cbDest, dwFlags);
+}
+
+#ifdef _MSC_VER
+__forceinline LPTIME_ZONE_INFORMATION getTziByContact(MCONTACT hContact, uint32_t dwFlags = 0)
+{
+ return TimeZone_GetInfo(TimeZone_CreateByContact(hContact, nullptr, dwFlags));
+}
+
+__forceinline int getTimeZoneTimeByContact(MCONTACT hContact, SYSTEMTIME *st, uint32_t dwFlags = 0)
+{
+ return TimeZone_GetTimeZoneTime(TimeZone_CreateByContact(hContact, nullptr, dwFlags), st);
+}
+#endif
+
+__forceinline mir_time timeStampToTimeZoneTimeStampByContact(MCONTACT hContact, mir_time ts, uint32_t dwFlags = 0)
+{
+ return TimeZone_UtcToLocal(TimeZone_CreateByContact(hContact, nullptr, dwFlags), ts);
+}
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Time services
+//
+// Converts a GMT timestamp into local time
+// Returns the converted value
+//
+// Timestamps have zero at midnight 1/1/1970 GMT, this service converts such a
+// value to be based at midnight 1/1/1970 local time.
+// This service does not use a simple conversion based on the current offset
+// between GMT and local. Rather, it figures out whether daylight savings time
+// would have been in place at the time of the stamp and gives the local time as
+// it would have been at the time and date the stamp contains.
+// This service isn't nearly as useful as db/time/TimestampToString below and I
+// recommend avoiding its use when possible so that you don't get your timezones
+// mixed up (like I did. Living at GMT makes things easier for me, but has certain
+// disadvantages :-)).
+
+EXTERN_C MIR_CORE_DLL(uint32_t) TimeZone_ToLocal(uint32_t);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Converts a GMT timestamp into a customisable local time string
+// Returns the destination buffer
+//
+// Uses db/time/timestamptolocal for the conversion so read that description to
+// see what's going on.
+// The string is formatted according to the current user's locale, language and
+// preferences.
+// szFormat can have the following special characters:
+// t Time without seconds, eg hh:mm
+// s Time with seconds, eg hh:mm:ss
+// m Time without minutes, eg hh
+// d Short date, eg dd/mm/yyyy
+// D Long date, eg d mmmm yyyy
+// I ISO 8061 Time yyyy-mm-ddThh:mm:ssZ
+// All other characters are copied across to szDest as-is
+
+EXTERN_C MIR_CORE_DLL(char*) TimeZone_ToString(mir_time timeVal, const char *szFormat, char *szDest, size_t cchDest);
+EXTERN_C MIR_CORE_DLL(wchar_t*) TimeZone_ToStringW(mir_time timeVal, const wchar_t *wszFormat, wchar_t *wszDest, size_t cchDest);
+
+#define TimeZone_ToStringT TimeZone_ToStringW
+
+#endif /* __M_TIMEZONES_H */
diff --git a/include/m_types.h b/include/m_types.h index 1b0bdeb3bf..5410b3476a 100644 --- a/include/m_types.h +++ b/include/m_types.h @@ -1,210 +1,210 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef M_TYPES_H__ -#define M_TYPES_H__ 1 - -/////////////////////////////////////////////////////////////////////////////// -// Linux - -#ifndef _MSC_VER - -#include <wchar.h> -#include <netinet/in.h> - -using namespace std; - -#define CALLBACK -#define EXTERN_C extern "C" - -#define PURE = 0 -#define STDMETHOD(method) virtual HRESULT method -#define STDMETHOD_(ret, method) virtual ret method -#define STDMETHODIMP_(ret) ret - -#define FALSE 0 -#define TRUE 1 -#define CP_ACP 0 -#define SW_HIDE 0 -#define SW_SHOW 5 -#define MAX_PATH 260 -#define LR_SHARED 0x8000 -#define LF_FACESIZE 32 -#define _TRUNCATE size_t(-1) -#define INVALID_HANDLE_VALUE HANDLE(-1) - -#define MB_OK 0x00000000L -#define MB_OKCANCEL 0x00000001L -#define MB_YESNOCANCEL 0x00000003L -#define MB_YESNO 0x00000004L -#define MB_RETRYCANCEL 0x00000005L - -#define MB_ICONSTOP 0x00000010L -#define MB_ICONERROR 0x00000010L -#define MB_ICONQUESTION 0x00000020L -#define MB_ICONEXCLAMATION 0x00000030L -#define MB_ICONWARNING 0x00000030L -#define MB_ICONINFORMATION 0x00000040L - -#define IDABORT 3 -#define IDCANCEL 2 -#define IDCONTINUE 11 -#define IDIGNORE 5 -#define IDNO 7 -#define IDOK 1 -#define IDRETRY 4 -#define IDTRYAGAIN 10 -#define IDYES 6 - -typedef void *HANDLE; -typedef int BOOL, SOCKET; -typedef uint32_t UINT, COLORREF; -typedef intptr_t WPARAM, LPARAM, INT_PTR; -typedef uintptr_t UINT_PTR, DWORD_PTR, LRESULT; -typedef char *LPSTR; -typedef const char *LPCSTR; -typedef wchar_t *LPWSTR, *LPTSTR; -typedef const wchar_t *LPCWSTR, *LPCTSTR; -typedef sockaddr_in SOCKADDR_IN; - -struct RECT { int left, top, right, bottom; }; -struct POINT { int x, y; }; -struct SIZE { int width, height; }; -struct MSG; -struct LOGFONTA; -struct LOGFONTW; -struct WIN32_FIND_DATA; - -#define GetCurrentThreadId pthread_self - -#define MIR_EXPORT __attribute__((__visibility__("default"))) -#define MIR_IMPORT -#define MIR_SYSCALL -#define MIR_CDECL -#define UNREFERENCED_PARAMETER(x) - -#define __try try -#define __except catch -#define EXCEPTION_EXECUTE_HANDLER ... - -#define _In_z_ -#define _Pre_notnull_ -#define _Always_(x) -#define _Printf_format_string_ -#define _countof(array) (sizeof(array) / sizeof(array[0])) -#define __forceinline inline __attribute__ ((always_inline)) -#define __fallthrough - -#define InterlockedIncrement(x) __sync_fetch_and_add(x, 1) -#define InterlockedDecrement(x) __sync_fetch_and_add(x, -1) - -#define SecureZeroMemory(x, y) memset(x, 0, y) -#define interface struct -#define memcpy_s(a,b,c,d) memcpy(a,c,(b)<(d)?(b):(d)) -#define memmove_s(a,b,c,d) memmove(a,c,(b)<(d)?(b):(d)) - -#define stricmp strcasecmp -#define strnicmp strncasecmp -#define wcsicmp wcscasecmp -#define wcsnicmp wcsncasecmp - -#define _vsnprintf vsnprintf -#define _vsnwprintf vswprintf - -#define DECLARE_HANDLE(name) struct _##name { int unused; }; typedef struct _##name *name -DECLARE_HANDLE(HDC); -DECLARE_HANDLE(HWND); -DECLARE_HANDLE(HFONT); -DECLARE_HANDLE(HICON); -DECLARE_HANDLE(HMENU); -DECLARE_HANDLE(HBRUSH); -DECLARE_HANDLE(HBITMAP); -DECLARE_HANDLE(HCURSOR); -DECLARE_HANDLE(HTREEITEM); -DECLARE_HANDLE(HINSTANCE); - -struct EXCEPTION_POINTERS { int unused; }; -struct LOGFONT { int unused; }; -struct SYSTEMTIME; -struct MEASUREITEMSTRUCT; -struct DRAWITEMSTRUCT; -struct DELETEITEMSTRUCT; - -struct NMHDR; -struct NMLISTVIEW; -struct NMLVDISPINFO; -struct NMLVSCROLL; -struct NMLVGETINFOTIP; -struct NMLVFINDITEM; -struct NMITEMACTIVATE; -struct NMLVKEYDOWN; -struct NMLVCUSTOMDRAW; -struct NMCLISTCONTROL; -struct NMTREEVIEW; -struct NMTVKEYDOWN; -struct NMTVDISPINFO; -struct NMTVGETINFOTIP; -struct NMTVCUSTOMDRAW; - -struct LVFINDINFO; -struct LVBKIMAGE; -struct LVCOLUMN; -struct LVGROUP; -struct LVGROUPMETRICS; -struct LVINSERTMARK; -struct LVTILEINFO; -struct LVTILEVIEWINFO; -struct LVITEM; -struct LVHITTESTINFO; -struct LVINSERTGROUPSORTED; -struct LVSETINFOTIP; - -struct TVITEMEX; -struct TVHITTESTINFO; -struct TVINSERTSTRUCT; -struct TVSORTCB; -struct _TREEITEM; - -#ifdef ELEMENTARY_H - typedef Evas_Object* MWindow; -#else - typedef void *MWindow; -#endif - -#else -/////////////////////////////////////////////////////////////////////////////// -// Windows - -#include <tchar.h> - -#define MIR_EXPORT __declspec(dllexport) -#define MIR_IMPORT __declspec(dllimport) - -#define MIR_SYSCALL __stdcall -#define MIR_CDECL __cdecl - -typedef HWND MWindow; - -#endif - -#endif // M_TYPES_H__ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_TYPES_H__
+#define M_TYPES_H__ 1
+
+///////////////////////////////////////////////////////////////////////////////
+// Linux
+
+#ifndef _MSC_VER
+
+#include <wchar.h>
+#include <netinet/in.h>
+
+using namespace std;
+
+#define CALLBACK
+#define EXTERN_C extern "C"
+
+#define PURE = 0
+#define STDMETHOD(method) virtual HRESULT method
+#define STDMETHOD_(ret, method) virtual ret method
+#define STDMETHODIMP_(ret) ret
+
+#define FALSE 0
+#define TRUE 1
+#define CP_ACP 0
+#define SW_HIDE 0
+#define SW_SHOW 5
+#define MAX_PATH 260
+#define LR_SHARED 0x8000
+#define LF_FACESIZE 32
+#define _TRUNCATE size_t(-1)
+#define INVALID_HANDLE_VALUE HANDLE(-1)
+
+#define MB_OK 0x00000000L
+#define MB_OKCANCEL 0x00000001L
+#define MB_YESNOCANCEL 0x00000003L
+#define MB_YESNO 0x00000004L
+#define MB_RETRYCANCEL 0x00000005L
+
+#define MB_ICONSTOP 0x00000010L
+#define MB_ICONERROR 0x00000010L
+#define MB_ICONQUESTION 0x00000020L
+#define MB_ICONEXCLAMATION 0x00000030L
+#define MB_ICONWARNING 0x00000030L
+#define MB_ICONINFORMATION 0x00000040L
+
+#define IDABORT 3
+#define IDCANCEL 2
+#define IDCONTINUE 11
+#define IDIGNORE 5
+#define IDNO 7
+#define IDOK 1
+#define IDRETRY 4
+#define IDTRYAGAIN 10
+#define IDYES 6
+
+typedef void *HANDLE;
+typedef int BOOL, SOCKET;
+typedef uint32_t UINT, COLORREF;
+typedef intptr_t WPARAM, LPARAM, INT_PTR;
+typedef uintptr_t UINT_PTR, DWORD_PTR, LRESULT;
+typedef char *LPSTR;
+typedef const char *LPCSTR;
+typedef wchar_t *LPWSTR, *LPTSTR;
+typedef const wchar_t *LPCWSTR, *LPCTSTR;
+typedef sockaddr_in SOCKADDR_IN;
+
+struct RECT { int left, top, right, bottom; };
+struct POINT { int x, y; };
+struct SIZE { int width, height; };
+struct MSG;
+struct LOGFONTA;
+struct LOGFONTW;
+struct WIN32_FIND_DATA;
+
+#define GetCurrentThreadId pthread_self
+
+#define MIR_EXPORT __attribute__((__visibility__("default")))
+#define MIR_IMPORT
+#define MIR_SYSCALL
+#define MIR_CDECL
+#define UNREFERENCED_PARAMETER(x)
+
+#define __try try
+#define __except catch
+#define EXCEPTION_EXECUTE_HANDLER ...
+
+#define _In_z_
+#define _Pre_notnull_
+#define _Always_(x)
+#define _Printf_format_string_
+#define _countof(array) (sizeof(array) / sizeof(array[0]))
+#define __forceinline inline __attribute__ ((always_inline))
+#define __fallthrough
+
+#define InterlockedIncrement(x) __sync_fetch_and_add(x, 1)
+#define InterlockedDecrement(x) __sync_fetch_and_add(x, -1)
+
+#define SecureZeroMemory(x, y) memset(x, 0, y)
+#define interface struct
+#define memcpy_s(a,b,c,d) memcpy(a,c,(b)<(d)?(b):(d))
+#define memmove_s(a,b,c,d) memmove(a,c,(b)<(d)?(b):(d))
+
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+#define wcsicmp wcscasecmp
+#define wcsnicmp wcsncasecmp
+
+#define _vsnprintf vsnprintf
+#define _vsnwprintf vswprintf
+
+#define DECLARE_HANDLE(name) struct _##name { int unused; }; typedef struct _##name *name
+DECLARE_HANDLE(HDC);
+DECLARE_HANDLE(HWND);
+DECLARE_HANDLE(HFONT);
+DECLARE_HANDLE(HICON);
+DECLARE_HANDLE(HMENU);
+DECLARE_HANDLE(HBRUSH);
+DECLARE_HANDLE(HBITMAP);
+DECLARE_HANDLE(HCURSOR);
+DECLARE_HANDLE(HTREEITEM);
+DECLARE_HANDLE(HINSTANCE);
+
+struct EXCEPTION_POINTERS { int unused; };
+struct LOGFONT { int unused; };
+struct SYSTEMTIME;
+struct MEASUREITEMSTRUCT;
+struct DRAWITEMSTRUCT;
+struct DELETEITEMSTRUCT;
+
+struct NMHDR;
+struct NMLISTVIEW;
+struct NMLVDISPINFO;
+struct NMLVSCROLL;
+struct NMLVGETINFOTIP;
+struct NMLVFINDITEM;
+struct NMITEMACTIVATE;
+struct NMLVKEYDOWN;
+struct NMLVCUSTOMDRAW;
+struct NMCLISTCONTROL;
+struct NMTREEVIEW;
+struct NMTVKEYDOWN;
+struct NMTVDISPINFO;
+struct NMTVGETINFOTIP;
+struct NMTVCUSTOMDRAW;
+
+struct LVFINDINFO;
+struct LVBKIMAGE;
+struct LVCOLUMN;
+struct LVGROUP;
+struct LVGROUPMETRICS;
+struct LVINSERTMARK;
+struct LVTILEINFO;
+struct LVTILEVIEWINFO;
+struct LVITEM;
+struct LVHITTESTINFO;
+struct LVINSERTGROUPSORTED;
+struct LVSETINFOTIP;
+
+struct TVITEMEX;
+struct TVHITTESTINFO;
+struct TVINSERTSTRUCT;
+struct TVSORTCB;
+struct _TREEITEM;
+
+#ifdef ELEMENTARY_H
+ typedef Evas_Object* MWindow;
+#else
+ typedef void *MWindow;
+#endif
+
+#else
+///////////////////////////////////////////////////////////////////////////////
+// Windows
+
+#include <tchar.h>
+
+#define MIR_EXPORT __declspec(dllexport)
+#define MIR_IMPORT __declspec(dllimport)
+
+#define MIR_SYSCALL __stdcall
+#define MIR_CDECL __cdecl
+
+typedef HWND MWindow;
+
+#endif
+
+#endif // M_TYPES_H__
diff --git a/include/m_userinfo.h b/include/m_userinfo.h index 9da71f1db5..880d224739 100644 --- a/include/m_userinfo.h +++ b/include/m_userinfo.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_utils.h b/include/m_utils.h index f9cb7e42cd..0d5b599ac6 100644 --- a/include/m_utils.h +++ b/include/m_utils.h @@ -3,7 +3,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-12 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/m_xml.h b/include/m_xml.h index e77db66a6f..de1231ec75 100644 --- a/include/m_xml.h +++ b/include/m_xml.h @@ -1,194 +1,194 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-08 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef M_XML_H__ -#define M_XML_H__ - -#include <m_core.h> - -///////////////////////////////////////////////////////////////////////////////////////// -// new API to replace the old one - -#ifdef MIR_CORE_EXPORTS -#define TINYXML2_EXPORT 1 -#else -#define TINYXML2_IMPORT 1 -#endif - -#include "../src/mir_core/src/tinyxml2.h" - -typedef tinyxml2::XMLNode TiXmlNode; -typedef tinyxml2::XMLText TiXmlText; -typedef tinyxml2::XMLElement TiXmlElement; -typedef tinyxml2::XMLDocument TiXmlDocument; - -typedef tinyxml2::XMLHandle TiXmlHandle; -typedef tinyxml2::XMLConstHandle TiXmlConst; - -///////////////////////////////////////////////////////////////////////////////////////// -// safe wrappers - -EXTERN_C MIR_CORE_DLL(int) XmlGetChildCount(const TiXmlElement*); - -EXTERN_C MIR_CORE_DLL(TiXmlElement*) XmlAddChild(TiXmlElement*, const char *pszName); -EXTERN_C MIR_CORE_DLL(TiXmlElement*) XmlAddChildA(TiXmlElement*, const char *pszName, const char *ptszValue); -EXTERN_C MIR_CORE_DLL(TiXmlElement*) XmlAddChildI(TiXmlElement*, const char *pszName, int iValue); - -EXTERN_C MIR_CORE_DLL(int) XmlGetChildInt(const TiXmlElement *hXml, const char *key); -EXTERN_C MIR_CORE_DLL(const char*) XmlGetChildText(const TiXmlElement *hXml, const char *key); -EXTERN_C MIR_CORE_DLL(const TiXmlElement*) XmlGetChildByTag(const TiXmlElement *hXml, const char *key, const char *attrName, const char *attrValue); -EXTERN_C MIR_CORE_DLL(const TiXmlElement*) XmlFirstChild(const TiXmlElement *hXml, const char *key = nullptr); - -EXTERN_C MIR_CORE_DLL(void) XmlAddAttr(TiXmlElement*, const char *pszName, const char *ptszValue); -EXTERN_C MIR_CORE_DLL(const char*) XmlGetAttr(const TiXmlElement*, const char *pszName); - -///////////////////////////////////////////////////////////////////////////////////////// -// simple element iterator -// -// allows traversing subnodes in a cycle like -// for (auto *pNode : TiXmlEnum(pRoot)) { - -class TiXmlIterator -{ - const TiXmlElement *m_pCurr; - -public: - TiXmlIterator(const TiXmlElement *pNode) : - m_pCurr(pNode) - { - } - - TiXmlIterator& operator=(const TiXmlElement *pNode) - { - m_pCurr = pNode; - return *this; - } - - // Prefix ++ overload - TiXmlIterator& operator++() - { - if (m_pCurr) - m_pCurr = m_pCurr->NextSiblingElement(); - return *this; - } - - const TiXmlElement* operator*() - { - return m_pCurr; - } - - bool operator!=(const TiXmlIterator &iterator) - { - return m_pCurr != iterator.m_pCurr; - } -}; - -class TiXmlEnum -{ - const TiXmlElement *m_pFirst; - -public: - TiXmlEnum(const TiXmlNode *pNode) - { - m_pFirst = (pNode) ? pNode->FirstChildElement() : nullptr; - } - - TiXmlIterator begin() - { - return TiXmlIterator(m_pFirst); - } - - TiXmlIterator end() - { - return TiXmlIterator(nullptr); - } -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// filtered element iterator -// -// allows traversing subnodes of the specified name in a cycle like -// for (auto *pNode : TiXmlFilter(pRoot, "element")) { - -class TiXmlFilterIterator -{ - const TiXmlElement *m_pCurr; - const char *m_pszFilter; - -public: - TiXmlFilterIterator(const TiXmlElement *pNode, const char *pszNodeName) : - m_pszFilter(pszNodeName), - m_pCurr(pNode) - { - } - - TiXmlFilterIterator& operator=(const TiXmlElement *pNode) - { - m_pCurr = pNode; - return *this; - } - - // Prefix ++ overload - TiXmlFilterIterator& operator++() - { - if (m_pCurr) - m_pCurr = m_pCurr->NextSiblingElement(m_pszFilter); - return *this; - } - - const TiXmlElement* operator*() - { - return m_pCurr; - } - - bool operator!=(const TiXmlFilterIterator &iterator) - { - return m_pCurr != iterator.m_pCurr; - } -}; - -class TiXmlFilter -{ - const TiXmlElement *m_pFirst; - const char *m_pszFilter; - -public: - TiXmlFilter(const TiXmlNode *pNode, const char *pszNodeName) : - m_pszFilter(pszNodeName) - { - m_pFirst = (pNode) ? pNode->FirstChildElement(pszNodeName) : nullptr; - } - - TiXmlFilterIterator begin() - { - return TiXmlFilterIterator(m_pFirst, m_pszFilter); - } - - TiXmlFilterIterator end() - { - return TiXmlFilterIterator(nullptr, nullptr); - } -}; - -#endif // M_XML_H__ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-08 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_XML_H__
+#define M_XML_H__
+
+#include <m_core.h>
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// new API to replace the old one
+
+#ifdef MIR_CORE_EXPORTS
+#define TINYXML2_EXPORT 1
+#else
+#define TINYXML2_IMPORT 1
+#endif
+
+#include "../src/mir_core/src/tinyxml2.h"
+
+typedef tinyxml2::XMLNode TiXmlNode;
+typedef tinyxml2::XMLText TiXmlText;
+typedef tinyxml2::XMLElement TiXmlElement;
+typedef tinyxml2::XMLDocument TiXmlDocument;
+
+typedef tinyxml2::XMLHandle TiXmlHandle;
+typedef tinyxml2::XMLConstHandle TiXmlConst;
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// safe wrappers
+
+EXTERN_C MIR_CORE_DLL(int) XmlGetChildCount(const TiXmlElement*);
+
+EXTERN_C MIR_CORE_DLL(TiXmlElement*) XmlAddChild(TiXmlElement*, const char *pszName);
+EXTERN_C MIR_CORE_DLL(TiXmlElement*) XmlAddChildA(TiXmlElement*, const char *pszName, const char *ptszValue);
+EXTERN_C MIR_CORE_DLL(TiXmlElement*) XmlAddChildI(TiXmlElement*, const char *pszName, int iValue);
+
+EXTERN_C MIR_CORE_DLL(int) XmlGetChildInt(const TiXmlElement *hXml, const char *key);
+EXTERN_C MIR_CORE_DLL(const char*) XmlGetChildText(const TiXmlElement *hXml, const char *key);
+EXTERN_C MIR_CORE_DLL(const TiXmlElement*) XmlGetChildByTag(const TiXmlElement *hXml, const char *key, const char *attrName, const char *attrValue);
+EXTERN_C MIR_CORE_DLL(const TiXmlElement*) XmlFirstChild(const TiXmlElement *hXml, const char *key = nullptr);
+
+EXTERN_C MIR_CORE_DLL(void) XmlAddAttr(TiXmlElement*, const char *pszName, const char *ptszValue);
+EXTERN_C MIR_CORE_DLL(const char*) XmlGetAttr(const TiXmlElement*, const char *pszName);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// simple element iterator
+//
+// allows traversing subnodes in a cycle like
+// for (auto *pNode : TiXmlEnum(pRoot)) {
+
+class TiXmlIterator
+{
+ const TiXmlElement *m_pCurr;
+
+public:
+ TiXmlIterator(const TiXmlElement *pNode) :
+ m_pCurr(pNode)
+ {
+ }
+
+ TiXmlIterator& operator=(const TiXmlElement *pNode)
+ {
+ m_pCurr = pNode;
+ return *this;
+ }
+
+ // Prefix ++ overload
+ TiXmlIterator& operator++()
+ {
+ if (m_pCurr)
+ m_pCurr = m_pCurr->NextSiblingElement();
+ return *this;
+ }
+
+ const TiXmlElement* operator*()
+ {
+ return m_pCurr;
+ }
+
+ bool operator!=(const TiXmlIterator &iterator)
+ {
+ return m_pCurr != iterator.m_pCurr;
+ }
+};
+
+class TiXmlEnum
+{
+ const TiXmlElement *m_pFirst;
+
+public:
+ TiXmlEnum(const TiXmlNode *pNode)
+ {
+ m_pFirst = (pNode) ? pNode->FirstChildElement() : nullptr;
+ }
+
+ TiXmlIterator begin()
+ {
+ return TiXmlIterator(m_pFirst);
+ }
+
+ TiXmlIterator end()
+ {
+ return TiXmlIterator(nullptr);
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// filtered element iterator
+//
+// allows traversing subnodes of the specified name in a cycle like
+// for (auto *pNode : TiXmlFilter(pRoot, "element")) {
+
+class TiXmlFilterIterator
+{
+ const TiXmlElement *m_pCurr;
+ const char *m_pszFilter;
+
+public:
+ TiXmlFilterIterator(const TiXmlElement *pNode, const char *pszNodeName) :
+ m_pszFilter(pszNodeName),
+ m_pCurr(pNode)
+ {
+ }
+
+ TiXmlFilterIterator& operator=(const TiXmlElement *pNode)
+ {
+ m_pCurr = pNode;
+ return *this;
+ }
+
+ // Prefix ++ overload
+ TiXmlFilterIterator& operator++()
+ {
+ if (m_pCurr)
+ m_pCurr = m_pCurr->NextSiblingElement(m_pszFilter);
+ return *this;
+ }
+
+ const TiXmlElement* operator*()
+ {
+ return m_pCurr;
+ }
+
+ bool operator!=(const TiXmlFilterIterator &iterator)
+ {
+ return m_pCurr != iterator.m_pCurr;
+ }
+};
+
+class TiXmlFilter
+{
+ const TiXmlElement *m_pFirst;
+ const char *m_pszFilter;
+
+public:
+ TiXmlFilter(const TiXmlNode *pNode, const char *pszNodeName) :
+ m_pszFilter(pszNodeName)
+ {
+ m_pFirst = (pNode) ? pNode->FirstChildElement(pszNodeName) : nullptr;
+ }
+
+ TiXmlFilterIterator begin()
+ {
+ return TiXmlFilterIterator(m_pFirst, m_pszFilter);
+ }
+
+ TiXmlFilterIterator end()
+ {
+ return TiXmlFilterIterator(nullptr, nullptr);
+ }
+};
+
+#endif // M_XML_H__
diff --git a/include/m_xstatus.h b/include/m_xstatus.h index b26c03bdb3..afbac6890e 100644 --- a/include/m_xstatus.h +++ b/include/m_xstatus.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
diff --git a/include/newpluginapi.h b/include/newpluginapi.h index 88d72a47d0..a7e561461f 100644 --- a/include/newpluginapi.h +++ b/include/newpluginapi.h @@ -1,501 +1,501 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org) -Copyright (c) 2000-08 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef M_NEWPLUGINAPI_H__ -#define M_NEWPLUGINAPI_H__ - -#if !defined(HIMAGELIST) -typedef struct _IMAGELIST* HIMAGELIST; -#endif - -#include <m_gui.h> -#include <m_database.h> -#include <m_protocols.h> - -#define PLUGIN_MAKE_VERSION(a, b, c, d) (((((DWORD)(a))&0xFF)<<24)|((((DWORD)(b))&0xFF)<<16)|((((DWORD)(c))&0xFF)<<8)|(((DWORD)(d))&0xFF)) -#define MAXMODULELABELLENGTH 64 - -#define UNICODE_AWARE 0x0001 -#define STATIC_PLUGIN 0x0002 - -MIR_APP_DLL(int) GetPluginLangId(const MUUID &uuid, int langId); -MIR_APP_DLL(int) IsPluginLoaded(const MUUID &uuid); -MIR_APP_DLL(int) SetServiceModePlugin(const char *szPluginName, WPARAM = 0, LPARAM = 0); - -// manually get/set flag specified at Options - Plugins - Enabled -MIR_APP_DLL(bool) IsPluginOnWhiteList(const char *szPluginName); -MIR_APP_DLL(void) SetPluginOnWhiteList(const char *szPluginName, bool bAllow); - -///////////////////////////////////////////////////////////////////////////////////////// -// Used to define the end of the MirandaPluginInterface list - -#define MIID_LAST {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}} - -///////////////////////////////////////////////////////////////////////////////////////// -// Replaceable internal modules interface ids - -#define MIID_HISTORY {0x5ca0cbc1, 0x999a, 0x4ea2, {0x8b, 0x44, 0xf8, 0xf6, 0x7d, 0x7f, 0x8e, 0xbe}} -#define MIID_UIUSERINFO {0x570b931c, 0x9af8, 0x48f1, {0xad, 0x9f, 0xc4, 0x49, 0x8c, 0x61, 0x8a, 0x77}} -#define MIID_SRAWAY {0x5ab54c76, 0x1b4c, 0x4a00, {0xb4, 0x04, 0x48, 0xcb, 0xea, 0x5f, 0xef, 0xe7}} -#define MIID_SREMAIL {0xd005b5a6, 0x1b66, 0x445a, {0xb6, 0x03, 0x74, 0xd4, 0xd4, 0x55, 0x2d, 0xe2}} -#define MIID_SRFILE {0x989d104d, 0xacb7, 0x4ee0, {0xb9, 0x6d, 0x67, 0xce, 0x46, 0x53, 0xb6, 0x95}} -#define MIID_UIHISTORY {0x7f7e3d98, 0xce1f, 0x4962, {0x82, 0x84, 0x96, 0x85, 0x50, 0xf1, 0xd3, 0xd9}} -#define MIID_AUTOAWAY {0x9c87f7dc, 0x3bd7, 0x4983, {0xb7, 0xfb, 0xb8, 0x48, 0xfd, 0xbc, 0x91, 0xf0}} -#define MIID_USERONLINE {0x130829e0, 0x2463, 0x4ff8, {0xbb, 0xc8, 0xce, 0x73, 0xc0, 0x18, 0x84, 0x42}} -#define MIID_CRYPTO {0x415ca6e1, 0x895f, 0x40e6, {0x87, 0xbd, 0x9b, 0x39, 0x60, 0x16, 0xd0, 0xe5}} -#define MIID_POPUP {0xb275f4a4, 0xe347, 0x4515, {0xaf, 0x71, 0x77, 0xd0, 0x1e, 0xef, 0x54, 0x41}} - -///////////////////////////////////////////////////////////////////////////////////////// -// Common plugin interfaces (core plugins) - -#define MIID_DATABASE {0xae77fd33, 0xe484, 0x4dc7, {0x8c, 0xbc, 0x09, 0x9f, 0xed, 0xcc, 0xcf, 0xdd}} -#define MIID_CLIST {0x9d8da8bf, 0x665b, 0x4908, {0x9e, 0x61, 0x9f, 0x75, 0x98, 0xae, 0x33, 0x0e}} -#define MIID_SRMM {0x58c7eea6, 0xf9db, 0x4dd9, {0x80, 0x36, 0xae, 0x80, 0x2b, 0xc0, 0x41, 0x4c}} -#define MIID_TESTPLUGIN {0x53b974f4, 0x3c74, 0x4dba, {0x8f, 0xc2, 0x6f, 0x92, 0xfe, 0x01, 0x3b, 0x8c}} - -///////////////////////////////////////////////////////////////////////////////////////// -// Special exception interface for protocols. -// This interface allows more than one plugin to implement it at the same time - -#define MIID_PROTOCOL {0x2a3c815e, 0xa7d9, 0x424b, {0xba, 0x30, 0x2, 0xd0, 0x83, 0x22, 0x90, 0x85}} - -#define MIID_SERVICEMODE {0x8a92c026, 0x953a, 0x4f5f, { 0x99, 0x21, 0xf2, 0xc2, 0xdc, 0x19, 0x5e, 0xc5}} - -///////////////////////////////////////////////////////////////////////////////////////// -// Each service mode plugin must implement MS_SERVICEMODE_LAUNCH -// This service might return one of the following values: -// SERVICE_CONTINUE - load Miranda normally, like there's no service plugins at all -// SERVICE_ONLYDB - load database and then execute service plugin only -// SERVICE_MONOPOLY - execute only service plugin, even without database -// SERVICE_FAILED - terminate Miranda execution - -#define SERVICE_CONTINUE 0 -#define SERVICE_ONLYDB 1 -#define SERVICE_MONOPOLY 2 -#define SERVICE_FAILED (-1) - -#define MS_SERVICEMODE_LAUNCH "ServiceMode/Launch" - -struct PLUGININFOEX -{ - int cbSize; - const char *shortName; - uint32_t version; - const char *description; - const char *author; - const char *copyright; - const char *homepage; - uint8_t flags; // right now the only flag, UNICODE_AWARE, is recognized here - MUUID uuid; // plugin's unique identifier -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Miranda/System/LoadModule event -// called when a plugin is being loaded dynamically -// wParam = CMPluginBase* -// lParam = HINSTANCE of the loaded plugin - -#define ME_SYSTEM_MODULELOAD "Miranda/System/LoadModule" - -///////////////////////////////////////////////////////////////////////////////////////// -// Miranda/System/UnloadModule event -// called when a plugin is being unloaded dynamically -// wParam = CMPluginBase* -// lParam = HINSTANCE of the plugin to be unloaded - -#define ME_SYSTEM_MODULEUNLOAD "Miranda/System/UnloadModule" - -///////////////////////////////////////////////////////////////////////////////////////// -// plugin's class - -// initializes an empty account -typedef struct PROTO_INTERFACE* (*pfnInitProto)(const char* szModuleName, const wchar_t* szUserName); - -// deallocates an account instance -typedef int(*pfnUninitProto)(PROTO_INTERFACE*); - -#pragma warning(push) -#pragma warning(disable:4275) - -struct IcolibItem; - -class MIR_APP_EXPORT CMPluginBase : public MNonCopyable -{ - void tryOpenLog(); - -protected: - HINSTANCE m_hInst; - const char *m_szModuleName; - const PLUGININFOEX &m_pInfo; - HANDLE m_hLogger = nullptr; - LIST<IcolibItem> m_arIcons; - - CMPluginBase(const char *moduleName, const PLUGININFOEX &pInfo); - ~CMPluginBase(); - - // pass one of PROTOTYPE_* constants as type - void RegisterProtocol(int type, pfnInitProto = nullptr, pfnUninitProto = nullptr); - void SetUniqueId(const char *pszUniqueId); - -public: - void debugLogA(LPCSTR szFormat, ...); - void debugLogW(LPCWSTR wszFormat, ...); - - __forceinline void addIcolib(HANDLE hIcolib) { m_arIcons.insert((IcolibItem*)hIcolib); } - int addImgListIcon(HIMAGELIST himl, int iconId); - HICON getIcon(int iconId, bool big = false); - HANDLE getIconHandle(int iconId); - void releaseIcon(int iconId, bool big = false); - - __forceinline const PLUGININFOEX& getInfo() const { return m_pInfo; } - __forceinline const char* getModule() const { return m_szModuleName; } - - __forceinline HINSTANCE getInst() const { return m_hInst; } - __forceinline void setInst(HINSTANCE hInst) { m_hInst = hInst; } - - virtual int Load(); - virtual int Unload(); - - //////////////////////////////////////////////////////////////////////////////////////// - // registering module's resources - - template <size_t _Size> - __forceinline void registerIcon(const char *szSection, IconItem(&pIcons)[_Size], const char *prefix = nullptr) - { - Icon_Register(m_hInst, szSection, pIcons, _Size, prefix, this); - } - - template <size_t _Size> - __forceinline void registerIconW(const wchar_t *szSection, IconItemT(&pIcons)[_Size], const char *prefix = nullptr) - { - Icon_RegisterT(m_hInst, szSection, pIcons, _Size, prefix, this); - } - - int addOptions(WPARAM wParam, struct OPTIONSDIALOGPAGE *odp); - void openOptions(const wchar_t *pszGroup, const wchar_t *pszPage = 0, const wchar_t *pszTab = 0); - void openOptionsPage(const wchar_t *pszGroup, const wchar_t *pszPage = 0, const wchar_t *pszTab = 0); - - HANDLE addIcon(const struct SKINICONDESC*); - HANDLE addTTB(const struct TTBButton*); - - HGENMENU addRootMenu(int hMenuObject, LPCWSTR ptszName, int position, HANDLE hIcoLib = nullptr); - - int addFont(struct FontID *pFont); - int addFont(struct FontIDW *pFont); - - int addColor(struct ColourID *pColor); - int addColor(struct ColourIDW *pColor); - - int addEffect(struct EffectID *pEffect); - int addEffect(struct EffectIDW *pEffect); - - int addPopupOption(const char *pszDescr, CMOption<bool> &pVar); - int addPopupOption(const wchar_t *pwszDescr, CMOption<bool> &pVal); - - int addFrame(const struct CLISTFrame*); - int addHotkey(const struct HOTKEYDESC*); - int addSound(const char *name, const wchar_t *section, const wchar_t *description, const wchar_t *defaultFile = nullptr); - int addUserInfo(WPARAM wParam, struct USERINFOPAGE *odp); - - //////////////////////////////////////////////////////////////////////////////////////// - - __forceinline INT_PTR delSetting(const char *name) - { - return db_unset(0, m_szModuleName, name); - } - __forceinline INT_PTR delSetting(MCONTACT hContact, const char *name) - { - return db_unset(hContact, m_szModuleName, name); - } - - __forceinline bool getBool(const char *name, bool defaultValue = false) - { - return db_get_b(0, m_szModuleName, name, defaultValue) != 0; - } - __forceinline bool getBool(MCONTACT hContact, const char *name, bool defaultValue = false) - { - return db_get_b(hContact, m_szModuleName, name, defaultValue) != 0; - } - - __forceinline int getByte(const char *name, int defaultValue = 0) - { - return db_get_b(0, m_szModuleName, name, defaultValue); - } - __forceinline int getByte(MCONTACT hContact, const char *name, int defaultValue = 0) - { - return db_get_b(hContact, m_szModuleName, name, defaultValue); - } - - __forceinline int getWord(const char *name, int defaultValue = 0) - { - return db_get_w(0, m_szModuleName, name, defaultValue); - } - __forceinline int getWord(MCONTACT hContact, const char *name, int defaultValue = 0) - { - return db_get_w(hContact, m_szModuleName, name, defaultValue); - } - - __forceinline uint32_t getDword(const char *name, int defaultValue = 0) - { - return db_get_dw(0, m_szModuleName, name, defaultValue); - } - __forceinline uint32_t getDword(MCONTACT hContact, const char *name, int defaultValue = 0) - { - return db_get_dw(hContact, m_szModuleName, name, defaultValue); - } - - __forceinline INT_PTR getString(const char *name, DBVARIANT *result) - { - return db_get_s(0, m_szModuleName, name, result); - } - __forceinline INT_PTR getString(MCONTACT hContact, const char *name, DBVARIANT *result) - { - return db_get_s(hContact, m_szModuleName, name, result); - } - - __forceinline INT_PTR getUString(const char *name, DBVARIANT *result) - { - return db_get_utf(0, m_szModuleName, name, result); - } - __forceinline INT_PTR getUString(MCONTACT hContact, const char *name, DBVARIANT *result) - { - return db_get_utf(hContact, m_szModuleName, name, result); - } - - __forceinline INT_PTR getWString(const char *name, DBVARIANT *result) - { - return db_get_ws(0, m_szModuleName, name, result); - } - __forceinline INT_PTR getWString(MCONTACT hContact, const char *name, DBVARIANT *result) - { - return db_get_ws(hContact, m_szModuleName, name, result); - } - - __forceinline CMStringA getMStringA(const char *name, const char *szValue = nullptr) - { - return db_get_sm(0, m_szModuleName, name, szValue); - } - __forceinline CMStringA getMStringA(MCONTACT hContact, const char *name, const char *szValue = nullptr) - { - return db_get_sm(hContact, m_szModuleName, name, szValue); - } - - __forceinline char* getStringA(const char *name, const char *szValue = nullptr) - { - return db_get_sa(0, m_szModuleName, name, szValue); - } - __forceinline char* getStringA(MCONTACT hContact, const char *name, const char *szValue = nullptr) - { - return db_get_sa(hContact, m_szModuleName, name, szValue); - } - - __forceinline char* getUStringA(const char *name, const char *szValue = nullptr) - { - return db_get_utfa(0, m_szModuleName, name, szValue); - } - __forceinline char* getUStringA(MCONTACT hContact, const char *name, const char *szValue = nullptr) - { - return db_get_utfa(hContact, m_szModuleName, name, szValue); - } - - __forceinline wchar_t* getWStringA(const char *name, const wchar_t *szValue = nullptr) - { - return db_get_wsa(0, m_szModuleName, name, szValue); - } - __forceinline wchar_t* getWStringA(MCONTACT hContact, const char *name, const wchar_t *szValue = nullptr) - { - return db_get_wsa(hContact, m_szModuleName, name, szValue); - } - - __forceinline CMStringW getMStringW(const char *name, const wchar_t *szValue = nullptr) - { - return db_get_wsm(0, m_szModuleName, name, szValue); - } - __forceinline CMStringW getMStringW(MCONTACT hContact, const char *name, const wchar_t *szValue = nullptr) - { - return db_get_wsm(hContact, m_szModuleName, name, szValue); - } - - __forceinline void setByte(const char *name, uint8_t value) - { - db_set_b(0, m_szModuleName, name, value); - } - __forceinline void setByte(MCONTACT hContact, const char *name, uint8_t value) - { - db_set_b(hContact, m_szModuleName, name, value); - } - - __forceinline void setWord(const char *name, uint16_t value) - { - db_set_w(0, m_szModuleName, name, value); - } - __forceinline void setWord(MCONTACT hContact, const char *name, uint16_t value) - { - db_set_w(hContact, m_szModuleName, name, value); - } - - __forceinline void setDword(const char *name, uint32_t value) - { - db_set_dw(0, m_szModuleName, name, value); - } - __forceinline void setDword(MCONTACT hContact, const char *name, uint32_t value) - { - db_set_dw(hContact, m_szModuleName, name, value); - } - - __forceinline void setString(const char *name, const char* value) - { - db_set_s(0, m_szModuleName, name, value); - } - __forceinline void setString(MCONTACT hContact, const char *name, const char* value) - { - db_set_s(hContact, m_szModuleName, name, value); - } - - __forceinline void setUString(const char *name, const char* value) - { - db_set_utf(0, m_szModuleName, name, value); - } - __forceinline void setUString(MCONTACT hContact, const char *name, const char* value) - { - db_set_utf(hContact, m_szModuleName, name, value); - } - - __forceinline void setWString(const char *name, const wchar_t* value) - { - db_set_ws(0, m_szModuleName, name, value); - } - __forceinline void setWString(MCONTACT hContact, const char *name, const wchar_t* value) - { - db_set_ws(hContact, m_szModuleName, name, value); - } -}; - -#pragma warning(pop) - -extern struct CMPlugin g_plugin; - -///////////////////////////////////////////////////////////////////////////////////////// -// Basic class for plugins (not protocols) written in C++ - -typedef BOOL(MIR_SYSCALL* const _pfnCrtInit)(HINSTANCE, uint32_t, void*); - -template<class T> class PLUGIN : public CMPluginBase -{ - typedef CMPluginBase CSuper; - -protected: - __forceinline PLUGIN(const char *moduleName, const PLUGININFOEX &pInfo) - : CSuper(moduleName, pInfo) - {} - - __forceinline HANDLE CreatePluginEvent(const char *name) - { - CMStringA str(FORMAT, "%s\\%s", m_szModuleName, name); - return CreateHookableEvent(str); - } - - typedef int(MIR_CDECL T::*MyEventFunc)(WPARAM, LPARAM); - __forceinline void HookPluginEvent(const char *name, MyEventFunc pFunc) - { - HookEventObj(name, (MIRANDAHOOKOBJ)*(void**)&pFunc, this); - } - - typedef INT_PTR(MIR_CDECL T::*MyServiceFunc)(WPARAM, LPARAM); - __forceinline void CreatePluginService(const char *name, MyServiceFunc pFunc) - { - CMStringA str(FORMAT, "%s\\%s", m_szModuleName, name); - CreateServiceFunctionObj(str, (MIRANDASERVICEOBJ)*(void**)&pFunc, this); - } - - typedef INT_PTR(MIR_CDECL T::*MyServiceFuncParam)(WPARAM, LPARAM, LPARAM); - __forceinline void CreatePluginServiceParam(const char *name, MyServiceFuncParam pFunc, LPARAM param) - { - CMStringA str(FORMAT, "%s\\%s", m_szModuleName, name); - CreateServiceFunctionObjParam(str, (MIRANDASERVICEOBJPARAM)*(void**)&pFunc, this, param); - } -}; - -///////////////////////////////////////////////////////////////////////////////////////// -// Basic class for protocols with accounts - -struct CMPlugin; - -template<class P> class ACCPROTOPLUGIN : public PLUGIN<CMPlugin> -{ - typedef PLUGIN<CMPlugin> CSuper; - -protected: - ACCPROTOPLUGIN(const char *moduleName, const PLUGININFOEX &pInfo) : - CSuper(moduleName, pInfo) - { - CMPluginBase::RegisterProtocol(1002, &fnInit, &fnUninit); - } - - static PROTO_INTERFACE* fnInit(const char *szModuleName, const wchar_t *wszAccountName) - { - P *ppro = new P(szModuleName, wszAccountName); - g_arInstances.insert(ppro); - return ppro; - } - - static int fnUninit(PROTO_INTERFACE *ppro) - { - g_arInstances.remove((P*)ppro); - return 0; - } - -public: - static OBJLIST<P> g_arInstances; - - static P* getInstance(const char *szProto) - { - for (auto &it : g_arInstances) - if (mir_strcmp(szProto, it->m_szModuleName) == 0) - return it; - - return nullptr; - } - - static P* getInstance(MCONTACT hContact) - { - return getInstance(::Proto_GetBaseAccountName(hContact)); - } -}; - -template<class P> -OBJLIST<P> ACCPROTOPLUGIN<P>::g_arInstances(1, PtrKeySortT); - -#ifndef __NO_CMPLUGIN_NEEDED -#ifdef _DEBUG -#pragma comment(lib, "cmstubd.lib") -#else -#pragma comment(lib, "cmstub.lib") -#endif -#endif - -EXTERN_C MIR_APP_DLL(HINSTANCE) GetInstByAddress(void* codePtr); -EXTERN_C MIR_APP_DLL(CMPluginBase&) GetPluginByInstance(HINSTANCE hInst); - -#endif // M_NEWPLUGINAPI_H__ +/*
+
+Miranda NG: the free IM client for Microsoft* Windows*
+
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2000-08 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_NEWPLUGINAPI_H__
+#define M_NEWPLUGINAPI_H__
+
+#if !defined(HIMAGELIST)
+typedef struct _IMAGELIST* HIMAGELIST;
+#endif
+
+#include <m_gui.h>
+#include <m_database.h>
+#include <m_protocols.h>
+
+#define PLUGIN_MAKE_VERSION(a, b, c, d) (((((DWORD)(a))&0xFF)<<24)|((((DWORD)(b))&0xFF)<<16)|((((DWORD)(c))&0xFF)<<8)|(((DWORD)(d))&0xFF))
+#define MAXMODULELABELLENGTH 64
+
+#define UNICODE_AWARE 0x0001
+#define STATIC_PLUGIN 0x0002
+
+MIR_APP_DLL(int) GetPluginLangId(const MUUID &uuid, int langId);
+MIR_APP_DLL(int) IsPluginLoaded(const MUUID &uuid);
+MIR_APP_DLL(int) SetServiceModePlugin(const char *szPluginName, WPARAM = 0, LPARAM = 0);
+
+// manually get/set flag specified at Options - Plugins - Enabled
+MIR_APP_DLL(bool) IsPluginOnWhiteList(const char *szPluginName);
+MIR_APP_DLL(void) SetPluginOnWhiteList(const char *szPluginName, bool bAllow);
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Used to define the end of the MirandaPluginInterface list
+
+#define MIID_LAST {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Replaceable internal modules interface ids
+
+#define MIID_HISTORY {0x5ca0cbc1, 0x999a, 0x4ea2, {0x8b, 0x44, 0xf8, 0xf6, 0x7d, 0x7f, 0x8e, 0xbe}}
+#define MIID_UIUSERINFO {0x570b931c, 0x9af8, 0x48f1, {0xad, 0x9f, 0xc4, 0x49, 0x8c, 0x61, 0x8a, 0x77}}
+#define MIID_SRAWAY {0x5ab54c76, 0x1b4c, 0x4a00, {0xb4, 0x04, 0x48, 0xcb, 0xea, 0x5f, 0xef, 0xe7}}
+#define MIID_SREMAIL {0xd005b5a6, 0x1b66, 0x445a, {0xb6, 0x03, 0x74, 0xd4, 0xd4, 0x55, 0x2d, 0xe2}}
+#define MIID_SRFILE {0x989d104d, 0xacb7, 0x4ee0, {0xb9, 0x6d, 0x67, 0xce, 0x46, 0x53, 0xb6, 0x95}}
+#define MIID_UIHISTORY {0x7f7e3d98, 0xce1f, 0x4962, {0x82, 0x84, 0x96, 0x85, 0x50, 0xf1, 0xd3, 0xd9}}
+#define MIID_AUTOAWAY {0x9c87f7dc, 0x3bd7, 0x4983, {0xb7, 0xfb, 0xb8, 0x48, 0xfd, 0xbc, 0x91, 0xf0}}
+#define MIID_USERONLINE {0x130829e0, 0x2463, 0x4ff8, {0xbb, 0xc8, 0xce, 0x73, 0xc0, 0x18, 0x84, 0x42}}
+#define MIID_CRYPTO {0x415ca6e1, 0x895f, 0x40e6, {0x87, 0xbd, 0x9b, 0x39, 0x60, 0x16, 0xd0, 0xe5}}
+#define MIID_POPUP {0xb275f4a4, 0xe347, 0x4515, {0xaf, 0x71, 0x77, 0xd0, 0x1e, 0xef, 0x54, 0x41}}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Common plugin interfaces (core plugins)
+
+#define MIID_DATABASE {0xae77fd33, 0xe484, 0x4dc7, {0x8c, 0xbc, 0x09, 0x9f, 0xed, 0xcc, 0xcf, 0xdd}}
+#define MIID_CLIST {0x9d8da8bf, 0x665b, 0x4908, {0x9e, 0x61, 0x9f, 0x75, 0x98, 0xae, 0x33, 0x0e}}
+#define MIID_SRMM {0x58c7eea6, 0xf9db, 0x4dd9, {0x80, 0x36, 0xae, 0x80, 0x2b, 0xc0, 0x41, 0x4c}}
+#define MIID_TESTPLUGIN {0x53b974f4, 0x3c74, 0x4dba, {0x8f, 0xc2, 0x6f, 0x92, 0xfe, 0x01, 0x3b, 0x8c}}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Special exception interface for protocols.
+// This interface allows more than one plugin to implement it at the same time
+
+#define MIID_PROTOCOL {0x2a3c815e, 0xa7d9, 0x424b, {0xba, 0x30, 0x2, 0xd0, 0x83, 0x22, 0x90, 0x85}}
+
+#define MIID_SERVICEMODE {0x8a92c026, 0x953a, 0x4f5f, { 0x99, 0x21, 0xf2, 0xc2, 0xdc, 0x19, 0x5e, 0xc5}}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Each service mode plugin must implement MS_SERVICEMODE_LAUNCH
+// This service might return one of the following values:
+// SERVICE_CONTINUE - load Miranda normally, like there's no service plugins at all
+// SERVICE_ONLYDB - load database and then execute service plugin only
+// SERVICE_MONOPOLY - execute only service plugin, even without database
+// SERVICE_FAILED - terminate Miranda execution
+
+#define SERVICE_CONTINUE 0
+#define SERVICE_ONLYDB 1
+#define SERVICE_MONOPOLY 2
+#define SERVICE_FAILED (-1)
+
+#define MS_SERVICEMODE_LAUNCH "ServiceMode/Launch"
+
+struct PLUGININFOEX
+{
+ int cbSize;
+ const char *shortName;
+ uint32_t version;
+ const char *description;
+ const char *author;
+ const char *copyright;
+ const char *homepage;
+ uint8_t flags; // right now the only flag, UNICODE_AWARE, is recognized here
+ MUUID uuid; // plugin's unique identifier
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Miranda/System/LoadModule event
+// called when a plugin is being loaded dynamically
+// wParam = CMPluginBase*
+// lParam = HINSTANCE of the loaded plugin
+
+#define ME_SYSTEM_MODULELOAD "Miranda/System/LoadModule"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Miranda/System/UnloadModule event
+// called when a plugin is being unloaded dynamically
+// wParam = CMPluginBase*
+// lParam = HINSTANCE of the plugin to be unloaded
+
+#define ME_SYSTEM_MODULEUNLOAD "Miranda/System/UnloadModule"
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// plugin's class
+
+// initializes an empty account
+typedef struct PROTO_INTERFACE* (*pfnInitProto)(const char* szModuleName, const wchar_t* szUserName);
+
+// deallocates an account instance
+typedef int(*pfnUninitProto)(PROTO_INTERFACE*);
+
+#pragma warning(push)
+#pragma warning(disable:4275)
+
+struct IcolibItem;
+
+class MIR_APP_EXPORT CMPluginBase : public MNonCopyable
+{
+ void tryOpenLog();
+
+protected:
+ HINSTANCE m_hInst;
+ const char *m_szModuleName;
+ const PLUGININFOEX &m_pInfo;
+ HANDLE m_hLogger = nullptr;
+ LIST<IcolibItem> m_arIcons;
+
+ CMPluginBase(const char *moduleName, const PLUGININFOEX &pInfo);
+ ~CMPluginBase();
+
+ // pass one of PROTOTYPE_* constants as type
+ void RegisterProtocol(int type, pfnInitProto = nullptr, pfnUninitProto = nullptr);
+ void SetUniqueId(const char *pszUniqueId);
+
+public:
+ void debugLogA(LPCSTR szFormat, ...);
+ void debugLogW(LPCWSTR wszFormat, ...);
+
+ __forceinline void addIcolib(HANDLE hIcolib) { m_arIcons.insert((IcolibItem*)hIcolib); }
+ int addImgListIcon(HIMAGELIST himl, int iconId);
+ HICON getIcon(int iconId, bool big = false);
+ HANDLE getIconHandle(int iconId);
+ void releaseIcon(int iconId, bool big = false);
+
+ __forceinline const PLUGININFOEX& getInfo() const { return m_pInfo; }
+ __forceinline const char* getModule() const { return m_szModuleName; }
+
+ __forceinline HINSTANCE getInst() const { return m_hInst; }
+ __forceinline void setInst(HINSTANCE hInst) { m_hInst = hInst; }
+
+ virtual int Load();
+ virtual int Unload();
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // registering module's resources
+
+ template <size_t _Size>
+ __forceinline void registerIcon(const char *szSection, IconItem(&pIcons)[_Size], const char *prefix = nullptr)
+ {
+ Icon_Register(m_hInst, szSection, pIcons, _Size, prefix, this);
+ }
+
+ template <size_t _Size>
+ __forceinline void registerIconW(const wchar_t *szSection, IconItemT(&pIcons)[_Size], const char *prefix = nullptr)
+ {
+ Icon_RegisterT(m_hInst, szSection, pIcons, _Size, prefix, this);
+ }
+
+ int addOptions(WPARAM wParam, struct OPTIONSDIALOGPAGE *odp);
+ void openOptions(const wchar_t *pszGroup, const wchar_t *pszPage = 0, const wchar_t *pszTab = 0);
+ void openOptionsPage(const wchar_t *pszGroup, const wchar_t *pszPage = 0, const wchar_t *pszTab = 0);
+
+ HANDLE addIcon(const struct SKINICONDESC*);
+ HANDLE addTTB(const struct TTBButton*);
+
+ HGENMENU addRootMenu(int hMenuObject, LPCWSTR ptszName, int position, HANDLE hIcoLib = nullptr);
+
+ int addFont(struct FontID *pFont);
+ int addFont(struct FontIDW *pFont);
+
+ int addColor(struct ColourID *pColor);
+ int addColor(struct ColourIDW *pColor);
+
+ int addEffect(struct EffectID *pEffect);
+ int addEffect(struct EffectIDW *pEffect);
+
+ int addPopupOption(const char *pszDescr, CMOption<bool> &pVar);
+ int addPopupOption(const wchar_t *pwszDescr, CMOption<bool> &pVal);
+
+ int addFrame(const struct CLISTFrame*);
+ int addHotkey(const struct HOTKEYDESC*);
+ int addSound(const char *name, const wchar_t *section, const wchar_t *description, const wchar_t *defaultFile = nullptr);
+ int addUserInfo(WPARAM wParam, struct USERINFOPAGE *odp);
+
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+ __forceinline INT_PTR delSetting(const char *name)
+ {
+ return db_unset(0, m_szModuleName, name);
+ }
+ __forceinline INT_PTR delSetting(MCONTACT hContact, const char *name)
+ {
+ return db_unset(hContact, m_szModuleName, name);
+ }
+
+ __forceinline bool getBool(const char *name, bool defaultValue = false)
+ {
+ return db_get_b(0, m_szModuleName, name, defaultValue) != 0;
+ }
+ __forceinline bool getBool(MCONTACT hContact, const char *name, bool defaultValue = false)
+ {
+ return db_get_b(hContact, m_szModuleName, name, defaultValue) != 0;
+ }
+
+ __forceinline int getByte(const char *name, int defaultValue = 0)
+ {
+ return db_get_b(0, m_szModuleName, name, defaultValue);
+ }
+ __forceinline int getByte(MCONTACT hContact, const char *name, int defaultValue = 0)
+ {
+ return db_get_b(hContact, m_szModuleName, name, defaultValue);
+ }
+
+ __forceinline int getWord(const char *name, int defaultValue = 0)
+ {
+ return db_get_w(0, m_szModuleName, name, defaultValue);
+ }
+ __forceinline int getWord(MCONTACT hContact, const char *name, int defaultValue = 0)
+ {
+ return db_get_w(hContact, m_szModuleName, name, defaultValue);
+ }
+
+ __forceinline uint32_t getDword(const char *name, int defaultValue = 0)
+ {
+ return db_get_dw(0, m_szModuleName, name, defaultValue);
+ }
+ __forceinline uint32_t getDword(MCONTACT hContact, const char *name, int defaultValue = 0)
+ {
+ return db_get_dw(hContact, m_szModuleName, name, defaultValue);
+ }
+
+ __forceinline INT_PTR getString(const char *name, DBVARIANT *result)
+ {
+ return db_get_s(0, m_szModuleName, name, result);
+ }
+ __forceinline INT_PTR getString(MCONTACT hContact, const char *name, DBVARIANT *result)
+ {
+ return db_get_s(hContact, m_szModuleName, name, result);
+ }
+
+ __forceinline INT_PTR getUString(const char *name, DBVARIANT *result)
+ {
+ return db_get_utf(0, m_szModuleName, name, result);
+ }
+ __forceinline INT_PTR getUString(MCONTACT hContact, const char *name, DBVARIANT *result)
+ {
+ return db_get_utf(hContact, m_szModuleName, name, result);
+ }
+
+ __forceinline INT_PTR getWString(const char *name, DBVARIANT *result)
+ {
+ return db_get_ws(0, m_szModuleName, name, result);
+ }
+ __forceinline INT_PTR getWString(MCONTACT hContact, const char *name, DBVARIANT *result)
+ {
+ return db_get_ws(hContact, m_szModuleName, name, result);
+ }
+
+ __forceinline CMStringA getMStringA(const char *name, const char *szValue = nullptr)
+ {
+ return db_get_sm(0, m_szModuleName, name, szValue);
+ }
+ __forceinline CMStringA getMStringA(MCONTACT hContact, const char *name, const char *szValue = nullptr)
+ {
+ return db_get_sm(hContact, m_szModuleName, name, szValue);
+ }
+
+ __forceinline char* getStringA(const char *name, const char *szValue = nullptr)
+ {
+ return db_get_sa(0, m_szModuleName, name, szValue);
+ }
+ __forceinline char* getStringA(MCONTACT hContact, const char *name, const char *szValue = nullptr)
+ {
+ return db_get_sa(hContact, m_szModuleName, name, szValue);
+ }
+
+ __forceinline char* getUStringA(const char *name, const char *szValue = nullptr)
+ {
+ return db_get_utfa(0, m_szModuleName, name, szValue);
+ }
+ __forceinline char* getUStringA(MCONTACT hContact, const char *name, const char *szValue = nullptr)
+ {
+ return db_get_utfa(hContact, m_szModuleName, name, szValue);
+ }
+
+ __forceinline wchar_t* getWStringA(const char *name, const wchar_t *szValue = nullptr)
+ {
+ return db_get_wsa(0, m_szModuleName, name, szValue);
+ }
+ __forceinline wchar_t* getWStringA(MCONTACT hContact, const char *name, const wchar_t *szValue = nullptr)
+ {
+ return db_get_wsa(hContact, m_szModuleName, name, szValue);
+ }
+
+ __forceinline CMStringW getMStringW(const char *name, const wchar_t *szValue = nullptr)
+ {
+ return db_get_wsm(0, m_szModuleName, name, szValue);
+ }
+ __forceinline CMStringW getMStringW(MCONTACT hContact, const char *name, const wchar_t *szValue = nullptr)
+ {
+ return db_get_wsm(hContact, m_szModuleName, name, szValue);
+ }
+
+ __forceinline void setByte(const char *name, uint8_t value)
+ {
+ db_set_b(0, m_szModuleName, name, value);
+ }
+ __forceinline void setByte(MCONTACT hContact, const char *name, uint8_t value)
+ {
+ db_set_b(hContact, m_szModuleName, name, value);
+ }
+
+ __forceinline void setWord(const char *name, uint16_t value)
+ {
+ db_set_w(0, m_szModuleName, name, value);
+ }
+ __forceinline void setWord(MCONTACT hContact, const char *name, uint16_t value)
+ {
+ db_set_w(hContact, m_szModuleName, name, value);
+ }
+
+ __forceinline void setDword(const char *name, uint32_t value)
+ {
+ db_set_dw(0, m_szModuleName, name, value);
+ }
+ __forceinline void setDword(MCONTACT hContact, const char *name, uint32_t value)
+ {
+ db_set_dw(hContact, m_szModuleName, name, value);
+ }
+
+ __forceinline void setString(const char *name, const char* value)
+ {
+ db_set_s(0, m_szModuleName, name, value);
+ }
+ __forceinline void setString(MCONTACT hContact, const char *name, const char* value)
+ {
+ db_set_s(hContact, m_szModuleName, name, value);
+ }
+
+ __forceinline void setUString(const char *name, const char* value)
+ {
+ db_set_utf(0, m_szModuleName, name, value);
+ }
+ __forceinline void setUString(MCONTACT hContact, const char *name, const char* value)
+ {
+ db_set_utf(hContact, m_szModuleName, name, value);
+ }
+
+ __forceinline void setWString(const char *name, const wchar_t* value)
+ {
+ db_set_ws(0, m_szModuleName, name, value);
+ }
+ __forceinline void setWString(MCONTACT hContact, const char *name, const wchar_t* value)
+ {
+ db_set_ws(hContact, m_szModuleName, name, value);
+ }
+};
+
+#pragma warning(pop)
+
+extern struct CMPlugin g_plugin;
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Basic class for plugins (not protocols) written in C++
+
+typedef BOOL(MIR_SYSCALL* const _pfnCrtInit)(HINSTANCE, uint32_t, void*);
+
+template<class T> class PLUGIN : public CMPluginBase
+{
+ typedef CMPluginBase CSuper;
+
+protected:
+ __forceinline PLUGIN(const char *moduleName, const PLUGININFOEX &pInfo)
+ : CSuper(moduleName, pInfo)
+ {}
+
+ __forceinline HANDLE CreatePluginEvent(const char *name)
+ {
+ CMStringA str(FORMAT, "%s\\%s", m_szModuleName, name);
+ return CreateHookableEvent(str);
+ }
+
+ typedef int(MIR_CDECL T::*MyEventFunc)(WPARAM, LPARAM);
+ __forceinline void HookPluginEvent(const char *name, MyEventFunc pFunc)
+ {
+ HookEventObj(name, (MIRANDAHOOKOBJ)*(void**)&pFunc, this);
+ }
+
+ typedef INT_PTR(MIR_CDECL T::*MyServiceFunc)(WPARAM, LPARAM);
+ __forceinline void CreatePluginService(const char *name, MyServiceFunc pFunc)
+ {
+ CMStringA str(FORMAT, "%s\\%s", m_szModuleName, name);
+ CreateServiceFunctionObj(str, (MIRANDASERVICEOBJ)*(void**)&pFunc, this);
+ }
+
+ typedef INT_PTR(MIR_CDECL T::*MyServiceFuncParam)(WPARAM, LPARAM, LPARAM);
+ __forceinline void CreatePluginServiceParam(const char *name, MyServiceFuncParam pFunc, LPARAM param)
+ {
+ CMStringA str(FORMAT, "%s\\%s", m_szModuleName, name);
+ CreateServiceFunctionObjParam(str, (MIRANDASERVICEOBJPARAM)*(void**)&pFunc, this, param);
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Basic class for protocols with accounts
+
+struct CMPlugin;
+
+template<class P> class ACCPROTOPLUGIN : public PLUGIN<CMPlugin>
+{
+ typedef PLUGIN<CMPlugin> CSuper;
+
+protected:
+ ACCPROTOPLUGIN(const char *moduleName, const PLUGININFOEX &pInfo) :
+ CSuper(moduleName, pInfo)
+ {
+ CMPluginBase::RegisterProtocol(1002, &fnInit, &fnUninit);
+ }
+
+ static PROTO_INTERFACE* fnInit(const char *szModuleName, const wchar_t *wszAccountName)
+ {
+ P *ppro = new P(szModuleName, wszAccountName);
+ g_arInstances.insert(ppro);
+ return ppro;
+ }
+
+ static int fnUninit(PROTO_INTERFACE *ppro)
+ {
+ g_arInstances.remove((P*)ppro);
+ return 0;
+ }
+
+public:
+ static OBJLIST<P> g_arInstances;
+
+ static P* getInstance(const char *szProto)
+ {
+ for (auto &it : g_arInstances)
+ if (mir_strcmp(szProto, it->m_szModuleName) == 0)
+ return it;
+
+ return nullptr;
+ }
+
+ static P* getInstance(MCONTACT hContact)
+ {
+ return getInstance(::Proto_GetBaseAccountName(hContact));
+ }
+};
+
+template<class P>
+OBJLIST<P> ACCPROTOPLUGIN<P>::g_arInstances(1, PtrKeySortT);
+
+#ifndef __NO_CMPLUGIN_NEEDED
+#ifdef _DEBUG
+#pragma comment(lib, "cmstubd.lib")
+#else
+#pragma comment(lib, "cmstub.lib")
+#endif
+#endif
+
+EXTERN_C MIR_APP_DLL(HINSTANCE) GetInstByAddress(void* codePtr);
+EXTERN_C MIR_APP_DLL(CMPluginBase&) GetPluginByInstance(HINSTANCE hInst);
+
+#endif // M_NEWPLUGINAPI_H__
diff --git a/include/statusmodes.h b/include/statusmodes.h index ddeedcb895..78559de1e1 100644 --- a/include/statusmodes.h +++ b/include/statusmodes.h @@ -2,7 +2,7 @@ Miranda NG: the free IM client for Microsoft* Windows*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 Miranda NG team (https://miranda-ng.org)
Copyright (c) 2000-08 Miranda ICQ/IM project,
all portions of this codebase are copyrighted to the people
listed in contributors.txt.
|