xref: /PHP-7.4/ext/com_dotnet/com_olechar.c (revision a385cfa7)
16df5d5baSWez Furlong /*
26df5d5baSWez Furlong    +----------------------------------------------------------------------+
3d0cb7153SJohannes Schlüter    | PHP Version 7                                                        |
46df5d5baSWez Furlong    +----------------------------------------------------------------------+
5a6519d05SXinchen Hui    | Copyright (c) The PHP Group                                          |
66df5d5baSWez Furlong    +----------------------------------------------------------------------+
75bd93221Sfoobar    | This source file is subject to version 3.01 of the PHP license,      |
86df5d5baSWez Furlong    | that is bundled with this package in the file LICENSE, and is        |
96df5d5baSWez Furlong    | available through the world-wide-web at the following url:           |
105bd93221Sfoobar    | http://www.php.net/license/3_01.txt                                  |
116df5d5baSWez Furlong    | If you did not receive a copy of the PHP license and are unable to   |
126df5d5baSWez Furlong    | obtain it through the world-wide-web, please send a note to          |
136df5d5baSWez Furlong    | license@php.net so we can mail you a copy immediately.               |
146df5d5baSWez Furlong    +----------------------------------------------------------------------+
156df5d5baSWez Furlong    | Author: Wez Furlong <wez@thebrainroom.com>                           |
166df5d5baSWez Furlong    |         Harald Radi <h.radi@nme.at>                                  |
176df5d5baSWez Furlong    +----------------------------------------------------------------------+
186df5d5baSWez Furlong  */
196df5d5baSWez Furlong 
206df5d5baSWez Furlong #ifdef HAVE_CONFIG_H
216df5d5baSWez Furlong #include "config.h"
226df5d5baSWez Furlong #endif
236df5d5baSWez Furlong 
246df5d5baSWez Furlong #include "php.h"
256df5d5baSWez Furlong #include "php_ini.h"
266df5d5baSWez Furlong #include "ext/standard/info.h"
276df5d5baSWez Furlong #include "php_com_dotnet.h"
286df5d5baSWez Furlong #include "php_com_dotnet_internal.h"
296df5d5baSWez Furlong 
306df5d5baSWez Furlong 
php_com_string_to_olestring(char * string,size_t string_len,int codepage)31bdeb220fSAnatol Belski PHP_COM_DOTNET_API OLECHAR *php_com_string_to_olestring(char *string, size_t string_len, int codepage)
326df5d5baSWez Furlong {
336df5d5baSWez Furlong 	OLECHAR *olestring = NULL;
346df5d5baSWez Furlong 	DWORD flags = codepage == CP_UTF8 ? 0 : MB_PRECOMPOSED | MB_ERR_INVALID_CHARS;
356df5d5baSWez Furlong 	BOOL ok;
366df5d5baSWez Furlong 
376df5d5baSWez Furlong 	if (string_len == -1) {
386df5d5baSWez Furlong 		/* determine required length for the buffer (includes NUL terminator) */
396df5d5baSWez Furlong 		string_len = MultiByteToWideChar(codepage, flags, string, -1, NULL, 0);
406df5d5baSWez Furlong 	} else {
416df5d5baSWez Furlong 		/* allow room for NUL terminator */
426df5d5baSWez Furlong 		string_len++;
436df5d5baSWez Furlong 	}
446df5d5baSWez Furlong 
45955d3e73SDmitry Stogov 	if (string_len > 0) {
4631a32582SStanislav Malyshev 		olestring = (OLECHAR*)safe_emalloc(string_len, sizeof(OLECHAR), 0);
472d625b5fSAnatol Belski 		/* XXX if that's a real multibyte string, olestring is obviously allocated excessively.
482d625b5fSAnatol Belski 		This should be fixed by reallocating the olestring, but as emalloc is used, that doesn't
492d625b5fSAnatol Belski 		matter much. */
5041a505fcSAnatol Belski 		ok = MultiByteToWideChar(codepage, flags, string, (int)string_len, olestring, (int)string_len);
517d7be194SKalle Sommer Nielsen 		if (ok > 0 && (size_t)ok < string_len) {
522d625b5fSAnatol Belski 			olestring[ok] = '\0';
532d625b5fSAnatol Belski 		}
546df5d5baSWez Furlong 	} else {
556df5d5baSWez Furlong 		ok = FALSE;
566df5d5baSWez Furlong 		olestring = (OLECHAR*)emalloc(sizeof(OLECHAR));
576df5d5baSWez Furlong 		*olestring = 0;
586df5d5baSWez Furlong 	}
596df5d5baSWez Furlong 
606df5d5baSWez Furlong 	if (!ok) {
614574844cSPierre Joye 		char *msg = php_win32_error_to_msg(GetLastError());
626df5d5baSWez Furlong 
63bdeb220fSAnatol Belski 		php_error_docref(NULL, E_WARNING,
646df5d5baSWez Furlong 			"Could not convert string to unicode: `%s'", msg);
656df5d5baSWez Furlong 
666df5d5baSWez Furlong 		php_win32_error_msg_free(msg);
676df5d5baSWez Furlong 	}
686df5d5baSWez Furlong 
696df5d5baSWez Furlong 	return olestring;
706df5d5baSWez Furlong }
716df5d5baSWez Furlong 
php_com_olestring_to_string(OLECHAR * olestring,size_t * string_len,int codepage)72bdeb220fSAnatol Belski PHP_COM_DOTNET_API char *php_com_olestring_to_string(OLECHAR *olestring, size_t *string_len, int codepage)
736df5d5baSWez Furlong {
746df5d5baSWez Furlong 	char *string;
75b204b3abSAnatol Belski 	uint32_t length = 0;
766df5d5baSWez Furlong 	BOOL ok;
776df5d5baSWez Furlong 
786df5d5baSWez Furlong 	length = WideCharToMultiByte(codepage, 0, olestring, -1, NULL, 0, NULL, NULL);
796df5d5baSWez Furlong 
806df5d5baSWez Furlong 	if (length) {
8131a32582SStanislav Malyshev 		string = (char*)safe_emalloc(length, sizeof(char), 0);
826df5d5baSWez Furlong 		length = WideCharToMultiByte(codepage, 0, olestring, -1, string, length, NULL, NULL);
836df5d5baSWez Furlong 		ok = length > 0;
846df5d5baSWez Furlong 	} else {
856df5d5baSWez Furlong 		string = (char*)emalloc(sizeof(char));
866df5d5baSWez Furlong 		*string = '\0';
876df5d5baSWez Furlong 		ok = FALSE;
886df5d5baSWez Furlong 		length = 0;
896df5d5baSWez Furlong 	}
906df5d5baSWez Furlong 
916df5d5baSWez Furlong 	if (!ok) {
923292399dSPierre Joye 		char *msg = php_win32_error_to_msg(GetLastError());
936df5d5baSWez Furlong 
94bdeb220fSAnatol Belski 		php_error_docref(NULL, E_WARNING,
956df5d5baSWez Furlong 			"Could not convert string from unicode: `%s'", msg);
966df5d5baSWez Furlong 
976df5d5baSWez Furlong 		php_win32_error_msg_free(msg);
986df5d5baSWez Furlong 	}
996df5d5baSWez Furlong 
1006df5d5baSWez Furlong 	if (string_len) {
1016df5d5baSWez Furlong 		*string_len = length-1;
1026df5d5baSWez Furlong 	}
1036df5d5baSWez Furlong 
1046df5d5baSWez Furlong 	return string;
105e10c206dSWez Furlong }
106*a385cfa7SChristoph M. Becker 
php_com_string_to_bstr(zend_string * string,int codepage)107*a385cfa7SChristoph M. Becker BSTR php_com_string_to_bstr(zend_string *string, int codepage)
108*a385cfa7SChristoph M. Becker {
109*a385cfa7SChristoph M. Becker 	BSTR bstr = NULL;
110*a385cfa7SChristoph M. Becker 	DWORD flags = codepage == CP_UTF8 ? 0 : MB_PRECOMPOSED | MB_ERR_INVALID_CHARS;
111*a385cfa7SChristoph M. Becker 	size_t mb_len = ZSTR_LEN(string);
112*a385cfa7SChristoph M. Becker 	int wc_len;
113*a385cfa7SChristoph M. Becker 
114*a385cfa7SChristoph M. Becker 	if ((wc_len = MultiByteToWideChar(codepage, flags, ZSTR_VAL(string), (int)mb_len + 1, NULL, 0)) <= 0) {
115*a385cfa7SChristoph M. Becker 		goto fail;
116*a385cfa7SChristoph M. Becker 	}
117*a385cfa7SChristoph M. Becker 	if ((bstr = SysAllocStringLen(NULL, (UINT)(wc_len - 1))) == NULL) {
118*a385cfa7SChristoph M. Becker 		goto fail;
119*a385cfa7SChristoph M. Becker 	}
120*a385cfa7SChristoph M. Becker 	if ((wc_len = MultiByteToWideChar(codepage, flags, ZSTR_VAL(string), (int)mb_len + 1, bstr, wc_len)) <= 0) {
121*a385cfa7SChristoph M. Becker 		goto fail;
122*a385cfa7SChristoph M. Becker 	}
123*a385cfa7SChristoph M. Becker 	return bstr;
124*a385cfa7SChristoph M. Becker 
125*a385cfa7SChristoph M. Becker fail:
126*a385cfa7SChristoph M. Becker 	char *msg = php_win32_error_to_msg(GetLastError());
127*a385cfa7SChristoph M. Becker 	php_error_docref(NULL, E_WARNING,
128*a385cfa7SChristoph M. Becker 		"Could not convert string to unicode: `%s'", msg);
129*a385cfa7SChristoph M. Becker 	LocalFree(msg);
130*a385cfa7SChristoph M. Becker 	SysFreeString(bstr);
131*a385cfa7SChristoph M. Becker 	return SysAllocString(L"");
132*a385cfa7SChristoph M. Becker }
133*a385cfa7SChristoph M. Becker 
php_com_bstr_to_string(BSTR bstr,int codepage)134*a385cfa7SChristoph M. Becker zend_string *php_com_bstr_to_string(BSTR bstr, int codepage)
135*a385cfa7SChristoph M. Becker {
136*a385cfa7SChristoph M. Becker 	zend_string *string = NULL;
137*a385cfa7SChristoph M. Becker 	UINT wc_len = SysStringLen(bstr);
138*a385cfa7SChristoph M. Becker 	int mb_len;
139*a385cfa7SChristoph M. Becker 
140*a385cfa7SChristoph M. Becker 	mb_len = WideCharToMultiByte(codepage, 0, bstr, wc_len + 1, NULL, 0, NULL, NULL);
141*a385cfa7SChristoph M. Becker 	if (mb_len > 0) {
142*a385cfa7SChristoph M. Becker 		string = zend_string_alloc(mb_len - 1, 0);
143*a385cfa7SChristoph M. Becker 		mb_len = WideCharToMultiByte(codepage, 0, bstr, wc_len + 1, ZSTR_VAL(string), mb_len, NULL, NULL);
144*a385cfa7SChristoph M. Becker 	}
145*a385cfa7SChristoph M. Becker 
146*a385cfa7SChristoph M. Becker 	if (mb_len <= 0) {
147*a385cfa7SChristoph M. Becker 		char *msg = php_win32_error_to_msg(GetLastError());
148*a385cfa7SChristoph M. Becker 
149*a385cfa7SChristoph M. Becker 		php_error_docref(NULL, E_WARNING,
150*a385cfa7SChristoph M. Becker 			"Could not convert string from unicode: `%s'", msg);
151*a385cfa7SChristoph M. Becker 		LocalFree(msg);
152*a385cfa7SChristoph M. Becker 
153*a385cfa7SChristoph M. Becker 		if (string != NULL) {
154*a385cfa7SChristoph M. Becker 			zend_string_release(string);
155*a385cfa7SChristoph M. Becker 		}
156*a385cfa7SChristoph M. Becker 		string = ZSTR_EMPTY_ALLOC();
157*a385cfa7SChristoph M. Becker 	}
158*a385cfa7SChristoph M. Becker 
159*a385cfa7SChristoph M. Becker 	return string;
160*a385cfa7SChristoph M. Becker }