summaryrefslogtreecommitdiff
path: root/win32/codepage.h
diff options
context:
space:
mode:
Diffstat (limited to 'win32/codepage.h')
-rw-r--r--win32/codepage.h162
1 files changed, 162 insertions, 0 deletions
diff --git a/win32/codepage.h b/win32/codepage.h
new file mode 100644
index 0000000000..96afd443ec
--- /dev/null
+++ b/win32/codepage.h
@@ -0,0 +1,162 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 7 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2016 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Anatol Belski <ab@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef PHP_WIN32_CODEPAGE_H
+#define PHP_WIN32_CODEPAGE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef PHP_EXPORTS
+# define PW32CP __declspec(dllexport)
+#else
+# define PW32CP __declspec(dllimport)
+#endif
+
+#define PHP_WIN32_CP_IGNORE_LEN (0)
+#define PHP_WIN32_CP_IGNORE_LEN_P ((size_t *)-1)
+
+struct php_win32_cp {
+ DWORD id;
+ DWORD to_w_fl;
+ DWORD from_w_fl;
+ DWORD char_size;
+ char *name;
+ char *enc;
+ char *desc;
+};
+
+PW32CP BOOL php_win32_cp_use_unicode(void);
+PW32CP const struct php_win32_cp *php_win32_cp_do_setup(const char *);
+#define php_win32_cp_setup() php_win32_cp_do_setup(NULL)
+PW32CP const struct php_win32_cp *php_win32_cp_do_update(const char *);
+#define php_win32_cp_update() php_win32_cp_do_update(NULL)
+PW32CP const struct php_win32_cp *php_win32_cp_shutdown(void);
+PW32CP const struct php_win32_cp *php_win32_cp_get_current(void);
+PW32CP const struct php_win32_cp *php_win32_cp_get_orig(void);
+PW32CP const struct php_win32_cp *php_win32_cp_get_by_id(DWORD id);
+PW32CP const struct php_win32_cp *php_win32_cp_set_by_id(DWORD id);
+PW32CP const struct php_win32_cp *php_win32_cp_get_by_enc(const char *enc);
+PW32CP const struct php_win32_cp *php_win32_cp_cli_do_setup(DWORD);
+#define php_win32_cp_cli_setup() php_win32_cp_cli_do_setup(0)
+#define php_win32_cp_cli_update() php_win32_cp_cli_do_setup(0)
+PW32CP const struct php_win32_cp *php_win32_cp_cli_do_restore(DWORD);
+#define php_win32_cp_cli_restore() php_win32_cp_cli_do_restore(0)
+
+/* This API is binary safe and expects a \0 terminated input.
+ The returned out is \0 terminated, but the length doesn't count \0. */
+PW32CP wchar_t *php_win32_cp_conv_to_w(DWORD in_cp, DWORD flags, const char* in, size_t in_len, size_t *out_len);
+PW32CP wchar_t *php_win32_cp_conv_utf8_to_w(const char* in, size_t in_len, size_t *out_len);
+#define php_win32_cp_utf8_to_w(in) php_win32_cp_conv_utf8_to_w(in, PHP_WIN32_CP_IGNORE_LEN, PHP_WIN32_CP_IGNORE_LEN_P)
+PW32CP wchar_t *php_win32_cp_conv_cur_to_w(const char* in, size_t in_len, size_t *out_len);
+#define php_win32_cp_cur_to_w(in) php_win32_cp_conv_cur_to_w(in, PHP_WIN32_CP_IGNORE_LEN, PHP_WIN32_CP_IGNORE_LEN_P)
+PW32CP wchar_t *php_win32_cp_conv_ascii_to_w(const char* in, size_t in_len, size_t *out_len);
+#define php_win32_cp_ascii_to_w(in) php_win32_cp_conv_ascii_to_w(in, PHP_WIN32_CP_IGNORE_LEN, PHP_WIN32_CP_IGNORE_LEN_P)
+PW32CP char *php_win32_cp_conv_from_w(DWORD out_cp, DWORD flags, const wchar_t* in, size_t in_len, size_t *out_len);
+PW32CP char *php_win32_cp_conv_w_to_utf8(const wchar_t* in, size_t in_len, size_t *out_len);
+#define php_win32_cp_w_to_utf8(in) php_win32_cp_conv_w_to_utf8(in, PHP_WIN32_CP_IGNORE_LEN, PHP_WIN32_CP_IGNORE_LEN_P)
+PW32CP char *php_win32_cp_conv_w_to_cur(const wchar_t* in, size_t in_len, size_t *out_len);
+#define php_win32_cp_w_to_cur(in) php_win32_cp_conv_w_to_cur(in, PHP_WIN32_CP_IGNORE_LEN, PHP_WIN32_CP_IGNORE_LEN_P)
+PW32CP wchar_t *php_win32_cp_env_any_to_w(const char* env);
+
+/* This function tries to make the best guess to convert any
+ given string to a wide char, also prefering the fastest code
+ path to unicode. It returns NULL on fail. */
+__forceinline static wchar_t *php_win32_cp_conv_any_to_w(const char* in, size_t in_len, size_t *out_len)
+{/*{{{*/
+ wchar_t *ret = NULL;
+
+ if (php_win32_cp_use_unicode()) {
+ /* First try the pure ascii conversion. This is the fastest way to do the
+ thing. Only applicable if the source string is UTF-8 in general.
+ While it could possibly be ok with European encodings, usage with
+ Asian encodings can cause unintended side effects. Lookup the term
+ "mojibake" if need more. */
+ ret = php_win32_cp_conv_ascii_to_w(in, in_len, out_len);
+
+ /* If that failed, try to convert to multibyte. */
+ if (!ret) {
+ ret = php_win32_cp_conv_utf8_to_w(in, in_len, out_len);
+
+ /* Still need this fallback with regard to possible broken data
+ in the existing scripts. Broken data might be hardcoded in
+ the user scripts, as UTF-8 settings was de facto ignored in
+ older PHP versions. The fallback can be removed later for
+ the sake of purity, keep now for BC reasons. */
+ if (!ret) {
+ const struct php_win32_cp *acp = php_win32_cp_get_by_id(GetACP());
+
+ if (acp) {
+ ret = php_win32_cp_conv_to_w(acp->id, acp->to_w_fl, in, in_len, out_len);
+ }
+ }
+ }
+ } else {
+ /* No unicode, convert from the current thread cp. */
+ ret = php_win32_cp_conv_cur_to_w(in, in_len, out_len);
+ }
+
+ return ret;
+}/*}}}*/
+#define php_win32_cp_any_to_w(in) php_win32_cp_conv_any_to_w(in, PHP_WIN32_CP_IGNORE_LEN, PHP_WIN32_CP_IGNORE_LEN_P)
+
+/* This function converts from unicode function output back to PHP. If
+ the PHP's current charset is not compatible with unicode, so the currently
+ configured CP will be used. */
+__forceinline static char *php_win32_cp_conv_w_to_any(const wchar_t* in, size_t in_len, size_t *out_len)
+{/*{{{*/
+ return php_win32_cp_conv_w_to_cur(in, in_len, out_len);
+}/*}}}*/
+#define php_win32_cp_w_to_any(in) php_win32_cp_conv_w_to_any(in, PHP_WIN32_CP_IGNORE_LEN, PHP_WIN32_CP_IGNORE_LEN_P)
+
+#define PHP_WIN32_CP_W_TO_ANY_ARRAY(aw, aw_len, aa, aa_len) do { \
+ int i; \
+ aa_len = aw_len; \
+ aa = (char **) malloc(aw_len * sizeof(char *)); \
+ if (!aa) { \
+ break; \
+ } \
+ for (i = 0; i < aw_len; i++) { \
+ aa[i] = php_win32_cp_w_to_any(aw[i]); \
+ } \
+} while (0);
+
+
+#define PHP_WIN32_CP_FREE_ARRAY(a, a_len) do { \
+ int i; \
+ for (i = 0; i < a_len; i++) { \
+ free(a[i]); \
+ } \
+ free(a); \
+} while (0);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PHP_WIN32_CODEPAGE_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */