summaryrefslogtreecommitdiffstats
path: root/lib/util
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
commit8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch)
tree4099e8021376c7d8c05bdf8503093d80e9c7bad0 /lib/util
parentInitial commit. (diff)
downloadsamba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz
samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/util')
-rw-r--r--lib/util/Doxyfile24
-rw-r--r--lib/util/README6
-rw-r--r--lib/util/access.c377
-rw-r--r--lib/util/access.h28
-rw-r--r--lib/util/asn1.c1176
-rw-r--r--lib/util/asn1.h110
-rw-r--r--lib/util/attr.h105
-rw-r--r--lib/util/base64.c169
-rw-r--r--lib/util/base64.h52
-rw-r--r--lib/util/become_daemon.c151
-rw-r--r--lib/util/become_daemon.h89
-rw-r--r--lib/util/binsearch.h121
-rw-r--r--lib/util/bitmap.c144
-rw-r--r--lib/util/bitmap.h29
-rw-r--r--lib/util/blocking.c76
-rw-r--r--lib/util/blocking.h34
-rw-r--r--lib/util/bytearray.h124
-rw-r--r--lib/util/byteorder.h169
-rw-r--r--lib/util/charset/charset.h299
-rw-r--r--lib/util/charset/charset_macosxfs.c605
-rw-r--r--lib/util/charset/charset_proto.h36
-rw-r--r--lib/util/charset/codepoints.c16850
-rw-r--r--lib/util/charset/convert_string.c556
-rw-r--r--lib/util/charset/iconv.c1196
-rw-r--r--lib/util/charset/pull_push.c160
-rw-r--r--lib/util/charset/tests/charset.c342
-rw-r--r--lib/util/charset/tests/convert_string.c2196
-rw-r--r--lib/util/charset/tests/iconv.c495
-rw-r--r--lib/util/charset/tests/util_unistr.c166
-rw-r--r--lib/util/charset/util_str.c608
-rw-r--r--lib/util/charset/util_unistr.c644
-rw-r--r--lib/util/charset/util_unistr_w.c255
-rw-r--r--lib/util/charset/weird.c142
-rw-r--r--lib/util/charset/wscript_build22
-rw-r--r--lib/util/charset/wscript_configure51
-rw-r--r--lib/util/charset_compat.h9
-rw-r--r--lib/util/close_low_fd.c75
-rw-r--r--lib/util/close_low_fd.h28
-rw-r--r--lib/util/data_blob.c298
-rw-r--r--lib/util/data_blob.h144
-rw-r--r--lib/util/debug-classes/debug-classname-table.c62
-rw-r--r--lib/util/debug.c1978
-rw-r--r--lib/util/debug.h396
-rw-r--r--lib/util/debug_s3.c155
-rw-r--r--lib/util/debug_s3.h26
-rw-r--r--lib/util/discard.h51
-rw-r--r--lib/util/dlinklist.h198
-rw-r--r--lib/util/dprintf.c80
-rw-r--r--lib/util/fault.c318
-rw-r--r--lib/util/fault.h59
-rw-r--r--lib/util/fsusage.c160
-rw-r--r--lib/util/genrand.c87
-rw-r--r--lib/util/genrand.h49
-rw-r--r--lib/util/genrand_util.c531
-rw-r--r--lib/util/getpass.c230
-rw-r--r--lib/util/gpfswrap.c296
-rw-r--r--lib/util/gpfswrap.h57
-rw-r--r--lib/util/idtree.c395
-rw-r--r--lib/util/idtree.h63
-rw-r--r--lib/util/idtree_random.c68
-rw-r--r--lib/util/idtree_random.h41
-rw-r--r--lib/util/iov_buf.c43
-rw-r--r--lib/util/iov_buf.h102
-rw-r--r--lib/util/mainpage.dox11
-rw-r--r--lib/util/memcache.c467
-rw-r--r--lib/util/memcache.h119
-rw-r--r--lib/util/memory.h129
-rw-r--r--lib/util/mkdir_p.c70
-rw-r--r--lib/util/mkdir_p.h21
-rw-r--r--lib/util/modules.c320
-rw-r--r--lib/util/ms_fnmatch.c249
-rw-r--r--lib/util/msghdr.c273
-rw-r--r--lib/util/msghdr.h42
-rw-r--r--lib/util/params.c116
-rw-r--r--lib/util/pidfile.c238
-rw-r--r--lib/util/pidfile.h85
-rw-r--r--lib/util/rbtree.c429
-rw-r--r--lib/util/rbtree.h132
-rw-r--r--lib/util/rfc1738.c198
-rw-r--r--lib/util/safe_string.h64
-rw-r--r--lib/util/samba-util.pc.in11
-rw-r--r--lib/util/samba_modules.h61
-rw-r--r--lib/util/samba_util.h708
-rw-r--r--lib/util/select.c61
-rw-r--r--lib/util/select.h29
-rw-r--r--lib/util/server_id.c229
-rw-r--r--lib/util/server_id.h57
-rw-r--r--lib/util/server_id_db.c355
-rw-r--r--lib/util/server_id_db.h50
-rw-r--r--lib/util/setid.c249
-rw-r--r--lib/util/setid.h43
-rw-r--r--lib/util/signal.c146
-rw-r--r--lib/util/signal.h50
-rw-r--r--lib/util/smb_strtox.c177
-rw-r--r--lib/util/smb_strtox.h40
-rw-r--r--lib/util/smb_threads.c206
-rw-r--r--lib/util/smb_threads.h137
-rw-r--r--lib/util/smb_threads_internal.h74
-rw-r--r--lib/util/stable_sort.c250
-rw-r--r--lib/util/stable_sort.h46
-rw-r--r--lib/util/string_wrappers.h99
-rw-r--r--lib/util/strv.c191
-rw-r--r--lib/util/strv.h37
-rw-r--r--lib/util/strv_util.c61
-rw-r--r--lib/util/strv_util.h30
-rw-r--r--lib/util/substitute.c280
-rw-r--r--lib/util/substitute.h64
-rw-r--r--lib/util/sys_popen.c177
-rw-r--r--lib/util/sys_popen.h26
-rw-r--r--lib/util/sys_rw.c295
-rw-r--r--lib/util/sys_rw.h45
-rw-r--r--lib/util/sys_rw_data.c117
-rw-r--r--lib/util/sys_rw_data.h34
-rw-r--r--lib/util/system.c65
-rw-r--r--lib/util/talloc_keep_secret.c67
-rw-r--r--lib/util/talloc_keep_secret.h42
-rw-r--r--lib/util/talloc_report.c184
-rw-r--r--lib/util/talloc_report.h27
-rw-r--r--lib/util/talloc_report_printf.c134
-rw-r--r--lib/util/talloc_report_printf.h29
-rw-r--r--lib/util/talloc_stack.c259
-rw-r--r--lib/util/talloc_stack.h66
-rw-r--r--lib/util/tests/README22
-rw-r--r--lib/util/tests/anonymous_shared.c70
-rw-r--r--lib/util/tests/asn1_tests.c383
-rw-r--r--lib/util/tests/binsearch.c173
-rw-r--r--lib/util/tests/data_blob.c172
-rw-r--r--lib/util/tests/dlinklist.c131
-rw-r--r--lib/util/tests/file.c291
-rw-r--r--lib/util/tests/genrand.c61
-rw-r--r--lib/util/tests/genrandperf.c39
-rw-r--r--lib/util/tests/idtree.c123
-rw-r--r--lib/util/tests/rfc1738.c411
-rw-r--r--lib/util/tests/str.c180
-rw-r--r--lib/util/tests/strlist.c558
-rw-r--r--lib/util/tests/strv.c201
-rw-r--r--lib/util/tests/strv_util.c150
-rw-r--r--lib/util/tests/test_bytearray.c435
-rw-r--r--lib/util/tests/test_byteorder.c435
-rw-r--r--lib/util/tests/test_byteorder_verify.c273
-rw-r--r--lib/util/tests/test_logging.c146
-rw-r--r--lib/util/tests/test_memcache.c161
-rw-r--r--lib/util/tests/test_ms_fnmatch.c114
-rw-r--r--lib/util/tests/test_stable_sort.c317
-rw-r--r--lib/util/tests/test_sys_rw.c178
-rw-r--r--lib/util/tests/test_talloc_keep_secret.c94
-rw-r--r--lib/util/tests/test_util.c344
-rw-r--r--lib/util/tests/test_util_paths.c127
-rw-r--r--lib/util/tests/tfork-drd.supp14
-rw-r--r--lib/util/tests/tfork-helgrind.supp32
-rw-r--r--lib/util/tests/tfork.c855
-rw-r--r--lib/util/tests/time.c151
-rw-r--r--lib/util/tests/util.c652
-rw-r--r--lib/util/tests/util_str_escape.c90
-rw-r--r--lib/util/tevent_debug.c116
-rw-r--r--lib/util/tevent_ntstatus.c114
-rw-r--r--lib/util/tevent_ntstatus.h47
-rw-r--r--lib/util/tevent_req_profile.c506
-rw-r--r--lib/util/tevent_req_profile.h46
-rw-r--r--lib/util/tevent_unix.c73
-rw-r--r--lib/util/tevent_unix.h34
-rw-r--r--lib/util/tevent_werror.c94
-rw-r--r--lib/util/tevent_werror.h46
-rw-r--r--lib/util/tfork.c944
-rw-r--r--lib/util/tfork.h111
-rw-r--r--lib/util/tftw.c129
-rw-r--r--lib/util/tftw.h32
-rw-r--r--lib/util/time.c1494
-rw-r--r--lib/util/time.h404
-rw-r--r--lib/util/time_basic.c99
-rw-r--r--lib/util/time_basic.h49
-rw-r--r--lib/util/tini.c320
-rw-r--r--lib/util/tini.h45
-rw-r--r--lib/util/tiniparser.c390
-rw-r--r--lib/util/tiniparser.h56
-rw-r--r--lib/util/tsort.h40
-rw-r--r--lib/util/unix_match.c183
-rw-r--r--lib/util/unix_match.h25
-rw-r--r--lib/util/unix_privs.c92
-rw-r--r--lib/util/util.c1335
-rw-r--r--lib/util/util.h94
-rw-r--r--lib/util/util_file.c498
-rw-r--r--lib/util/util_id.c89
-rw-r--r--lib/util/util_ldb.c114
-rw-r--r--lib/util/util_ldb.h50
-rw-r--r--lib/util/util_net.c1240
-rw-r--r--lib/util/util_net.h145
-rw-r--r--lib/util/util_paths.c170
-rw-r--r--lib/util/util_paths.h63
-rw-r--r--lib/util/util_process.c101
-rw-r--r--lib/util/util_process.h84
-rw-r--r--lib/util/util_pw.c99
-rw-r--r--lib/util/util_pw.h32
-rw-r--r--lib/util/util_runcmd.c379
-rw-r--r--lib/util/util_str.c307
-rw-r--r--lib/util/util_str_common.c154
-rw-r--r--lib/util/util_str_escape.c127
-rw-r--r--lib/util/util_str_escape.h27
-rw-r--r--lib/util/util_str_hex.c69
-rw-r--r--lib/util/util_str_hex.h5
-rw-r--r--lib/util/util_strlist.c561
-rw-r--r--lib/util/util_strlist.h156
-rw-r--r--lib/util/util_strlist_v3.c128
-rw-r--r--lib/util/util_tdb.c525
-rw-r--r--lib/util/util_tdb.h125
-rw-r--r--lib/util/wscript32
-rw-r--r--lib/util/wscript_build415
-rw-r--r--lib/util/wscript_configure189
208 files changed, 62062 insertions, 0 deletions
diff --git a/lib/util/Doxyfile b/lib/util/Doxyfile
new file mode 100644
index 0000000..02e36a7
--- /dev/null
+++ b/lib/util/Doxyfile
@@ -0,0 +1,24 @@
+PROJECT_NAME = SAMBA_UTIL
+OUTPUT_DIRECTORY = apidocs
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+OPTIMIZE_OUTPUT_FOR_C = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+GENERATE_TODOLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+SHOW_USED_FILES = NO
+SHOW_DIRECTORIES = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+INPUT = .
+FILE_PATTERNS = *.c *.h *.dox
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+GENERATE_MAN = YES
+ALWAYS_DETAILED_SEC = YES
+JAVADOC_AUTOBRIEF = YES
diff --git a/lib/util/README b/lib/util/README
new file mode 100644
index 0000000..fffd44d
--- /dev/null
+++ b/lib/util/README
@@ -0,0 +1,6 @@
+This directory contains libutil (until we can think of a better name)
+
+The idea is that this library contains simple but useful data structures
+and support functions that are generally useful; not just for Samba but for
+other projects as well. Functions here should not depend on any external
+libraries, just on libc (perhaps partially provided by libreplace).
diff --git a/lib/util/access.c b/lib/util/access.c
new file mode 100644
index 0000000..fd9912d
--- /dev/null
+++ b/lib/util/access.c
@@ -0,0 +1,377 @@
+/*
+ This module is an adaption of code from the tcpd-1.4 package written
+ by Wietse Venema, Eindhoven University of Technology, The Netherlands.
+
+ The code is used here with permission.
+
+ The code has been considerably changed from the original. Bug reports
+ should be sent to samba-technical@lists.samba.org
+
+ Updated for IPv6 by Jeremy Allison (C) 2007.
+*/
+
+#include "replace.h"
+#include "system/locale.h"
+#include "lib/util/debug.h"
+#include "../lib/util/memcache.h"
+#include "lib/socket/interfaces.h"
+#include "lib/util/samba_util.h"
+#include "lib/util/util_net.h"
+#include "lib/util/samba_util.h"
+#include "lib/util/memory.h"
+#include "lib/util/access.h"
+#include "lib/util/unix_match.h"
+#include "lib/util/smb_strtox.h"
+
+#define NAME_INDEX 0
+#define ADDR_INDEX 1
+
+/* masked_match - match address against netnumber/netmask */
+static bool masked_match(const char *tok, const char *slash, const char *s)
+{
+ struct sockaddr_storage ss_mask;
+ struct sockaddr_storage ss_tok;
+ struct sockaddr_storage ss_host;
+ char *tok_copy = NULL;
+
+ if (!interpret_string_addr(&ss_host, s, 0)) {
+ return false;
+ }
+
+ if (*tok == '[') {
+ /* IPv6 address - remove braces. */
+ tok_copy = smb_xstrdup(tok+1);
+ if (!tok_copy) {
+ return false;
+ }
+ /* Remove the terminating ']' */
+ tok_copy[PTR_DIFF(slash,tok)-1] = '\0';
+ } else {
+ tok_copy = smb_xstrdup(tok);
+ if (!tok_copy) {
+ return false;
+ }
+ /* Remove the terminating '/' */
+ tok_copy[PTR_DIFF(slash,tok)] = '\0';
+ }
+
+ if (!interpret_string_addr(&ss_tok, tok_copy, 0)) {
+ SAFE_FREE(tok_copy);
+ return false;
+ }
+
+ SAFE_FREE(tok_copy);
+
+ if (strlen(slash + 1) > 2) {
+ if (!interpret_string_addr(&ss_mask, slash+1, 0)) {
+ return false;
+ }
+ } else {
+ int error = 0;
+ unsigned long val;
+
+ val = smb_strtoul(slash+1,
+ NULL,
+ 0,
+ &error,
+ SMB_STR_FULL_STR_CONV);
+ if (error != 0) {
+ return false;
+ }
+ if (!make_netmask(&ss_mask, &ss_tok, val)) {
+ return false;
+ }
+ }
+
+ return same_net((struct sockaddr *)(void *)&ss_host,
+ (struct sockaddr *)(void *)&ss_tok,
+ (struct sockaddr *)(void *)&ss_mask);
+}
+
+/* string_match - match string s against token tok */
+static bool string_match(const char *tok,const char *s)
+{
+ size_t tok_len;
+ size_t str_len;
+ const char *cut;
+
+ /* Return true if a token has the magic value "ALL". Return
+ * true if the token is "FAIL". If the token starts with a "."
+ * (domain name), return true if it matches the last fields of
+ * the string. If the token has the magic value "LOCAL",
+ * return true if the string does not contain a "."
+ * character. If the token ends on a "." (network number),
+ * return true if it matches the first fields of the
+ * string. If the token begins with a "@" (netgroup name),
+ * return true if the string is a (host) member of the
+ * netgroup. Return true if the token fully matches the
+ * string. If the token is a netnumber/netmask pair, return
+ * true if the address is a member of the specified subnet.
+ */
+
+ if (tok[0] == '.') { /* domain: match last fields */
+ if ((str_len = strlen(s)) > (tok_len = strlen(tok))
+ && strequal_m(tok, s + str_len - tok_len)) {
+ return true;
+ }
+ } else if (tok[0] == '@') { /* netgroup: look it up */
+#if defined(HAVE_NETGROUP) && defined(HAVE_INNETGR)
+ DATA_BLOB tmp;
+ char *mydomain = NULL;
+ char *hostname = NULL;
+ bool netgroup_ok = false;
+ char nis_domain_buf[256];
+
+ if (memcache_lookup(
+ NULL, SINGLETON_CACHE,
+ data_blob_string_const_null("yp_default_domain"),
+ &tmp)) {
+
+ SMB_ASSERT(tmp.length > 0);
+ mydomain = (tmp.data[0] == '\0')
+ ? NULL : (char *)tmp.data;
+ } else {
+ if (getdomainname(nis_domain_buf,
+ sizeof(nis_domain_buf)) == 0) {
+ mydomain = &nis_domain_buf[0];
+ memcache_add(NULL,
+ SINGLETON_CACHE,
+ data_blob_string_const_null(
+ "yp_default_domain"),
+ data_blob_string_const_null(
+ mydomain));
+ } else {
+ mydomain = NULL;
+ }
+ }
+
+ if (!mydomain) {
+ DEBUG(0,("Unable to get default yp domain. "
+ "Try without it.\n"));
+ }
+ if (!(hostname = smb_xstrdup(s))) {
+ DEBUG(1,("out of memory for strdup!\n"));
+ return false;
+ }
+
+ netgroup_ok = innetgr(tok + 1, hostname, (char *) 0, mydomain);
+
+ DBG_INFO("%s %s of domain %s in netgroup %s\n",
+ netgroup_ok ? "Found" : "Could not find",
+ hostname,
+ mydomain?mydomain:"(ANY)",
+ tok+1);
+
+ SAFE_FREE(hostname);
+
+ if (netgroup_ok)
+ return true;
+#else
+ DEBUG(0,("access: netgroup support is not configured\n"));
+ return false;
+#endif
+ } else if (strequal_m(tok, "ALL")) { /* all: match any */
+ return true;
+ } else if (strequal_m(tok, "FAIL")) { /* fail: match any */
+ return true;
+ } else if (strequal_m(tok, "LOCAL")) { /* local: no dots */
+ if (strchr_m(s, '.') == 0 && !strequal_m(s, "unknown")) {
+ return true;
+ }
+ } else if (strequal_m(tok, s)) { /* match host name or address */
+ return true;
+ } else if (tok[(tok_len = strlen(tok)) - 1] == '.') { /* network */
+ if (strncmp(tok, s, tok_len) == 0) {
+ return true;
+ }
+ } else if ((cut = strchr_m(tok, '/')) != 0) { /* netnumber/netmask */
+ if ((isdigit(s[0]) && strchr_m(tok, '.') != NULL) ||
+ (tok[0] == '[' && cut > tok && cut[-1] == ']') ||
+ ((isxdigit(s[0]) || s[0] == ':') &&
+ strchr_m(tok, ':') != NULL)) {
+ /* IPv4/netmask or
+ * [IPv6:addr]/netmask or IPv6:addr/netmask */
+ return masked_match(tok, cut, s);
+ }
+ } else if (strchr_m(tok, '*') != 0 || strchr_m(tok, '?')) {
+ return unix_wild_match(tok, s);
+ }
+ return false;
+}
+
+/* client_match - match host name and address against token */
+bool client_match(const char *tok, const void *item)
+{
+ const char **client = discard_const_p(const char *, item);
+ const char *tok_addr = tok;
+ const char *cli_addr = client[ADDR_INDEX];
+
+ /*
+ * tok and client[ADDR_INDEX] can be an IPv4 mapped to IPv6,
+ * we try and match the IPv4 part of address only.
+ * Bug #5311 and #7383.
+ */
+
+ if (strncasecmp_m(tok_addr, "::ffff:", 7) == 0) {
+ tok_addr += 7;
+ }
+
+ if (strncasecmp_m(cli_addr, "::ffff:", 7) == 0) {
+ cli_addr += 7;
+ }
+
+ /*
+ * Try to match the address first. If that fails, try to match the host
+ * name if available.
+ */
+
+ if (string_match(tok_addr, cli_addr)) {
+ return true;
+ }
+
+ if (client[NAME_INDEX][0] != 0) {
+ if (string_match(tok, client[NAME_INDEX])) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* list_match - match an item against a list of tokens with exceptions */
+bool list_match(const char **list,const void *item,
+ bool (*match_fn)(const char *, const void *))
+{
+ bool match = false;
+
+ if (!list) {
+ return false;
+ }
+
+ /*
+ * Process tokens one at a time. We have exhausted all possible matches
+ * when we reach an "EXCEPT" token or the end of the list. If we do find
+ * a match, look for an "EXCEPT" list and recurse to determine whether
+ * the match is affected by any exceptions.
+ */
+
+ for (; *list ; list++) {
+ if (strequal_m(*list, "EXCEPT")) {
+ /* EXCEPT: give up */
+ break;
+ }
+ if ((match = (*match_fn) (*list, item))) {
+ /* true or FAIL */
+ break;
+ }
+ }
+ /* Process exceptions to true or FAIL matches. */
+
+ if (match != false) {
+ while (*list && !strequal_m(*list, "EXCEPT")) {
+ list++;
+ }
+
+ for (; *list; list++) {
+ if ((*match_fn) (*list, item)) {
+ /* Exception Found */
+ return false;
+ }
+ }
+ }
+
+ return match;
+}
+
+/* return true if access should be allowed */
+static bool allow_access_internal(const char **deny_list,
+ const char **allow_list,
+ const char *cname,
+ const char *caddr)
+{
+ const char *client[2];
+
+ client[NAME_INDEX] = cname;
+ client[ADDR_INDEX] = caddr;
+
+ /* if it is loopback then always allow unless specifically denied */
+ if (strcmp(caddr, "127.0.0.1") == 0 || strcmp(caddr, "::1") == 0) {
+ /*
+ * If 127.0.0.1 matches both allow and deny then allow.
+ * Patch from Steve Langasek vorlon@netexpress.net.
+ */
+ if (deny_list &&
+ list_match(deny_list,client,client_match) &&
+ (!allow_list ||
+ !list_match(allow_list,client, client_match))) {
+ return false;
+ }
+ return true;
+ }
+
+ /* if there's no deny list and no allow list then allow access */
+ if ((!deny_list || *deny_list == 0) &&
+ (!allow_list || *allow_list == 0)) {
+ return true;
+ }
+
+ /* if there is an allow list but no deny list then allow only hosts
+ on the allow list */
+ if (!deny_list || *deny_list == 0) {
+ return(list_match(allow_list,client,client_match));
+ }
+
+ /* if there's a deny list but no allow list then allow
+ all hosts not on the deny list */
+ if (!allow_list || *allow_list == 0) {
+ return(!list_match(deny_list,client,client_match));
+ }
+
+ /* if there are both types of list then allow all hosts on the
+ allow list */
+ if (list_match(allow_list,(const char *)client,client_match)) {
+ return true;
+ }
+
+ /* if there are both types of list and it's not on the allow then
+ allow it if its not on the deny */
+ if (list_match(deny_list,(const char *)client,client_match)) {
+ return false;
+ }
+
+ return true;
+}
+
+/* return true if access should be allowed - doesn't print log message */
+bool allow_access_nolog(const char **deny_list,
+ const char **allow_list,
+ const char *cname,
+ const char *caddr)
+{
+ bool ret;
+ char *nc_cname = smb_xstrdup(cname);
+ char *nc_caddr = smb_xstrdup(caddr);
+
+ ret = allow_access_internal(deny_list, allow_list, nc_cname, nc_caddr);
+
+ SAFE_FREE(nc_cname);
+ SAFE_FREE(nc_caddr);
+ return ret;
+}
+
+/* return true if access should be allowed - prints log message */
+bool allow_access(const char **deny_list,
+ const char **allow_list,
+ const char *cname,
+ const char *caddr)
+{
+ bool ret;
+
+ ret = allow_access_nolog(deny_list, allow_list, cname, caddr);
+
+ DEBUG(ret ? 3 : 0,
+ ("%s connection from %s (%s)\n",
+ ret ? "Allowed" : "Denied", cname, caddr));
+
+ return ret;
+}
diff --git a/lib/util/access.h b/lib/util/access.h
new file mode 100644
index 0000000..73f71b6
--- /dev/null
+++ b/lib/util/access.h
@@ -0,0 +1,28 @@
+/*
+ This module is an adaption of code from the tcpd-1.4 package written
+ by Wietse Venema, Eindhoven University of Technology, The Netherlands.
+
+ The code is used here with permission.
+
+ The code has been considerably changed from the original. Bug reports
+ should be sent to samba-technical@lists.samba.org
+
+ Updated for IPv6 by Jeremy Allison (C) 2007.
+*/
+
+#ifndef _UTIL_ACCESS_H_
+#define _UTIL_ACCESS_H_
+
+bool client_match(const char *tok, const void *item);
+bool list_match(const char **list,const void *item,
+ bool (*match_fn)(const char *, const void *));
+bool allow_access_nolog(const char **deny_list,
+ const char **allow_list,
+ const char *cname,
+ const char *caddr);
+bool allow_access(const char **deny_list,
+ const char **allow_list,
+ const char *cname,
+ const char *caddr);
+
+#endif
diff --git a/lib/util/asn1.c b/lib/util/asn1.c
new file mode 100644
index 0000000..1a92a55
--- /dev/null
+++ b/lib/util/asn1.c
@@ -0,0 +1,1176 @@
+/*
+ Unix SMB/CIFS implementation.
+ simple ASN1 routines
+ Copyright (C) Andrew Tridgell 2001
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/locale.h"
+#include "lib/util/asn1.h"
+#include "lib/util/debug.h"
+#include "lib/util/samba_util.h"
+#include "lib/util/smb_strtox.h"
+
+struct nesting {
+ off_t start;
+ size_t taglen; /* for parsing */
+ struct nesting *next;
+};
+
+
+struct asn1_data {
+ uint8_t *data;
+ size_t length;
+ off_t ofs;
+ struct nesting *nesting;
+ bool has_error;
+ unsigned depth;
+ unsigned max_depth;
+};
+
+/* allocate an asn1 structure */
+struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx, unsigned max_depth)
+{
+ struct asn1_data *ret = talloc_zero(mem_ctx, struct asn1_data);
+ if (ret == NULL) {
+ DBG_ERR("asn1_init failed! out of memory\n");
+ return ret;
+ }
+ ret->max_depth = max_depth;
+ return ret;
+}
+
+/* free an asn1 structure */
+void asn1_free(struct asn1_data *data)
+{
+ talloc_free(data);
+}
+
+bool asn1_has_error(const struct asn1_data *data)
+{
+ return data->has_error;
+}
+
+void asn1_set_error(struct asn1_data *data)
+{
+ data->has_error = true;
+}
+
+bool asn1_has_nesting(const struct asn1_data *data)
+{
+ return data->nesting != NULL;
+}
+
+off_t asn1_current_ofs(const struct asn1_data *data)
+{
+ return data->ofs;
+}
+
+/* write to the ASN1 buffer, advancing the buffer pointer */
+bool asn1_write(struct asn1_data *data, const void *p, int len)
+{
+ if (data->has_error) return false;
+
+ if ((len < 0) || (data->ofs + (size_t)len < data->ofs)) {
+ data->has_error = true;
+ return false;
+ }
+
+ if (data->length < data->ofs+len) {
+ uint8_t *newp;
+ newp = talloc_realloc(data, data->data, uint8_t, data->ofs+len);
+ if (!newp) {
+ data->has_error = true;
+ return false;
+ }
+ data->data = newp;
+ data->length = data->ofs+len;
+ }
+ if (len > 0) {
+ memcpy(data->data + data->ofs, p, len);
+ data->ofs += len;
+ }
+ return true;
+}
+
+/* useful fn for writing a uint8_t */
+bool asn1_write_uint8(struct asn1_data *data, uint8_t v)
+{
+ return asn1_write(data, &v, 1);
+}
+
+/* push a tag onto the asn1 data buffer. Used for nested structures */
+bool asn1_push_tag(struct asn1_data *data, uint8_t tag)
+{
+ struct nesting *nesting;
+
+ if (!asn1_write_uint8(data, tag)) {
+ return false;
+ }
+ nesting = talloc(data, struct nesting);
+ if (!nesting) {
+ data->has_error = true;
+ return false;
+ }
+
+ nesting->start = data->ofs;
+ nesting->next = data->nesting;
+ data->nesting = nesting;
+ return asn1_write_uint8(data, 0xff);
+}
+
+/* pop a tag */
+bool asn1_pop_tag(struct asn1_data *data)
+{
+ struct nesting *nesting;
+ size_t len;
+
+ if (data->has_error) {
+ return false;
+ }
+
+ nesting = data->nesting;
+
+ if (!nesting) {
+ data->has_error = true;
+ return false;
+ }
+ len = data->ofs - (nesting->start+1);
+ /* yes, this is ugly. We don't know in advance how many bytes the length
+ of a tag will take, so we assumed 1 byte. If we were wrong then we
+ need to correct our mistake */
+ if (len > 0xFFFFFF) {
+ data->data[nesting->start] = 0x84;
+ if (!asn1_write_uint8(data, 0)) return false;
+ if (!asn1_write_uint8(data, 0)) return false;
+ if (!asn1_write_uint8(data, 0)) return false;
+ if (!asn1_write_uint8(data, 0)) return false;
+ memmove(data->data+nesting->start+5, data->data+nesting->start+1, len);
+ data->data[nesting->start+1] = (len>>24) & 0xFF;
+ data->data[nesting->start+2] = (len>>16) & 0xFF;
+ data->data[nesting->start+3] = (len>>8) & 0xFF;
+ data->data[nesting->start+4] = len&0xff;
+ } else if (len > 0xFFFF) {
+ data->data[nesting->start] = 0x83;
+ if (!asn1_write_uint8(data, 0)) return false;
+ if (!asn1_write_uint8(data, 0)) return false;
+ if (!asn1_write_uint8(data, 0)) return false;
+ memmove(data->data+nesting->start+4, data->data+nesting->start+1, len);
+ data->data[nesting->start+1] = (len>>16) & 0xFF;
+ data->data[nesting->start+2] = (len>>8) & 0xFF;
+ data->data[nesting->start+3] = len&0xff;
+ } else if (len > 255) {
+ data->data[nesting->start] = 0x82;
+ if (!asn1_write_uint8(data, 0)) return false;
+ if (!asn1_write_uint8(data, 0)) return false;
+ memmove(data->data+nesting->start+3, data->data+nesting->start+1, len);
+ data->data[nesting->start+1] = len>>8;
+ data->data[nesting->start+2] = len&0xff;
+ } else if (len > 127) {
+ data->data[nesting->start] = 0x81;
+ if (!asn1_write_uint8(data, 0)) return false;
+ memmove(data->data+nesting->start+2, data->data+nesting->start+1, len);
+ data->data[nesting->start+1] = len;
+ } else {
+ data->data[nesting->start] = len;
+ }
+
+ data->nesting = nesting->next;
+ talloc_free(nesting);
+ return true;
+}
+
+/* "i" is the one's complement representation, as is the normal result of an
+ * implicit signed->unsigned conversion */
+
+static bool push_int_bigendian(struct asn1_data *data, unsigned int i, bool negative)
+{
+ uint8_t lowest = i & 0xFF;
+
+ i = i >> 8;
+ if (i != 0)
+ if (!push_int_bigendian(data, i, negative))
+ return false;
+
+ if (data->nesting->start+1 == data->ofs) {
+
+ /* We did not write anything yet, looking at the highest
+ * valued byte */
+
+ if (negative) {
+ /* Don't write leading 0xff's */
+ if (lowest == 0xFF)
+ return true;
+
+ if ((lowest & 0x80) == 0) {
+ /* The only exception for a leading 0xff is if
+ * the highest bit is 0, which would indicate
+ * a positive value */
+ if (!asn1_write_uint8(data, 0xff))
+ return false;
+ }
+ } else {
+ if (lowest & 0x80) {
+ /* The highest bit of a positive integer is 1,
+ * this would indicate a negative number. Push
+ * a 0 to indicate a positive one */
+ if (!asn1_write_uint8(data, 0))
+ return false;
+ }
+ }
+ }
+
+ return asn1_write_uint8(data, lowest);
+}
+
+/* write an Integer without the tag framing. Needed for example for the LDAP
+ * Abandon Operation */
+
+bool asn1_write_implicit_Integer(struct asn1_data *data, int i)
+{
+ if (data->has_error) {
+ return false;
+ }
+
+ if (i == -1) {
+ /* -1 is special as it consists of all-0xff bytes. In
+ push_int_bigendian this is the only case that is not
+ properly handled, as all 0xff bytes would be handled as
+ leading ones to be ignored. */
+ return asn1_write_uint8(data, 0xff);
+ } else {
+ return push_int_bigendian(data, i, i<0);
+ }
+}
+
+
+/* write an integer */
+bool asn1_write_Integer(struct asn1_data *data, int i)
+{
+ if (!asn1_push_tag(data, ASN1_INTEGER)) return false;
+ if (!asn1_write_implicit_Integer(data, i)) return false;
+ return asn1_pop_tag(data);
+}
+
+/* write a BIT STRING */
+bool asn1_write_BitString(struct asn1_data *data, const void *p, size_t length, uint8_t padding)
+{
+ if (!asn1_push_tag(data, ASN1_BIT_STRING)) return false;
+ if (!asn1_write_uint8(data, padding)) return false;
+ if (!asn1_write(data, p, length)) return false;
+ return asn1_pop_tag(data);
+}
+
+bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID)
+{
+ unsigned int v, v2;
+ const char *p = (const char *)OID;
+ char *newp;
+ int i;
+ int error = 0;
+
+ if (!isdigit(*p)) return false;
+ v = smb_strtoul(p, &newp, 10, &error, SMB_STR_STANDARD);
+ if (newp[0] != '.' || error != 0) {
+ return false;
+ }
+ p = newp + 1;
+
+ if (!isdigit(*p)) return false;
+ v2 = smb_strtoul(p, &newp, 10, &error, SMB_STR_STANDARD);
+ if (newp[0] != '.' || error != 0) {
+ return false;
+ }
+ p = newp + 1;
+
+ /*the ber representation can't use more space than the string one */
+ *blob = data_blob_talloc(mem_ctx, NULL, strlen(OID));
+ if (!blob->data) return false;
+
+ blob->data[0] = 40*v + v2;
+
+ i = 1;
+ while (*p) {
+ if (!isdigit(*p)) return false;
+ v = smb_strtoul(p, &newp, 10, &error, SMB_STR_STANDARD);
+ if (newp[0] == '.' || error != 0) {
+ p = newp + 1;
+ /* check for empty last component */
+ if (!*p) return false;
+ } else if (newp[0] == '\0') {
+ p = newp;
+ } else {
+ data_blob_free(blob);
+ return false;
+ }
+ if (v >= (1<<28)) blob->data[i++] = (0x80 | ((v>>28)&0x7f));
+ if (v >= (1<<21)) blob->data[i++] = (0x80 | ((v>>21)&0x7f));
+ if (v >= (1<<14)) blob->data[i++] = (0x80 | ((v>>14)&0x7f));
+ if (v >= (1<<7)) blob->data[i++] = (0x80 | ((v>>7)&0x7f));
+ blob->data[i++] = (v&0x7f);
+ }
+
+ blob->length = i;
+
+ return true;
+}
+
+/**
+ * Serialize partial OID string.
+ * Partial OIDs are in the form:
+ * 1:2.5.6:0x81
+ * 1:2.5.6:0x8182
+ */
+bool ber_write_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *partial_oid)
+{
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ char *oid = talloc_strdup(tmp_ctx, partial_oid);
+ char *p;
+
+ /* truncate partial part so ber_write_OID_String() works */
+ p = strchr(oid, ':');
+ if (p) {
+ *p = '\0';
+ p++;
+ }
+
+ if (!ber_write_OID_String(mem_ctx, blob, oid)) {
+ talloc_free(tmp_ctx);
+ return false;
+ }
+
+ /* Add partially encoded sub-identifier */
+ if (p) {
+ DATA_BLOB tmp_blob = strhex_to_data_blob(tmp_ctx, p);
+ if (!data_blob_append(mem_ctx, blob, tmp_blob.data,
+ tmp_blob.length)) {
+ talloc_free(tmp_ctx);
+ return false;
+ }
+ }
+
+ talloc_free(tmp_ctx);
+
+ return true;
+}
+
+/* write an object ID to a ASN1 buffer */
+bool asn1_write_OID(struct asn1_data *data, const char *OID)
+{
+ DATA_BLOB blob;
+
+ if (!asn1_push_tag(data, ASN1_OID)) return false;
+
+ if (!ber_write_OID_String(NULL, &blob, OID)) {
+ data->has_error = true;
+ return false;
+ }
+
+ if (!asn1_write(data, blob.data, blob.length)) {
+ data_blob_free(&blob);
+ data->has_error = true;
+ return false;
+ }
+ data_blob_free(&blob);
+ return asn1_pop_tag(data);
+}
+
+/* write an octet string */
+bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length)
+{
+ if (!asn1_push_tag(data, ASN1_OCTET_STRING)) return false;
+ if (!asn1_write(data, p, length)) return false;
+ return asn1_pop_tag(data);
+}
+
+/* write a LDAP string */
+bool asn1_write_LDAPString(struct asn1_data *data, const char *s)
+{
+ return asn1_write(data, s, strlen(s));
+}
+
+/* write a LDAP string from a DATA_BLOB */
+bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s)
+{
+ return asn1_write(data, s->data, s->length);
+}
+
+/* write a general string */
+bool asn1_write_GeneralString(struct asn1_data *data, const char *s)
+{
+ if (!asn1_push_tag(data, ASN1_GENERAL_STRING)) return false;
+ if (!asn1_write_LDAPString(data, s)) return false;
+ return asn1_pop_tag(data);
+}
+
+bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob)
+{
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false;
+ if (!asn1_write(data, blob->data, blob->length)) return false;
+ return asn1_pop_tag(data);
+}
+
+/* write a BOOLEAN */
+bool asn1_write_BOOLEAN(struct asn1_data *data, bool v)
+{
+ if (!asn1_push_tag(data, ASN1_BOOLEAN)) return false;
+ if (!asn1_write_uint8(data, v ? 0xFF : 0)) return false;
+ return asn1_pop_tag(data);
+}
+
+bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v)
+{
+ uint8_t tmp = 0;
+ if (!asn1_start_tag(data, ASN1_BOOLEAN)) return false;
+ *v = false;
+ if (!asn1_read_uint8(data, &tmp)) return false;
+ if (tmp == 0xFF) {
+ *v = true;
+ }
+ return asn1_end_tag(data);
+}
+
+/* write a BOOLEAN in a simple context */
+bool asn1_write_BOOLEAN_context(struct asn1_data *data, bool v, int context)
+{
+ if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(context))) return false;
+ if (!asn1_write_uint8(data, v ? 0xFF : 0)) return false;
+ return asn1_pop_tag(data);
+}
+
+bool asn1_read_BOOLEAN_context(struct asn1_data *data, bool *v, int context)
+{
+ uint8_t tmp = 0;
+ if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(context))) return false;
+ *v = false;
+ if (!asn1_read_uint8(data, &tmp)) return false;
+ if (tmp == 0xFF) {
+ *v = true;
+ }
+ return asn1_end_tag(data);
+}
+
+/* check a BOOLEAN */
+bool asn1_check_BOOLEAN(struct asn1_data *data, bool v)
+{
+ uint8_t b = 0;
+
+ if (!asn1_read_uint8(data, &b)) return false;
+ if (b != ASN1_BOOLEAN) {
+ data->has_error = true;
+ return false;
+ }
+ if (!asn1_read_uint8(data, &b)) return false;
+ if (b != v) {
+ data->has_error = true;
+ return false;
+ }
+ return !data->has_error;
+}
+
+
+/* load a struct asn1_data structure with a lump of data, ready to be parsed */
+bool asn1_load(struct asn1_data *data, DATA_BLOB blob)
+{
+ /*
+ * Save the maximum depth
+ */
+ unsigned max_depth = data->max_depth;
+
+ ZERO_STRUCTP(data);
+ data->data = (uint8_t *)talloc_memdup(data, blob.data, blob.length);
+ if (!data->data) {
+ data->has_error = true;
+ return false;
+ }
+ data->length = blob.length;
+ data->max_depth = max_depth;
+ return true;
+}
+
+/* Peek into an ASN1 buffer, not advancing the pointer */
+bool asn1_peek(struct asn1_data *data, void *p, int len)
+{
+ if (data->has_error)
+ return false;
+
+ if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len)
+ return false;
+
+ if (data->ofs + len > data->length) {
+ /* we need to mark the buffer as consumed, so the caller knows
+ this was an out of data error, and not a decode error */
+ data->ofs = data->length;
+ return false;
+ }
+
+ memcpy(p, data->data + data->ofs, len);
+ return true;
+}
+
+/* read from a ASN1 buffer, advancing the buffer pointer */
+bool asn1_read(struct asn1_data *data, void *p, int len)
+{
+ if (!asn1_peek(data, p, len)) {
+ data->has_error = true;
+ return false;
+ }
+
+ data->ofs += len;
+ return true;
+}
+
+/* read a uint8_t from a ASN1 buffer */
+bool asn1_read_uint8(struct asn1_data *data, uint8_t *v)
+{
+ return asn1_read(data, v, 1);
+}
+
+bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v)
+{
+ return asn1_peek(data, v, 1);
+}
+
+bool asn1_peek_tag(struct asn1_data *data, uint8_t tag)
+{
+ uint8_t b;
+
+ if (asn1_tag_remaining(data) <= 0) {
+ return false;
+ }
+
+ if (!asn1_peek_uint8(data, &b))
+ return false;
+
+ return (b == tag);
+}
+
+/*
+ * just get the needed size the tag would consume
+ */
+static bool asn1_peek_tag_needed_size(struct asn1_data *data, uint8_t tag,
+ size_t *size)
+{
+ off_t start_ofs = data->ofs;
+ uint8_t b;
+ size_t taglen = 0;
+
+ if (data->has_error) {
+ return false;
+ }
+
+ if (!asn1_read_uint8(data, &b)) {
+ data->ofs = start_ofs;
+ data->has_error = false;
+ return false;
+ }
+
+ if (b != tag) {
+ data->ofs = start_ofs;
+ data->has_error = false;
+ return false;
+ }
+
+ if (!asn1_read_uint8(data, &b)) {
+ data->ofs = start_ofs;
+ data->has_error = false;
+ return false;
+ }
+
+ if (b & 0x80) {
+ int n = b & 0x7f;
+ if (!asn1_read_uint8(data, &b)) {
+ data->ofs = start_ofs;
+ data->has_error = false;
+ return false;
+ }
+ if (n > 4) {
+ /*
+ * We should not allow more than 4 bytes
+ * for the encoding of the tag length.
+ *
+ * Otherwise we'd overflow the taglen
+ * variable on 32 bit systems.
+ */
+ data->ofs = start_ofs;
+ data->has_error = false;
+ return false;
+ }
+ taglen = b;
+ while (n > 1) {
+ size_t tmp_taglen;
+
+ if (!asn1_read_uint8(data, &b)) {
+ data->ofs = start_ofs;
+ data->has_error = false;
+ return false;
+ }
+
+ tmp_taglen = (taglen << 8) | b;
+
+ if ((tmp_taglen >> 8) != taglen) {
+ /* overflow */
+ data->ofs = start_ofs;
+ data->has_error = false;
+ return false;
+ }
+ taglen = tmp_taglen;
+
+ n--;
+ }
+ } else {
+ taglen = b;
+ }
+
+ *size = (data->ofs - start_ofs) + taglen;
+
+ data->ofs = start_ofs;
+ data->has_error = false;
+ return true;
+}
+
+/* start reading a nested asn1 structure */
+bool asn1_start_tag(struct asn1_data *data, uint8_t tag)
+{
+ uint8_t b;
+ struct nesting *nesting;
+
+ /*
+ * Check the depth of the parse tree and prevent it from growing
+ * too large.
+ */
+ data->depth++;
+ if (data->depth > data->max_depth) {
+ data->has_error = true;
+ return false;
+ }
+
+ if (!asn1_read_uint8(data, &b))
+ return false;
+
+ if (b != tag) {
+ data->has_error = true;
+ return false;
+ }
+ nesting = talloc(data, struct nesting);
+ if (!nesting) {
+ data->has_error = true;
+ return false;
+ }
+
+ if (!asn1_read_uint8(data, &b)) {
+ return false;
+ }
+
+ if (b & 0x80) {
+ int n = b & 0x7f;
+ if (!asn1_read_uint8(data, &b))
+ return false;
+ nesting->taglen = b;
+ while (n > 1) {
+ size_t taglen;
+
+ if (!asn1_read_uint8(data, &b))
+ return false;
+
+ taglen = (nesting->taglen << 8) | b;
+
+ if ((taglen >> 8) != nesting->taglen) {
+ /* overflow */
+ data->has_error = true;
+ return false;
+ }
+ nesting->taglen = taglen;
+
+ n--;
+ }
+ } else {
+ nesting->taglen = b;
+ }
+ nesting->start = data->ofs;
+ nesting->next = data->nesting;
+ data->nesting = nesting;
+ if (asn1_tag_remaining(data) == -1) {
+ return false;
+ }
+ return !data->has_error;
+}
+
+/* stop reading a tag */
+bool asn1_end_tag(struct asn1_data *data)
+{
+ struct nesting *nesting;
+
+ if (data->depth == 0) {
+ smb_panic("Unbalanced ASN.1 Tag nesting");
+ }
+ data->depth--;
+ /* make sure we read it all */
+ if (asn1_tag_remaining(data) != 0) {
+ data->has_error = true;
+ return false;
+ }
+
+ nesting = data->nesting;
+
+ if (!nesting) {
+ data->has_error = true;
+ return false;
+ }
+
+ data->nesting = nesting->next;
+ talloc_free(nesting);
+ return true;
+}
+
+/* work out how many bytes are left in this nested tag */
+int asn1_tag_remaining(struct asn1_data *data)
+{
+ int remaining;
+ if (data->has_error) {
+ return -1;
+ }
+
+ if (!data->nesting) {
+ data->has_error = true;
+ return -1;
+ }
+ remaining = data->nesting->taglen - (data->ofs - data->nesting->start);
+ if (remaining > (data->length - data->ofs)) {
+ data->has_error = true;
+ return -1;
+ }
+ if (remaining < 0) {
+ data->has_error = true;
+ return -1;
+ }
+ return remaining;
+}
+
+/**
+ * Internal implementation for reading binary OIDs
+ * Reading is done as far in the buffer as valid OID
+ * till buffer ends or not valid sub-identifier is found.
+ */
+static bool _ber_read_OID_String_impl(TALLOC_CTX *mem_ctx, DATA_BLOB blob,
+ char **OID, size_t *bytes_eaten)
+{
+ int i;
+ uint8_t *b;
+ unsigned int v;
+ char *tmp_oid = NULL;
+
+ if (blob.length < 2) return false;
+
+ b = blob.data;
+
+ tmp_oid = talloc_asprintf(mem_ctx, "%u.%u", b[0]/40, b[0]%40);
+ if (!tmp_oid) goto nomem;
+
+ if (bytes_eaten != NULL) {
+ *bytes_eaten = 0;
+ }
+
+ for(i = 1, v = 0; i < blob.length; i++) {
+ v = (v<<7) | (b[i]&0x7f);
+ if ( ! (b[i] & 0x80)) {
+ tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", v);
+ v = 0;
+ if (bytes_eaten)
+ *bytes_eaten = i+1;
+ }
+ if (!tmp_oid) goto nomem;
+ }
+
+ *OID = tmp_oid;
+ return true;
+
+nomem:
+ return false;
+}
+
+/* read an object ID from a data blob */
+bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, char **OID)
+{
+ size_t bytes_eaten;
+
+ if (!_ber_read_OID_String_impl(mem_ctx, blob, OID, &bytes_eaten))
+ return false;
+
+ return (bytes_eaten == blob.length);
+}
+
+/**
+ * Deserialize partial OID string.
+ * Partial OIDs are in the form:
+ * 1:2.5.6:0x81
+ * 1:2.5.6:0x8182
+ */
+bool ber_read_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob,
+ char **partial_oid)
+{
+ size_t bytes_left;
+ size_t bytes_eaten;
+ char *identifier = NULL;
+ char *tmp_oid = NULL;
+
+ if (!_ber_read_OID_String_impl(mem_ctx, blob, &tmp_oid, &bytes_eaten))
+ return false;
+
+ if (bytes_eaten < blob.length) {
+ bytes_left = blob.length - bytes_eaten;
+ identifier = hex_encode_talloc(mem_ctx, &blob.data[bytes_eaten], bytes_left);
+ if (!identifier) goto nomem;
+
+ *partial_oid = talloc_asprintf_append_buffer(tmp_oid, ":0x%s", identifier);
+ if (!*partial_oid) goto nomem;
+ TALLOC_FREE(identifier);
+ } else {
+ *partial_oid = tmp_oid;
+ }
+
+ return true;
+
+nomem:
+ TALLOC_FREE(identifier);
+ TALLOC_FREE(tmp_oid);
+ return false;
+}
+
+/* read an object ID from a ASN1 buffer */
+bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **OID)
+{
+ DATA_BLOB blob;
+ int len;
+
+ if (!asn1_start_tag(data, ASN1_OID)) return false;
+
+ len = asn1_tag_remaining(data);
+ if (len < 0) {
+ data->has_error = true;
+ return false;
+ }
+
+ blob = data_blob(NULL, len);
+ if (!blob.data) {
+ data->has_error = true;
+ return false;
+ }
+
+ if (!asn1_read(data, blob.data, len)) return false;
+ if (!asn1_end_tag(data)) {
+ data_blob_free(&blob);
+ return false;
+ }
+
+ if (!ber_read_OID_String(mem_ctx, blob, OID)) {
+ data->has_error = true;
+ data_blob_free(&blob);
+ return false;
+ }
+
+ data_blob_free(&blob);
+ return true;
+}
+
+/* check that the next object ID is correct */
+bool asn1_check_OID(struct asn1_data *data, const char *OID)
+{
+ char *id;
+
+ if (!asn1_read_OID(data, data, &id)) return false;
+
+ if (strcmp(id, OID) != 0) {
+ talloc_free(id);
+ data->has_error = true;
+ return false;
+ }
+ talloc_free(id);
+ return true;
+}
+
+/* read a LDAPString from a ASN1 buffer */
+bool asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s)
+{
+ int len;
+ len = asn1_tag_remaining(data);
+ if (len < 0) {
+ data->has_error = true;
+ return false;
+ }
+ *s = talloc_array(mem_ctx, char, len+1);
+ if (! *s) {
+ data->has_error = true;
+ return false;
+ }
+ (*s)[len] = 0;
+ return asn1_read(data, *s, len);
+}
+
+
+/* read a GeneralString from a ASN1 buffer */
+bool asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s)
+{
+ if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return false;
+ if (!asn1_read_LDAPString(data, mem_ctx, s)) return false;
+ return asn1_end_tag(data);
+}
+
+
+/* read a octet string blob */
+bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
+{
+ int len;
+ ZERO_STRUCTP(blob);
+ if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return false;
+ len = asn1_tag_remaining(data);
+ if (len < 0) {
+ data->has_error = true;
+ return false;
+ }
+ *blob = data_blob_talloc(mem_ctx, NULL, len+1);
+ if (!blob->data || blob->length < len) {
+ data->has_error = true;
+ return false;
+ }
+ if (!asn1_read(data, blob->data, len)) goto err;
+ if (!asn1_end_tag(data)) goto err;
+ blob->length--;
+ blob->data[len] = 0;
+ return true;
+
+ err:
+
+ data_blob_free(blob);
+ *blob = data_blob_null;
+ return false;
+}
+
+bool asn1_read_ContextSimple(struct asn1_data *data, TALLOC_CTX *mem_ctx, uint8_t num,
+ DATA_BLOB *blob)
+{
+ int len;
+ ZERO_STRUCTP(blob);
+ if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(num))) return false;
+ len = asn1_tag_remaining(data);
+ if (len < 0) {
+ data->has_error = true;
+ return false;
+ }
+ *blob = data_blob_talloc(mem_ctx, NULL, len + 1);
+ if ((len != 0) && (!blob->data)) {
+ data->has_error = true;
+ return false;
+ }
+ if (!asn1_read(data, blob->data, len)) return false;
+ blob->length--;
+ blob->data[len] = 0;
+ return asn1_end_tag(data);
+}
+
+/* read an integer without tag*/
+bool asn1_read_implicit_Integer(struct asn1_data *data, int *i)
+{
+ uint8_t b;
+ uint32_t x = 0;
+ bool first_byte = true;
+
+ *i = 0;
+
+ while (!data->has_error && asn1_tag_remaining(data)>0) {
+ if (!asn1_read_uint8(data, &b)) return false;
+ if (first_byte) {
+ if (b & 0x80) {
+ /* Number is negative. */
+ x = (uint32_t)-1;
+ }
+ first_byte = false;
+ }
+ x = (x << 8) + b;
+ }
+ *i = (int)x;
+
+ return !data->has_error;
+}
+
+/* read an integer */
+bool asn1_read_Integer(struct asn1_data *data, int *i)
+{
+ *i = 0;
+
+ if (!asn1_start_tag(data, ASN1_INTEGER)) return false;
+ if (!asn1_read_implicit_Integer(data, i)) return false;
+ return asn1_end_tag(data);
+}
+
+/* read a BIT STRING */
+bool asn1_read_BitString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint8_t *padding)
+{
+ int len;
+ ZERO_STRUCTP(blob);
+ if (!asn1_start_tag(data, ASN1_BIT_STRING)) return false;
+ len = asn1_tag_remaining(data);
+ if (len < 0) {
+ data->has_error = true;
+ return false;
+ }
+ if (!asn1_read_uint8(data, padding)) return false;
+
+ *blob = data_blob_talloc(mem_ctx, NULL, len+1);
+ if (!blob->data || blob->length < len) {
+ data->has_error = true;
+ return false;
+ }
+ if (asn1_read(data, blob->data, len - 1)) {
+ blob->length--;
+ blob->data[len] = 0;
+ asn1_end_tag(data);
+ }
+
+ if (data->has_error) {
+ data_blob_free(blob);
+ *blob = data_blob_null;
+ *padding = 0;
+ return false;
+ }
+ return true;
+}
+
+/* read a non-negative enumerated value */
+bool asn1_read_enumerated(struct asn1_data *data, int *v)
+{
+ unsigned int val_will_wrap = (0xFFU << ((sizeof(int)*8)-8));
+ *v = 0;
+
+ if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false;
+ while (!data->has_error && asn1_tag_remaining(data)>0) {
+ uint8_t b;
+ if (!asn1_read_uint8(data, &b)) {
+ return false;
+ }
+ if (*v & val_will_wrap) {
+ /*
+ * There is something already in
+ * the top byte of the int. If we
+ * shift left by 8 it's going to
+ * wrap. Prevent this.
+ */
+ data->has_error = true;
+ return false;
+ }
+ /*
+ * To please/fool the Undefined Behaviour Sanitizer we cast to
+ * unsigned for the left shift.
+ */
+ *v = ((unsigned int)*v << 8) + b;
+ if (*v < 0) {
+ /* ASN1_ENUMERATED can't be -ve. */
+ data->has_error = true;
+ return false;
+ }
+ }
+ return asn1_end_tag(data);
+}
+
+/* write an enumerated value to the stream */
+bool asn1_write_enumerated(struct asn1_data *data, uint8_t v)
+{
+ if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false;
+ if (!asn1_write_uint8(data, v)) return false;
+ return asn1_pop_tag(data);
+}
+
+/*
+ Get us the data just written without copying
+*/
+bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob)
+{
+ if (asn1->has_error) {
+ return false;
+ }
+ if (asn1->nesting != NULL) {
+ return false;
+ }
+ blob->data = asn1->data;
+ blob->length = asn1->length;
+ return true;
+}
+
+bool asn1_extract_blob(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
+ DATA_BLOB *pblob)
+{
+ DATA_BLOB blob;
+
+ if (!asn1_blob(asn1, &blob)) {
+ return false;
+ }
+
+ *pblob = (DATA_BLOB) { .length = blob.length };
+ pblob->data = talloc_move(mem_ctx, &blob.data);
+
+ /*
+ * Stop access from here on
+ */
+ asn1->has_error = true;
+
+ return true;
+}
+
+/*
+ Fill in an asn1 struct without making a copy
+*/
+void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len)
+{
+ /*
+ * Save max_depth
+ */
+ unsigned max_depth = data->max_depth;
+ ZERO_STRUCTP(data);
+ data->data = buf;
+ data->length = len;
+ data->max_depth = max_depth;
+}
+
+int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size)
+{
+ struct asn1_data asn1;
+ size_t size;
+ bool ok;
+
+ ZERO_STRUCT(asn1);
+ asn1.data = blob.data;
+ asn1.length = blob.length;
+
+ ok = asn1_peek_tag_needed_size(&asn1, tag, &size);
+ if (!ok) {
+ return EMSGSIZE;
+ }
+
+ if (size > blob.length) {
+ *packet_size = size;
+ return EAGAIN;
+ }
+
+ *packet_size = size;
+ return 0;
+}
+
+/*
+ * Get the length of the ASN.1 data
+ */
+size_t asn1_get_length(const struct asn1_data *asn1) {
+ return asn1->length;
+}
diff --git a/lib/util/asn1.h b/lib/util/asn1.h
new file mode 100644
index 0000000..9043c34
--- /dev/null
+++ b/lib/util/asn1.h
@@ -0,0 +1,110 @@
+/*
+ Unix SMB/CIFS implementation.
+ simple ASN1 code
+ Copyright (C) Andrew Tridgell 2001
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _ASN_1_H
+#define _ASN_1_H
+
+#include "replace.h"
+#include <talloc.h>
+#include "lib/util/data_blob.h"
+
+
+struct nesting;
+struct asn1_data;
+typedef struct asn1_data ASN1_DATA;
+
+#define ASN1_APPLICATION(x) ((x)+0x60)
+#define ASN1_APPLICATION_SIMPLE(x) ((x)+0x40)
+#define ASN1_SEQUENCE(x) ((x)+0x30)
+#define ASN1_CONTEXT(x) ((x)+0xa0)
+#define ASN1_CONTEXT_SIMPLE(x) ((x)+0x80)
+#define ASN1_GENERAL_STRING 0x1b
+#define ASN1_OCTET_STRING 0x4
+#define ASN1_OID 0x6
+#define ASN1_BOOLEAN 0x1
+#define ASN1_INTEGER 0x2
+#define ASN1_BIT_STRING 0x3
+#define ASN1_ENUMERATED 0xa
+#define ASN1_SET 0x31
+
+#define ASN1_MAX_OIDS 20
+
+/*
+ * The maximum permitted depth for an ASN.1 parse tree, the limit is chosen
+ * to align with the value for windows. Note that this value will trigger
+ * ASAN stack overflow errors.
+ */
+#define ASN1_MAX_TREE_DEPTH 512
+
+struct asn1_data *asn1_init(TALLOC_CTX *mem_ctx, unsigned max_depth);
+void asn1_free(struct asn1_data *data);
+bool asn1_has_error(const struct asn1_data *data);
+void asn1_set_error(struct asn1_data *data);
+bool asn1_has_nesting(const struct asn1_data *data);
+off_t asn1_current_ofs(const struct asn1_data *data);
+bool asn1_write(struct asn1_data *data, const void *p, int len);
+bool asn1_write_uint8(struct asn1_data *data, uint8_t v);
+bool asn1_push_tag(struct asn1_data *data, uint8_t tag);
+bool asn1_pop_tag(struct asn1_data *data);
+bool asn1_write_implicit_Integer(struct asn1_data *data, int i);
+bool asn1_write_Integer(struct asn1_data *data, int i);
+bool asn1_write_BitString(struct asn1_data *data, const void *p, size_t length, uint8_t padding);
+bool ber_write_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *OID);
+bool ber_write_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *partial_oid);
+bool asn1_write_OID(struct asn1_data *data, const char *OID);
+bool asn1_write_OctetString(struct asn1_data *data, const void *p, size_t length);
+bool asn1_write_LDAPString(struct asn1_data *data, const char *s);
+bool asn1_write_DATA_BLOB_LDAPString(struct asn1_data *data, const DATA_BLOB *s);
+bool asn1_write_GeneralString(struct asn1_data *data, const char *s);
+bool asn1_write_ContextSimple(struct asn1_data *data, uint8_t num, DATA_BLOB *blob);
+bool asn1_write_BOOLEAN(struct asn1_data *data, bool v);
+bool asn1_read_BOOLEAN(struct asn1_data *data, bool *v);
+bool asn1_check_BOOLEAN(struct asn1_data *data, bool v);
+bool asn1_write_BOOLEAN_context(struct asn1_data *data, bool v, int context);
+bool asn1_read_BOOLEAN_context(struct asn1_data *data, bool *v, int context);
+bool asn1_load(struct asn1_data *data, DATA_BLOB blob);
+bool asn1_peek(struct asn1_data *data, void *p, int len);
+bool asn1_read(struct asn1_data *data, void *p, int len);
+bool asn1_read_uint8(struct asn1_data *data, uint8_t *v);
+bool asn1_peek_uint8(struct asn1_data *data, uint8_t *v);
+bool asn1_peek_tag(struct asn1_data *data, uint8_t tag);
+bool asn1_start_tag(struct asn1_data *data, uint8_t tag);
+bool asn1_end_tag(struct asn1_data *data);
+int asn1_tag_remaining(struct asn1_data *data);
+bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, char **OID);
+bool ber_read_partial_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, char **partial_oid);
+bool asn1_read_OID(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **OID);
+bool asn1_check_OID(struct asn1_data *data, const char *OID);
+bool asn1_read_LDAPString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s);
+bool asn1_read_GeneralString(struct asn1_data *data, TALLOC_CTX *mem_ctx, char **s);
+bool asn1_read_OctetString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob);
+bool asn1_read_ContextSimple(struct asn1_data *data, TALLOC_CTX *mem_ctx, uint8_t num, DATA_BLOB *blob);
+bool asn1_read_implicit_Integer(struct asn1_data *data, int *i);
+bool asn1_read_Integer(struct asn1_data *data, int *i);
+bool asn1_read_BitString(struct asn1_data *data, TALLOC_CTX *mem_ctx, DATA_BLOB *blob, uint8_t *padding);
+bool asn1_read_enumerated(struct asn1_data *data, int *v);
+bool asn1_write_enumerated(struct asn1_data *data, uint8_t v);
+bool asn1_blob(const struct asn1_data *asn1, DATA_BLOB *blob);
+bool asn1_extract_blob(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
+ DATA_BLOB *pblob);
+void asn1_load_nocopy(struct asn1_data *data, uint8_t *buf, size_t len);
+int asn1_peek_full_tag(DATA_BLOB blob, uint8_t tag, size_t *packet_size);
+size_t asn1_get_length(const struct asn1_data *asn1);
+
+#endif /* _ASN_1_H */
diff --git a/lib/util/attr.h b/lib/util/attr.h
new file mode 100644
index 0000000..af3e244
--- /dev/null
+++ b/lib/util/attr.h
@@ -0,0 +1,105 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __UTIL_ATTR_H__
+#define __UTIL_ATTR_H__
+
+/* for old gcc releases that don't have the feature test macro __has_attribute */
+#ifndef __has_attribute
+#define __has_attribute(x) 0
+#endif
+
+#ifndef _UNUSED_
+#if __has_attribute(unused) || ( (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) )
+/** gcc attribute used on function parameters so that it does not emit
+ * warnings about them being unused. **/
+# define _UNUSED_ __attribute__ ((unused))
+#else
+# define _UNUSED_
+#endif
+#endif
+#ifndef UNUSED
+#define UNUSED(param) param _UNUSED_
+#endif
+
+#ifndef _DEPRECATED_
+#if __has_attribute(deprecated) || ( (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) )
+#define _DEPRECATED_ __attribute__ ((deprecated))
+#else
+#define _DEPRECATED_
+#endif
+#endif
+
+#ifndef _WARN_UNUSED_RESULT_
+#if __has_attribute(warn_unused_result) || ( (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) )
+#define _WARN_UNUSED_RESULT_ __attribute__ ((warn_unused_result))
+#else
+#define _WARN_UNUSED_RESULT_
+#endif
+#endif
+
+#ifndef _NORETURN_
+#if __has_attribute(noreturn) || ( (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) )
+#define _NORETURN_ __attribute__ ((noreturn))
+#else
+#define _NORETURN_
+#endif
+#endif
+
+#ifndef _PURE_
+#if __has_attribute(pure) || ( (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) )
+#define _PURE_ __attribute__((pure))
+#else
+#define _PURE_
+#endif
+#endif
+
+#ifndef NONNULL
+#if __has_attribute(nonnull) || ( (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) )
+#define NONNULL(param) param __attribute__((nonnull))
+#else
+#define NONNULL(param) param
+#endif
+#endif
+
+#ifndef PRINTF_ATTRIBUTE
+#if __has_attribute(format) || ( (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) )
+/** Use gcc attribute to check printf fns. a1 is the 1-based index of
+ * the parameter containing the format, and a2 the index of the first
+ * argument. Note that some gcc 2.x versions don't handle this
+ * properly **/
+#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
+#else
+#define PRINTF_ATTRIBUTE(a1, a2)
+#endif
+#endif
+
+#ifndef FORMAT_ATTRIBUTE
+#if __has_attribute(format) || ( (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) )
+/** Use gcc attribute to check printf fns. a1 is argument to format()
+ * in the above macro. This is needed to support Heimdal's printf
+ * decorations. Note that some gcc 2.x versions don't handle this
+ * properly. **/
+#define FORMAT_ATTRIBUTE(a) __attribute__ ((format a))
+#else
+#define FORMAT_ATTRIBUTE(a)
+#endif
+#endif
+
+#endif /* __UTIL_ATTR_H__ */
diff --git a/lib/util/base64.c b/lib/util/base64.c
new file mode 100644
index 0000000..7acc83d
--- /dev/null
+++ b/lib/util/base64.c
@@ -0,0 +1,169 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+
+ Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) Simo Sorce 2001-2002
+ Copyright (C) Martin Pool 2003
+ Copyright (C) James Peach 2006
+ Copyright (C) Jeremy Allison 1992-2007
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "lib/util/base64.h"
+
+static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/**
+ * Decode a base64 string into a DATA_BLOB - simple and slow algorithm.
+ *
+ * A DATA_BLOB like {.data = NULL, length = 0} indicates memory error.
+ *
+ * Decoding stops at the first invalid character.
+ **/
+_PUBLIC_ DATA_BLOB base64_decode_data_blob_talloc(TALLOC_CTX *mem_ctx, const char *s)
+{
+ int bit_offset, byte_offset, idx, i, n;
+ DATA_BLOB decoded = data_blob_talloc(mem_ctx, s, strlen(s)+1);
+ unsigned char *d = decoded.data;
+ char *p;
+
+ if (decoded.data == NULL) {
+ decoded.length = 0;
+ return decoded;
+ }
+
+ n=i=0;
+
+ while (*s && (p=strchr(b64,*s))) {
+ idx = (int)(p - b64);
+ byte_offset = (i*6)/8;
+ bit_offset = (i*6)%8;
+ d[byte_offset] &= ~((1<<(8-bit_offset))-1);
+ if (bit_offset < 3) {
+ d[byte_offset] |= (idx << (2-bit_offset));
+ n = byte_offset+1;
+ } else {
+ d[byte_offset] |= (idx >> (bit_offset-2));
+ d[byte_offset+1] = (idx << (8-(bit_offset-2))) & 0xFF;
+ n = byte_offset+2;
+ }
+ s++; i++;
+ }
+
+ if ((n > 0) && (*s == '=')) {
+ n -= 1;
+ }
+
+ /* fix up length */
+ decoded.length = n;
+ decoded.data = talloc_realloc(mem_ctx, decoded.data, uint8_t, n);
+ return decoded;
+}
+
+/**
+ * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
+ **/
+_PUBLIC_ DATA_BLOB base64_decode_data_blob(const char *s)
+{
+ return base64_decode_data_blob_talloc(NULL, s);
+}
+
+/**
+ * Decode a base64 string in-place - wrapper for the above
+ **/
+_PUBLIC_ void base64_decode_inplace(char *s)
+{
+ DATA_BLOB decoded = base64_decode_data_blob(s);
+
+ if ( decoded.length != 0 ) {
+ memcpy(s, decoded.data, decoded.length);
+
+ /* null terminate */
+ s[decoded.length] = '\0';
+ } else {
+ *s = '\0';
+ }
+
+ data_blob_free(&decoded);
+}
+
+/**
+ * Encode a base64 string into a talloc()ed string caller to free.
+ *
+ * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
+ * with adjustments
+ **/
+
+_PUBLIC_ char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
+{
+ int bits = 0;
+ int char_count = 0;
+ size_t out_cnt, len, output_len;
+ char *result;
+
+ /*
+ * Note: we return NULL for a zero-length blob, even though it can be
+ * encoded as a zero length string in base64.
+ *
+ * FIXME, perhaps, but we need to check carefully before changing
+ * this.
+ */
+ if (data.length == 0 || data.data == NULL) {
+ return NULL;
+ }
+
+ out_cnt = 0;
+ len = data.length;
+ output_len = data.length * 2 + 4; /* Account for closing bytes. 4 is
+ * random but should be enough for
+ * the = and \0 */
+ result = talloc_array(mem_ctx, char, output_len); /* get us plenty of space */
+ if (result == NULL) {
+ return NULL;
+ }
+
+ while (len--) {
+ int c = (unsigned char) *(data.data++);
+ bits += c;
+ char_count++;
+ if (char_count == 3) {
+ result[out_cnt++] = b64[bits >> 18];
+ result[out_cnt++] = b64[(bits >> 12) & 0x3f];
+ result[out_cnt++] = b64[(bits >> 6) & 0x3f];
+ result[out_cnt++] = b64[bits & 0x3f];
+ bits = 0;
+ char_count = 0;
+ } else {
+ bits <<= 8;
+ }
+ }
+ if (char_count != 0) {
+ bits <<= 16 - (8 * char_count);
+ result[out_cnt++] = b64[bits >> 18];
+ result[out_cnt++] = b64[(bits >> 12) & 0x3f];
+ if (char_count == 1) {
+ result[out_cnt++] = '=';
+ result[out_cnt++] = '=';
+ } else {
+ result[out_cnt++] = b64[(bits >> 6) & 0x3f];
+ result[out_cnt++] = '=';
+ }
+ }
+ result[out_cnt] = '\0'; /* terminate */
+ return result;
+}
+
diff --git a/lib/util/base64.h b/lib/util/base64.h
new file mode 100644
index 0000000..4763804
--- /dev/null
+++ b/lib/util/base64.h
@@ -0,0 +1,52 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba utility functions
+ *
+ * Copyright (C) Andrew Tridgell 1992-2001
+ * Copyright (C) Simo Sorce 2001-2002
+ * Copyright (C) Martin Pool 2003
+ * Copyright (C) James Peach 2006
+ * Copyright (C) Jeremy Allison 1992-2007
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIB_UTIL_BASE64_H__
+#define __LIB_UTIL_BASE64_H__
+
+#include "replace.h"
+#include "lib/util/data_blob.h"
+
+/**
+ Base64 decode a string, place into a data blob. Caller to
+ data_blob_free() the result.
+**/
+DATA_BLOB base64_decode_data_blob_talloc(TALLOC_CTX *mem_ctx, const char *s);
+
+/**
+ Base64 decode a string, place into a data blob on NULL context.
+ Caller to data_blob_free() the result.
+**/
+DATA_BLOB base64_decode_data_blob(const char *s);
+
+/**
+ Base64 decode a string, inplace
+**/
+void base64_decode_inplace(char *s);
+/**
+ Base64 encode a binary data blob into a string
+**/
+char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data);
+
+#endif
diff --git a/lib/util/become_daemon.c b/lib/util/become_daemon.c
new file mode 100644
index 0000000..c6795c5
--- /dev/null
+++ b/lib/util/become_daemon.c
@@ -0,0 +1,151 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 2001-2002
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
+ Copyright (C) James J Myers 2003
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/locale.h"
+#if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
+#include <systemd/sd-daemon.h>
+#endif
+
+#include "close_low_fd.h"
+#include "debug.h"
+
+#include "become_daemon.h"
+
+static bool sd_notifications = true;
+
+/*******************************************************************
+ Enable or disable daemon status systemd notifications
+********************************************************************/
+void daemon_sd_notifications(bool enable)
+{
+ sd_notifications = enable;
+ DBG_DEBUG("Daemon status systemd notifications %s\n",
+ sd_notifications ? "enabled" : "disabled");
+}
+
+/****************************************************************************
+ Become a daemon, discarding the controlling terminal.
+****************************************************************************/
+
+void become_daemon(bool do_fork, bool no_session, bool log_stdout)
+{
+ pid_t newpid;
+ if (do_fork) {
+ newpid = fork();
+ if (newpid == -1) {
+ exit_daemon("Fork failed", errno);
+ }
+ if (newpid) {
+ _exit(0);
+ }
+#if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
+ } else if (sd_notifications) {
+ sd_notify(0, "STATUS=Starting process...");
+#endif
+ }
+
+ /* detach from the terminal */
+#ifdef HAVE_SETSID
+ if (!no_session) {
+ int ret = setsid();
+ if (ret == -1) {
+ exit_daemon("Failed to create session", errno);
+ }
+ }
+#elif defined(TIOCNOTTY)
+ if (!no_session) {
+ int i = open("/dev/tty", O_RDWR, 0);
+ if (i != -1) {
+ ioctl(i, (int) TIOCNOTTY, (char *)0);
+ close(i);
+ }
+ }
+#endif /* HAVE_SETSID */
+
+ /* Close fd's 0,1,2 as appropriate. Needed if started by rsh. */
+ /* stdin must be open if we do not fork, for monitoring for
+ * close. stdout must be open if we are logging there, and we
+ * never close stderr (but debug might dup it onto a log file) */
+ if (do_fork) {
+ int ret = close_low_fd(0);
+ if (ret != 0) {
+ exit_daemon("close_low_fd(0) failed: %s\n", errno);
+ }
+ }
+ if (!log_stdout) {
+ int ret = close_low_fd(1);
+ if (ret != 0) {
+ exit_daemon("close_low_fd(1) failed: %s\n", errno);
+ }
+ }
+}
+
+void exit_daemon(const char *msg, int error)
+{
+ if (msg == NULL) {
+ msg = strerror(error);
+ }
+
+#if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
+ if (sd_notifications) {
+ sd_notifyf(0, "STATUS=daemon failed to start: %s\n"
+ "ERRNO=%i",
+ msg,
+ error);
+ }
+#endif
+ DBG_ERR("daemon failed to start: %s, error code %d\n",
+ msg, error);
+ exit(1);
+}
+
+void daemon_ready(const char *daemon)
+{
+ if (daemon == NULL) {
+ daemon = "Samba";
+ }
+#if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
+ if (sd_notifications) {
+ sd_notifyf(0,
+ "READY=1\nSTATUS=%s: ready to serve connections...",
+ daemon);
+ }
+#endif
+ DBG_INFO("daemon '%s' finished starting up and ready to serve "
+ "connections\n", daemon);
+}
+
+void daemon_status(const char *daemon, const char *msg)
+{
+ if (daemon == NULL) {
+ daemon = "Samba";
+ }
+#if defined(HAVE_LIBSYSTEMD_DAEMON) || defined(HAVE_LIBSYSTEMD)
+ if (sd_notifications) {
+ sd_notifyf(0, "STATUS=%s: %s", daemon, msg);
+ }
+#endif
+ DBG_STARTUP_NOTICE("daemon '%s' : %s\n", daemon, msg);
+}
diff --git a/lib/util/become_daemon.h b/lib/util/become_daemon.h
new file mode 100644
index 0000000..e12be27
--- /dev/null
+++ b/lib/util/become_daemon.h
@@ -0,0 +1,89 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 2001-2002
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
+ Copyright (C) James J Myers 2003
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _BECOME_DAEMON_H
+#define _BECOME_DAEMON_H
+
+#include <stdbool.h>
+
+/**
+ * @file become_daemon.h
+ *
+ * @brief Utilities for demonising
+ */
+
+/**
+ * @brief Enable or disable daemon status systemd notifications
+ *
+ * When samba runs as AD DC only the main 'samba' process has to
+ * notify systemd. Child processes started by the main 'samba', like
+ * smbd and winbindd should call this function to disable sd_notify()
+ * calls.
+ *
+ * @param[in] enable True to enable notifications, false to disable
+**/
+void daemon_sd_notifications(bool enable);
+
+/**
+ * @brief Become a daemon, optionally discarding the controlling terminal
+ *
+ * @param[in] do_fork Should the process fork?
+ * @param[in] no_session Don't start a new session
+ * @param[in] log_stdour Should stdout be closed?
+**/
+void become_daemon(bool do_fork, bool no_session, bool log_stdout);
+
+/**
+ * @brief Exit daemon and log an error message at ERR level
+ *
+ * Optionally report failure to systemd if systemd integration is
+ * enabled.
+ *
+ * @param[in] msg Message to log, generated from error if NULL
+ * @param[in] error Errno of error that occurred
+**/
+void exit_daemon(const char *msg, int error);
+
+/**
+ * @brief Log at ERR level that the daemon is ready to serve connections
+ *
+ * Optionally report status to systemd if systemd integration is enabled.
+ *
+ * @param[in] daemon Name of daemon to include it message
+**/
+void daemon_ready(const char *daemon);
+
+/**
+ * @brief Log at ERR level the specified daemon status
+ *
+ * For example if it is not ready to serve connections and is waiting
+ * for some event to happen.
+ *
+ * Optionally report status to systemd if systemd integration is enabled.
+ *
+ * @param[in] daemon Name of daemon to include it message
+ * @param[in] msg Message to log
+**/
+void daemon_status(const char *daemon, const char *msg);
+
+#endif /* _BECOME_DAEMON_H */
diff --git a/lib/util/binsearch.h b/lib/util/binsearch.h
new file mode 100644
index 0000000..8ae9da2
--- /dev/null
+++ b/lib/util/binsearch.h
@@ -0,0 +1,121 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ a generic binary search macro
+
+ Copyright (C) Andrew Tridgell 2009
+
+ ** NOTE! The following LGPL license applies to the binsearch.h
+ ** header. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _BINSEARCH_H
+#define _BINSEARCH_H
+
+/* a binary array search, where the array is an array of pointers to structures,
+ and we want to find a match for 'target' on 'field' in those structures.
+
+ Inputs:
+ array: base pointer to an array of structures
+ arrray_size: number of elements in the array
+ field: the name of the field in the structure we are keying off
+ target: the field value we are looking for
+ comparison_fn: the comparison function
+ result: where the result of the search is put
+
+ if the element is found, then 'result' is set to point to the found array element. If not,
+ then 'result' is set to NULL.
+
+ The array is assumed to be sorted by the same comparison_fn as the
+ search (with, for example, qsort)
+ */
+#define BINARY_ARRAY_SEARCH_P(array, array_size, field, target, comparison_fn, result) do { \
+ int32_t _b, _e; \
+ (result) = NULL; \
+ if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \
+ int32_t _i = (_b+_e)/2; \
+ int _r = comparison_fn(target, array[_i]->field); \
+ if (_r == 0) { (result) = array[_i]; break; } \
+ if (_r < 0) _e = _i - 1; else _b = _i + 1; \
+ }} } while (0)
+
+/*
+ like BINARY_ARRAY_SEARCH_P, but assumes that the array is an array
+ of structures, rather than pointers to structures
+
+ result points to the found structure, or NULL
+ */
+#define BINARY_ARRAY_SEARCH(array, array_size, field, target, comparison_fn, result) do { \
+ int32_t _b, _e; \
+ (result) = NULL; \
+ if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \
+ int32_t _i = (_b+_e)/2; \
+ int _r = comparison_fn(target, array[_i].field); \
+ if (_r == 0) { (result) = &array[_i]; break; } \
+ if (_r < 0) _e = _i - 1; else _b = _i + 1; \
+ }} } while (0)
+
+/*
+ like BINARY_ARRAY_SEARCH_P, but assumes that the array is an array
+ of elements, rather than pointers to structures
+
+ result points to the found structure, or NULL
+ */
+#define BINARY_ARRAY_SEARCH_V(array, array_size, target, comparison_fn, result) do { \
+ int32_t _b, _e; \
+ (result) = NULL; \
+ if (array_size) { for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \
+ int32_t _i = (_b+_e)/2; \
+ int _r = comparison_fn(target, array[_i]); \
+ if (_r == 0) { (result) = &array[_i]; break; } \
+ if (_r < 0) _e = _i - 1; else _b = _i + 1; \
+ }} } while (0)
+
+
+/*
+ like BINARY_ARRAY_SEARCH_V, but if an exact result is not found, the 'next'
+ argument will point to the element after the place where the exact result
+ would have been. If an exact result is found, 'next' will be NULL. If the
+ target is beyond the end of the list, both 'exact' and 'next' will be NULL.
+ Unlike other binsearch macros, where there are several elements that compare
+ the same, the exact result will always point to the first one.
+
+ If you don't care to distinguish between the 'greater than' and 'equals'
+ cases, you can use the same pointer for both 'exact' and 'next'.
+
+ As with all the binsearch macros, the comparison function is always called
+ with the search term first.
+ */
+#define BINARY_ARRAY_SEARCH_GTE(array, array_size, target, comparison_fn, \
+ exact, next) do { \
+ int32_t _b, _e; \
+ (exact) = NULL; (next) = NULL; \
+ if ((array_size) > 0) { \
+ for (_b = 0, _e = (array_size)-1; _b <= _e; ) { \
+ int32_t _i = (_b + _e) / 2; \
+ int _r = comparison_fn(target, &array[_i]); \
+ if (_r == 0) { \
+ (exact) = &array[_i]; \
+ _e = _i - 1; \
+ } else if (_r < 0) { _e = _i - 1; \
+ } else { _b = _i + 1; } \
+ } \
+ if ((exact) == NULL &&_b < (array_size)) { \
+ (next) = &array[_b]; \
+ } } } while (0)
+
+#endif
diff --git a/lib/util/bitmap.c b/lib/util/bitmap.c
new file mode 100644
index 0000000..12cdfe4
--- /dev/null
+++ b/lib/util/bitmap.c
@@ -0,0 +1,144 @@
+/*
+ Unix SMB/CIFS implementation.
+ simple bitmap functions
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include <talloc.h>
+#include "lib/util/bitmap.h"
+#include "lib/util/debug.h"
+#include "lib/util/fault.h"
+
+struct bitmap {
+ unsigned int n;
+ uint32_t b[1]; /* We allocate more */
+};
+
+/* these functions provide a simple way to allocate integers from a
+ pool without repetition */
+
+/****************************************************************************
+talloc a bitmap
+****************************************************************************/
+struct bitmap *bitmap_talloc(TALLOC_CTX *mem_ctx, int n)
+{
+ struct bitmap *bm;
+
+ bm = (struct bitmap *)talloc_zero_size(
+ mem_ctx,
+ offsetof(struct bitmap, b) + sizeof(uint32_t)*((n+31)/32));
+
+ if (!bm) return NULL;
+
+ talloc_set_name_const(bm, "struct bitmap");
+
+ bm->n = n;
+ return bm;
+}
+
+/****************************************************************************
+copy as much of the source bitmap as will fit in the destination bitmap.
+****************************************************************************/
+
+int bitmap_copy(struct bitmap * const dst, const struct bitmap * const src)
+{
+ int count = MIN(dst->n, src->n);
+
+ SMB_ASSERT(dst->b != src->b);
+ memcpy(dst->b, src->b, sizeof(uint32_t)*((count+31)/32));
+
+ return count;
+}
+
+/****************************************************************************
+set a bit in a bitmap
+****************************************************************************/
+bool bitmap_set(struct bitmap *bm, unsigned i)
+{
+ if (i >= bm->n) {
+ DEBUG(0,("Setting invalid bitmap entry %d (of %d)\n",
+ i, bm->n));
+ return false;
+ }
+ bm->b[i/32] |= (1U<<(i%32));
+ return true;
+}
+
+/****************************************************************************
+clear a bit in a bitmap
+****************************************************************************/
+bool bitmap_clear(struct bitmap *bm, unsigned i)
+{
+ if (i >= bm->n) {
+ DEBUG(0,("clearing invalid bitmap entry %d (of %d)\n",
+ i, bm->n));
+ return false;
+ }
+ bm->b[i/32] &= ~(1U<<(i%32));
+ return true;
+}
+
+/****************************************************************************
+query a bit in a bitmap
+****************************************************************************/
+bool bitmap_query(struct bitmap *bm, unsigned i)
+{
+ if (i >= bm->n) return false;
+ if (bm->b[i/32] & (1U<<(i%32))) {
+ return true;
+ }
+ return false;
+}
+
+/****************************************************************************
+find a zero bit in a bitmap starting at the specified offset, with
+wraparound
+****************************************************************************/
+int bitmap_find(struct bitmap *bm, unsigned ofs)
+{
+ unsigned int i, j;
+
+ if (ofs > bm->n) ofs = 0;
+
+ i = ofs;
+ while (i < bm->n) {
+ if (~(bm->b[i/32])) {
+ j = i;
+ do {
+ if (!bitmap_query(bm, j)) return j;
+ j++;
+ } while (j & 31 && j < bm->n);
+ }
+ i += 32;
+ i &= ~31;
+ }
+
+ i = 0;
+ while (i < ofs) {
+ if (~(bm->b[i/32])) {
+ j = i;
+ do {
+ if (!bitmap_query(bm, j)) return j;
+ j++;
+ } while (j & 31 && j < bm->n);
+ }
+ i += 32;
+ i &= ~31;
+ }
+
+ return -1;
+}
diff --git a/lib/util/bitmap.h b/lib/util/bitmap.h
new file mode 100644
index 0000000..6d75929
--- /dev/null
+++ b/lib/util/bitmap.h
@@ -0,0 +1,29 @@
+/*
+ Unix SMB/CIFS implementation.
+ simple bitmap functions
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/* The following definitions come from lib/bitmap.c */
+
+struct bitmap;
+
+struct bitmap *bitmap_talloc(TALLOC_CTX *mem_ctx, int n);
+int bitmap_copy(struct bitmap * const dst, const struct bitmap * const src);
+bool bitmap_set(struct bitmap *bm, unsigned i);
+bool bitmap_clear(struct bitmap *bm, unsigned i);
+bool bitmap_query(struct bitmap *bm, unsigned i);
+int bitmap_find(struct bitmap *bm, unsigned ofs);
diff --git a/lib/util/blocking.c b/lib/util/blocking.c
new file mode 100644
index 0000000..6d7fc91
--- /dev/null
+++ b/lib/util/blocking.c
@@ -0,0 +1,76 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 2001-2002
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
+ Copyright (C) James J Myers 2003
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "blocking.h"
+
+/**
+ Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
+ else
+ if SYSV use O_NDELAY
+ if BSD use FNDELAY
+**/
+
+_PUBLIC_ int set_blocking(int fd, bool set)
+{
+ int val;
+#ifdef O_NONBLOCK
+#define FLAG_TO_SET O_NONBLOCK
+#else
+#ifdef SYSV
+#define FLAG_TO_SET O_NDELAY
+#else /* BSD */
+#define FLAG_TO_SET FNDELAY
+#endif
+#endif
+
+ if((val = fcntl(fd, F_GETFL, 0)) == -1)
+ return -1;
+ if(set) /* Turn blocking on - ie. clear nonblock flag */
+ val &= ~FLAG_TO_SET;
+ else
+ val |= FLAG_TO_SET;
+ return fcntl( fd, F_SETFL, val);
+#undef FLAG_TO_SET
+}
+
+
+_PUBLIC_ bool smb_set_close_on_exec(int fd)
+{
+#ifdef FD_CLOEXEC
+ int val;
+
+ val = fcntl(fd, F_GETFD, 0);
+ if (val >= 0) {
+ val |= FD_CLOEXEC;
+ val = fcntl(fd, F_SETFD, val);
+ if (val != -1) {
+ return true;
+ }
+ }
+#else
+ errno = ENOSYS;
+#endif
+ return false;
+}
diff --git a/lib/util/blocking.h b/lib/util/blocking.h
new file mode 100644
index 0000000..d605352
--- /dev/null
+++ b/lib/util/blocking.h
@@ -0,0 +1,34 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 2001-2002
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
+ Copyright (C) James J Myers 2003
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_BLOCKING_H_
+#define _SAMBA_BLOCKING_H_
+
+#include <stdbool.h>
+
+int set_blocking(int fd, bool set);
+bool smb_set_close_on_exec(int fd);
+
+#define set_close_on_exec(fd) smb_set_close_on_exec(fd)
+
+#endif /* _SAMBA_BLOCKING_H_ */
diff --git a/lib/util/bytearray.h b/lib/util/bytearray.h
new file mode 100644
index 0000000..0af8a82
--- /dev/null
+++ b/lib/util/bytearray.h
@@ -0,0 +1,124 @@
+/*
+ * Macros for handling integer types in byte arrays
+ *
+ * This file is originally from the libssh.org project
+ *
+ * Copyright (c) 2018 Andreas Schneider <asn@cryptomilk.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef _BYTEARRAY_H
+#define _BYTEARRAY_H
+
+#define _DATA_BYTE_CONST(data, pos) \
+ ((uint8_t)(((const uint8_t *)(data))[(pos)]))
+
+#define _DATA_BYTE(data, pos) \
+ (((uint8_t *)(data))[(pos)])
+
+/*
+ * These macros pull or push integer values from byte arrays stored in
+ * little-endian byte order.
+ */
+#define PULL_LE_U8(data, pos) \
+ (_DATA_BYTE_CONST(data, pos))
+#define PULL_LE_I8(data, pos) \
+ (int8_t)PULL_LE_U8(data, pos)
+
+#define PULL_LE_U16(data, pos) \
+ ((uint16_t)PULL_LE_U8(data, pos) | ((uint16_t)(PULL_LE_U8(data, (pos) + 1))) << 8)
+#define PULL_LE_I16(data, pos) \
+ (int16_t)PULL_LE_U16(data, pos)
+
+#define PULL_LE_U32(data, pos) \
+ ((uint32_t)(PULL_LE_U16(data, pos) | ((uint32_t)PULL_LE_U16(data, (pos) + 2)) << 16))
+#define PULL_LE_I32(data, pos) \
+ (int32_t)PULL_LE_U32(data, pos)
+
+#define PULL_LE_U64(data, pos) \
+ ((uint64_t)(PULL_LE_U32(data, pos) | ((uint64_t)PULL_LE_U32(data, (pos) + 4)) << 32))
+#define PULL_LE_I64(data, pos) \
+ (int64_t)PULL_LE_U64(data, pos)
+
+
+#define PUSH_LE_U8(data, pos, val) \
+ (_DATA_BYTE(data, pos) = ((uint8_t)(val)))
+#define PUSH_LE_I8(data, pos, val) \
+ PUSH_LE_U8(data, pos, val)
+
+#define PUSH_LE_U16(data, pos, val) \
+ (PUSH_LE_U8(data, pos, (uint16_t)(val) & 0xff), PUSH_LE_U8(data, (pos) + 1, (uint16_t)(val) >> 8))
+#define PUSH_LE_I16(data, pos, val) \
+ PUSH_LE_U16(data, pos, val)
+
+#define PUSH_LE_U32(data, pos, val) \
+ (PUSH_LE_U16(data, pos, (uint32_t)(val) & 0xffff), PUSH_LE_U16(data, (pos) + 2, (uint32_t)(val) >> 16))
+#define PUSH_LE_I32(data, pos, val) \
+ PUSH_LE_U32(data, pos, val)
+
+#define PUSH_LE_U64(data, pos, val) \
+ (PUSH_LE_U32(data, pos, (uint64_t)(val) & 0xffffffff), PUSH_LE_U32(data, (pos) + 4, (uint64_t)(val) >> 32))
+#define PUSH_LE_I64(data, pos, val) \
+ PUSH_LE_U64(data, pos, val)
+
+
+
+/*
+ * These macros pull or push integer values from byte arrays stored in
+ * big-endian byte order (network byte order).
+ */
+#define PULL_BE_U8(data, pos) \
+ (_DATA_BYTE_CONST(data, pos))
+#define PULL_BE_I8(data, pos) \
+ (int8_t)PULL_BE_U8(data, pos)
+
+#define PULL_BE_U16(data, pos) \
+ ((((uint16_t)(PULL_BE_U8(data, pos))) << 8) | (uint16_t)PULL_BE_U8(data, (pos) + 1))
+#define PULL_BE_I16(data, pos) \
+ (int16_t)PULL_BE_U16(data, pos)
+
+#define PULL_BE_U32(data, pos) \
+ ((((uint32_t)PULL_BE_U16(data, pos)) << 16) | (uint32_t)(PULL_BE_U16(data, (pos) + 2)))
+#define PULL_BE_I32(data, pos) \
+ (int32_t)PULL_BE_U32(data, pos)
+
+#define PULL_BE_U64(data, pos) \
+ ((((uint64_t)PULL_BE_U32(data, pos)) << 32) | (uint64_t)(PULL_BE_U32(data, (pos) + 4)))
+#define PULL_BE_I64(data, pos) \
+ (int64_t)PULL_BE_U64(data, pos)
+
+
+
+#define PUSH_BE_U8(data, pos, val) \
+ (_DATA_BYTE(data, pos) = ((uint8_t)(val)))
+#define PUSH_BE_I8(data, pos, val) \
+ PUSH_BE_U8(data, pos, val)
+
+#define PUSH_BE_U16(data, pos, val) \
+ (PUSH_BE_U8(data, pos, ((uint16_t)(val)) >> 8), PUSH_BE_U8(data, (pos) + 1, (uint16_t)(val) & 0xff))
+#define PUSH_BE_I16(data, pos, val) \
+ PUSH_BE_U16(data, pos, val)
+
+#define PUSH_BE_U32(data, pos, val) \
+ (PUSH_BE_U16(data, pos, (uint32_t)(val) >> 16), PUSH_BE_U16(data, (pos) + 2, (uint32_t)(val) & 0xffff))
+#define PUSH_BE_I32(data, pos, val) \
+ PUSH_BE_U32(data, pos, val)
+
+#define PUSH_BE_U64(data, pos, val) \
+ (PUSH_BE_U32(data, pos, (uint64_t)(val) >> 32), PUSH_BE_U32(data, (pos) + 4, (uint64_t)(val) & 0xffffffff))
+#define PUSH_BE_I64(data, pos, val) \
+ PUSH_BE_U64(data, pos, val)
+
+#endif /* _BYTEARRAY_H */
diff --git a/lib/util/byteorder.h b/lib/util/byteorder.h
new file mode 100644
index 0000000..65023f9
--- /dev/null
+++ b/lib/util/byteorder.h
@@ -0,0 +1,169 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB Byte handling
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _BYTEORDER_H
+#define _BYTEORDER_H
+
+#include "bytearray.h"
+
+/*
+ This file implements macros for machine independent short and
+ int manipulation
+
+Here is a description of this file that I emailed to the samba list once:
+
+> I am confused about the way that byteorder.h works in Samba. I have
+> looked at it, and I would have thought that you might make a distinction
+> between LE and BE machines, but you only seem to distinguish between 386
+> and all other architectures.
+>
+> Can you give me a clue?
+
+sure.
+
+Ok, now to the macros themselves. I'll take a simple example, say we
+want to extract a 2 byte integer from a SMB packet and put it into a
+type called uint16_t that is in the local machines byte order, and you
+want to do it with only the assumption that uint16_t is _at_least_ 16
+bits long (this last condition is very important for architectures
+that don't have any int types that are 2 bytes long)
+
+You do this:
+
+#define CVAL(buf,pos) (((uint8_t *)(buf))[pos])
+#define PVAL(buf,pos) ((unsigned int)CVAL(buf,pos))
+#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
+
+then to extract a uint16_t value at offset 25 in a buffer you do this:
+
+char *buffer = foo_bar();
+uint16_t xx = SVAL(buffer,25);
+
+We are using the byteorder independence of the ANSI C bitshifts to do
+the work. A good optimising compiler should turn this into efficient
+code, especially if it happens to have the right byteorder :-)
+
+I know these macros can be made a bit tidier by removing some of the
+casts, but you need to look at byteorder.h as a whole to see the
+reasoning behind them. byteorder.h defines the following macros:
+
+SVAL(buf,pos) - extract a 2 byte SMB value
+IVAL(buf,pos) - extract a 4 byte SMB value
+BVAL(buf,pos) - extract a 8 byte SMB value
+SVALS(buf,pos) - signed version of SVAL()
+IVALS(buf,pos) - signed version of IVAL()
+BVALS(buf,pos) - signed version of BVAL()
+
+SSVAL(buf,pos,val) - put a 2 byte SMB value into a buffer
+SIVAL(buf,pos,val) - put a 4 byte SMB value into a buffer
+SBVAL(buf,pos,val) - put a 8 byte SMB value into a buffer
+SSVALS(buf,pos,val) - signed version of SSVAL()
+SIVALS(buf,pos,val) - signed version of SIVAL()
+SBVALS(buf,pos,val) - signed version of SBVAL()
+
+RSVAL(buf,pos) - like SVAL() but for NMB byte ordering
+RSVALS(buf,pos) - like SVALS() but for NMB byte ordering
+RIVAL(buf,pos) - like IVAL() but for NMB byte ordering
+RIVALS(buf,pos) - like IVALS() but for NMB byte ordering
+RSSVAL(buf,pos,val) - like SSVAL() but for NMB ordering
+RSIVAL(buf,pos,val) - like SIVAL() but for NMB ordering
+RSIVALS(buf,pos,val) - like SIVALS() but for NMB ordering
+
+it also defines lots of intermediate macros, just ignore those :-)
+
+*/
+
+
+/****************************************************************************
+ *
+ * ATTENTION: Do not use those macros anymore, use the ones from bytearray.h
+ *
+ ****************************************************************************/
+
+#define CVAL(buf,pos) ((uint32_t)_DATA_BYTE_CONST(buf, pos))
+#define CVAL_NC(buf,pos) _DATA_BYTE(buf, pos) /* Non-const version of CVAL */
+#define PVAL(buf,pos) (CVAL(buf,pos))
+#define SCVAL(buf,pos,val) (CVAL_NC(buf,pos) = (val))
+
+/****************************************************************************
+ *
+ * ATTENTION: Do not use those macros anymore, use the ones from bytearray.h
+ *
+ ****************************************************************************/
+
+#define SVAL(buf,pos) (uint32_t)PULL_LE_U16(buf, pos)
+#define IVAL(buf,pos) PULL_LE_U32(buf, pos)
+#define SSVALX(buf,pos,val) (CVAL_NC(buf,pos)=(uint8_t)((val)&0xFF),CVAL_NC(buf,(pos)+1)=(uint8_t)((val)>>8))
+#define SIVALX(buf,pos,val) (SSVALX(buf,pos,(val)&0xFFFF),SSVALX(buf,(pos)+2,(val)>>16))
+#define SVALS(buf,pos) ((int16_t)SVAL(buf,pos))
+#define IVALS(buf,pos) ((int32_t)IVAL(buf,pos))
+#define SSVAL(buf,pos,val) PUSH_LE_U16(buf, pos, val)
+#define SIVAL(buf,pos,val) PUSH_LE_U32(buf, pos, val)
+#define SSVALS(buf,pos,val) PUSH_LE_U16(buf, pos, val)
+#define SIVALS(buf,pos,val) PUSH_LE_U32(buf, pos, val)
+
+/****************************************************************************
+ *
+ * ATTENTION: Do not use those macros anymore, use the ones from bytearray.h
+ *
+ ****************************************************************************/
+
+/* 64 bit macros */
+#define BVAL(p, ofs) PULL_LE_U64(p, ofs)
+#define BVALS(p, ofs) ((int64_t)BVAL(p,ofs))
+#define SBVAL(p, ofs, v) PUSH_LE_U64(p, ofs, v)
+#define SBVALS(p, ofs, v) (SBVAL(p,ofs,(uint64_t)(v)))
+
+/****************************************************************************
+ *
+ * ATTENTION: Do not use those macros anymore, use the ones from bytearray.h
+ *
+ ****************************************************************************/
+
+/* now the reverse routines - these are used in nmb packets (mostly) */
+#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
+#define IREV(x) ((SREV((uint32_t)(x))<<16) | (SREV(((uint32_t)(x))>>16)))
+#define BREV(x) ((IREV((uint64_t)(x))<<32) | (IREV(((uint64_t)(x))>>32)))
+
+/****************************************************************************
+ *
+ * ATTENTION: Do not use those macros anymore, use the ones from bytearray.h
+ *
+ ****************************************************************************/
+
+#define RSVAL(buf,pos) (uint32_t)PULL_BE_U16(buf, pos)
+#define RSVALS(buf,pos) PULL_BE_U16(buf, pos)
+#define RIVAL(buf,pos) PULL_BE_U32(buf, pos)
+#define RIVALS(buf,pos) PULL_BE_U32(buf, pos)
+#define RBVAL(buf,pos) PULL_BE_U64(buf, pos)
+#define RBVALS(buf,pos) PULL_BE_U64(buf, pos)
+#define RSSVAL(buf,pos,val) PUSH_BE_U16(buf, pos, val)
+#define RSSVALS(buf,pos,val) PUSH_BE_U16(buf, pos, val)
+#define RSIVAL(buf,pos,val) PUSH_BE_U32(buf, pos, val)
+#define RSIVALS(buf,pos,val) PUSH_BE_U32(buf, pos, val)
+#define RSBVAL(buf,pos,val) PUSH_BE_U64(buf, pos, val)
+#define RSBVALS(buf,pos,val) PUSH_BE_U64(buf, pos, val)
+
+/****************************************************************************
+ *
+ * ATTENTION: Do not use those macros anymore, use the ones from bytearray.h
+ *
+ ****************************************************************************/
+
+#endif /* _BYTEORDER_H */
diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h
new file mode 100644
index 0000000..12dc348
--- /dev/null
+++ b/lib/util/charset/charset.h
@@ -0,0 +1,299 @@
+/*
+ Unix SMB/CIFS implementation.
+ charset defines
+ Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Jelmer Vernooij 2002
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/* This is a public header file that is installed as part of Samba.
+ * If you remove any functions or change their signature, update
+ * the so version number. */
+
+#ifndef __CHARSET_H__
+#define __CHARSET_H__
+
+#include <talloc.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+/* this defines the charset types used in samba */
+typedef enum {
+ CH_UTF16LE = 0,
+ CH_UTF16 = 0,
+ CH_UNIX,
+ CH_DOS,
+ CH_UTF8,
+ CH_UTF16BE,
+ CH_UTF16MUNGED,
+ /* The number of distinct character sets. */
+ NUM_CHARSETS
+} charset_t;
+
+/*
+ * SMB UCS2 (16-bit unicode) internal type.
+ * smb_ucs2_t is *always* in little endian format.
+ */
+
+typedef uint16_t smb_ucs2_t;
+
+#ifdef WORDS_BIGENDIAN
+#define UCS2_SHIFT 8
+#else
+#define UCS2_SHIFT 0
+#endif
+
+/* turn a 7 bit character into a ucs2 character */
+#define UCS2_CHAR(c) ((c) << UCS2_SHIFT)
+
+/*
+ * for each charset we have a function that pulls from that charset to
+ * a ucs2 buffer, and a function that pushes to a ucs2 buffer
+ * */
+
+struct charset_functions {
+ const char *name;
+ size_t (*pull)(void *, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft);
+ size_t (*push)(void *, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft);
+ bool samba_internal_charset;
+};
+
+/* this type is used for manipulating unicode codepoints */
+typedef uint32_t codepoint_t;
+
+#define INVALID_CODEPOINT ((codepoint_t)-1)
+
+/* generic iconv conversion structure */
+typedef struct smb_iconv_s {
+ size_t (*direct)(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft);
+ size_t (*pull)(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft);
+ size_t (*push)(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft);
+ void *cd_direct, *cd_pull, *cd_push;
+ char *from_name, *to_name;
+} *smb_iconv_t;
+
+/* string manipulation flags */
+#define STR_TERMINATE 1
+#define STR_UPPER 2
+#define STR_ASCII 4
+#define STR_UNICODE 8
+#define STR_NOALIGN 16
+#define STR_NO_RANGE_CHECK 32
+#define STR_LEN8BIT 64
+#define STR_TERMINATE_ASCII 128 /* only terminate if ascii */
+#define STR_LEN_NOTERM 256 /* the length field is the unterminated length */
+
+struct loadparm_context;
+struct smb_iconv_handle;
+
+size_t ucs2_align(const void *base_ptr, const void *p, int flags);
+
+/**
+return the number of bytes occupied by a buffer in CH_UTF16 format
+**/
+size_t utf16_len(const void *buf);
+
+/**
+return the number of bytes occupied by a buffer in CH_UTF16 format
+the result includes the null termination
+**/
+size_t utf16_null_terminated_len(const void *buf);
+
+/**
+return the number of bytes occupied by a buffer in CH_UTF16 format
+limited by 'n' bytes
+**/
+size_t utf16_len_n(const void *src, size_t n);
+
+/**
+return the number of bytes occupied by a buffer in CH_UTF16 format
+the result includes the null termination
+limited by 'n' bytes
+**/
+size_t utf16_null_terminated_len_n(const void *src, size_t n);
+
+unsigned char *talloc_utf16_strlendup(TALLOC_CTX *mem_ctx, const char *str, size_t len);
+unsigned char *talloc_utf16_strdup(TALLOC_CTX *mem_ctx, const char *str);
+unsigned char *talloc_utf16_strndup(TALLOC_CTX *mem_ctx, const char *str, size_t n);
+
+char *strchr_m(const char *s, char c);
+/**
+ * Calculate the number of units (8 or 16-bit, depending on the
+ * destination charset) that would be needed to convert the input
+ * string, which is expected to be in src_charset encoding, to the
+ * destination charset (which should be a unicode charset).
+ */
+size_t strlen_m_ext_handle(struct smb_iconv_handle *ic,
+ const char *s, charset_t src_charset, charset_t dst_charset);
+size_t strlen_m_ext(const char *s, charset_t src_charset, charset_t dst_charset);
+size_t strlen_m_ext_term(const char *s, charset_t src_charset,
+ charset_t dst_charset);
+size_t strlen_m_ext_term_null(const char *s,
+ charset_t src_charset,
+ charset_t dst_charset);
+size_t strlen_m(const char *s);
+size_t strlen_m_term(const char *s);
+size_t strlen_m_term_null(const char *s);
+char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength);
+char *talloc_alpha_strcpy(TALLOC_CTX *mem_ctx,
+ const char *src,
+ const char *other_safe_chars);
+void string_replace_m(char *s, char oldc, char newc);
+bool strcsequal(const char *s1,const char *s2);
+bool strequal_m(const char *s1, const char *s2);
+int strncasecmp_m(const char *s1, const char *s2, size_t n);
+int strncasecmp_m_handle(struct smb_iconv_handle *iconv_handle,
+ const char *s1, const char *s2, size_t n);
+bool next_token(const char **ptr,char *buff, const char *sep, size_t bufsize);
+int strcasecmp_m_handle(struct smb_iconv_handle *iconv_handle,
+ const char *s1, const char *s2);
+int strcasecmp_m(const char *s1, const char *s2);
+size_t count_chars_m(const char *s, char c);
+char *strupper_talloc(TALLOC_CTX *ctx, const char *src);
+char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *src);
+char *strupper_talloc_n_handle(struct smb_iconv_handle *iconv_handle,
+ TALLOC_CTX *ctx, const char *src, size_t n);
+char *strupper_talloc_n(TALLOC_CTX *ctx, const char *src, size_t n);
+ char *strlower_talloc_handle(struct smb_iconv_handle *iconv_handle,
+ TALLOC_CTX *ctx, const char *src);
+char *strlower_talloc(TALLOC_CTX *ctx, const char *src);
+bool strhasupper(const char *string);
+bool strhaslower_handle(struct smb_iconv_handle *ic,
+ const char *string);
+bool strhaslower(const char *string);
+bool strhasupper_handle(struct smb_iconv_handle *ic,
+ const char *string);
+char *strrchr_m(const char *s, char c);
+char *strchr_m(const char *s, char c);
+char *strstr_m(const char *src, const char *findstr);
+
+bool utf8_check(const char *input, size_t maxlen,
+ size_t *byte_len,
+ size_t *char_len,
+ size_t *utf16_len);
+
+bool push_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size);
+bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src, size_t *converted_size);
+bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size);
+bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size);
+bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src, size_t *converted_size);
+bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src, size_t *converted_size);
+ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags);
+ssize_t pull_string(char *dest, const void *src, size_t dest_len, size_t src_len, int flags);
+
+bool convert_string_talloc(TALLOC_CTX *ctx,
+ charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t *converted_size);
+
+bool convert_string(charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t destlen,
+ size_t *converted_size);
+bool convert_string_error(charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t destlen,
+ size_t *converted_size);
+
+struct smb_iconv_handle *get_iconv_handle(void);
+struct smb_iconv_handle *get_iconv_testing_handle(TALLOC_CTX *mem_ctx,
+ const char *dos_charset,
+ const char *unix_charset,
+ bool use_builtin_handlers);
+struct smb_iconv_handle *reinit_iconv_handle(TALLOC_CTX *mem_ctx,
+ const char *dos_charset,
+ const char *unix_charset);
+void free_iconv_handle(void);
+
+smb_iconv_t get_conv_handle(struct smb_iconv_handle *ic,
+ charset_t from, charset_t to);
+const char *charset_name(struct smb_iconv_handle *ic, charset_t ch);
+
+codepoint_t next_codepoint_ext(const char *str, size_t len,
+ charset_t src_charset, size_t *size);
+codepoint_t next_codepoint(const char *str, size_t *size);
+ssize_t push_codepoint(char *str, codepoint_t c);
+
+/* codepoints */
+codepoint_t next_codepoint_handle_ext(struct smb_iconv_handle *ic,
+ const char *str, size_t len,
+ charset_t src_charset,
+ size_t *size);
+codepoint_t next_codepoint_handle(struct smb_iconv_handle *ic,
+ const char *str, size_t *size);
+ssize_t push_codepoint_handle(struct smb_iconv_handle *ic,
+ char *str, codepoint_t c);
+
+codepoint_t toupper_m(codepoint_t val);
+codepoint_t tolower_m(codepoint_t val);
+bool islower_m(codepoint_t val);
+bool isupper_m(codepoint_t val);
+int codepoint_cmpi(codepoint_t c1, codepoint_t c2);
+
+/* Iconv convenience functions */
+struct smb_iconv_handle *smb_iconv_handle_reinit(TALLOC_CTX *mem_ctx,
+ const char *dos_charset,
+ const char *unix_charset,
+ bool use_builtin_handlers,
+ struct smb_iconv_handle *old_ic);
+
+bool convert_string_handle(struct smb_iconv_handle *ic,
+ charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t destlen, size_t *converted_size);
+bool convert_string_error_handle(struct smb_iconv_handle *ic,
+ charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t destlen,
+ size_t *converted_size);
+
+bool convert_string_talloc_handle(TALLOC_CTX *ctx,
+ struct smb_iconv_handle *ic,
+ charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t *converted_size);
+/* iconv */
+smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode);
+int smb_iconv_close(smb_iconv_t cd);
+size_t smb_iconv(smb_iconv_t cd,
+ const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft);
+smb_iconv_t smb_iconv_open_ex(TALLOC_CTX *mem_ctx, const char *tocode,
+ const char *fromcode, bool use_builtin_handlers);
+
+void smb_init_locale(void);
+
+/* The following definitions come from util_unistr_w.c */
+
+size_t strlen_w(const smb_ucs2_t *src);
+size_t strnlen_w(const smb_ucs2_t *src, size_t max);
+smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c);
+smb_ucs2_t *strchr_wa(const smb_ucs2_t *s, char c);
+smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c);
+smb_ucs2_t *strnrchr_w(const smb_ucs2_t *s, smb_ucs2_t c, unsigned int n);
+smb_ucs2_t *strstr_w(const smb_ucs2_t *s, const smb_ucs2_t *ins);
+bool strlower_w(smb_ucs2_t *s);
+bool strupper_w(smb_ucs2_t *s);
+int strcasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b);
+int strncasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b, size_t len);
+int strcmp_wa(const smb_ucs2_t *a, const char *b);
+smb_ucs2_t toupper_w(smb_ucs2_t v);
+
+#endif /* __CHARSET_H__ */
diff --git a/lib/util/charset/charset_macosxfs.c b/lib/util/charset/charset_macosxfs.c
new file mode 100644
index 0000000..2ecfdff
--- /dev/null
+++ b/lib/util/charset/charset_macosxfs.c
@@ -0,0 +1,605 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba charset module for Mac OS X/Darwin
+ Copyright (C) Benjamin Riefenstahl 2003
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * modules/charset_macosxfs.c
+ *
+ * A Samba charset module to use on Mac OS X/Darwin as the filesystem
+ * and display encoding.
+ *
+ * Actually two implementations are provided here. The default
+ * implementation is based on the official CFString API. The other is
+ * based on internal CFString APIs as defined in the OpenDarwin
+ * source.
+ */
+
+#include "replace.h"
+#include "charset.h"
+#include "charset_proto.h"
+#include "lib/util/debug.h"
+#undef realloc
+
+#ifdef DARWINOS
+
+/*
+ * Include OS frameworks. These are only needed in this module.
+ */
+#include <CoreFoundation/CFString.h>
+
+/*
+ * See if autoconf has found us the internal headers in some form.
+ */
+#if defined(HAVE_COREFOUNDATION_CFSTRINGENCODINGCONVERTER_H)
+# include <CoreFoundation/CFStringEncodingConverter.h>
+# include <CoreFoundation/CFUnicodePrecomposition.h>
+# define USE_INTERNAL_API 1
+#elif defined(HAVE_CFSTRINGENCODINGCONVERTER_H)
+# include <CFStringEncodingConverter.h>
+# include <CFUnicodePrecomposition.h>
+# define USE_INTERNAL_API 1
+#endif
+
+/*
+ * Compile time configuration: Do we want debug output?
+ */
+/* #define DEBUG_STRINGS 1 */
+
+/*
+ * A simple, but efficient memory provider for our buffers.
+ */
+static inline void *resize_buffer (void *buffer, size_t *size, size_t newsize)
+{
+ if (newsize > *size) {
+ *size = newsize + 128;
+ buffer = realloc(buffer, *size);
+ }
+ return buffer;
+}
+
+/*
+ * While there is a version of OpenDarwin for intel, the usual case is
+ * big-endian PPC. So we need byte swapping to handle the
+ * little-endian byte order of the network protocol. We also need an
+ * additional dynamic buffer to do this work for incoming data blocks,
+ * because we have to consider the original data as constant.
+ *
+ * We abstract the differences away by providing a simple facade with
+ * these functions/macros:
+ *
+ * le_to_native(dst,src,len)
+ * native_to_le(cp,len)
+ * set_ucbuffer_with_le(buffer,bufsize,data,size)
+ * set_ucbuffer_with_le_copy(buffer,bufsize,data,size,reserve)
+ */
+#ifdef WORDS_BIGENDIAN
+
+static inline void swap_bytes (char * dst, const char * src, size_t len)
+{
+ const char *srcend = src + len;
+ while (src < srcend) {
+ dst[0] = src[1];
+ dst[1] = src[0];
+ dst += 2;
+ src += 2;
+ }
+}
+static inline void swap_bytes_inplace (char * cp, size_t len)
+{
+ char temp;
+ char *end = cp + len;
+ while (cp < end) {
+ temp = cp[1];
+ cp[1] = cp[0];
+ cp[0] = temp;
+ cp += 2;
+ }
+}
+
+#define le_to_native(dst,src,len) swap_bytes(dst,src,len)
+#define native_to_le(cp,len) swap_bytes_inplace(cp,len)
+#define set_ucbuffer_with_le(buffer,bufsize,data,size) \
+ set_ucbuffer_with_le_copy(buffer,bufsize,data,size,0)
+
+#else /* ! WORDS_BIGENDIAN */
+
+#define le_to_native(dst,src,len) memcpy(dst,src,len)
+#define native_to_le(cp,len) /* nothing */
+#define set_ucbuffer_with_le(buffer,bufsize,data,size) \
+ (((void)(bufsize)),(UniChar*)(data))
+
+#endif
+
+static inline UniChar *set_ucbuffer_with_le_copy (
+ UniChar *buffer, size_t *bufsize,
+ const void *data, size_t size, size_t reserve)
+{
+ buffer = resize_buffer(buffer, bufsize, size+reserve);
+ le_to_native((char*)buffer,data,size);
+ return buffer;
+}
+
+
+/*
+ * A simple hexdump function for debugging error conditions.
+ */
+#define debug_out(s) DEBUG(0,(s))
+
+#ifdef DEBUG_STRINGS
+
+static void hexdump( const char * label, const char * s, size_t len )
+{
+ size_t restlen = len;
+ debug_out("<<<<<<<\n");
+ debug_out(label);
+ debug_out("\n");
+ while (restlen > 0) {
+ char line[100];
+ size_t i, j;
+ char * d = line;
+#undef sprintf
+ d += sprintf(d, "%04X ", (unsigned)(len-restlen));
+ *d++ = ' ';
+ for( i = 0; i<restlen && i<8; ++i ) {
+ d += sprintf(d, "%02X ", ((unsigned)s[i]) & 0xFF);
+ }
+ for( j = i; j<8; ++j ) {
+ d += sprintf(d, " ");
+ }
+ *d++ = ' ';
+ for( i = 8; i<restlen && i<16; ++i ) {
+ d += sprintf(d, "%02X ", ((unsigned)s[i]) & 0xFF);
+ }
+ for( j = i; j<16; ++j ) {
+ d += sprintf(d, " ");
+ }
+ *d++ = ' ';
+ for( i = 0; i<restlen && i<16; ++i ) {
+ if(s[i] < ' ' || s[i] >= 0x7F || !isprint(s[i]))
+ *d++ = '.';
+ else
+ *d++ = s[i];
+ }
+ *d++ = '\n';
+ *d = 0;
+ restlen -= i;
+ s += i;
+ debug_out(line);
+ }
+ debug_out(">>>>>>>\n");
+}
+
+#else /* !DEBUG_STRINGS */
+
+#define hexdump(label,s,len) /* nothing */
+
+#endif
+
+
+#if !USE_INTERNAL_API
+
+/*
+ * An implementation based on documented Mac OS X APIs.
+ *
+ * This does a certain amount of memory management, creating and
+ * manipulating CFString objects. We try to minimize the impact by
+ * keeping those objects around and re-using them. We also use
+ * external backing store for the CFStrings where this is possible and
+ * benficial.
+ *
+ * The Unicode normalizations forms available at this level are
+ * generic, not specifically for the file system. So they may not be
+ * perfect fits.
+ */
+size_t macosxfs_encoding_pull(
+ void *cd, /* Encoder handle */
+ const char **inbuf, size_t *inbytesleft, /* Script string */
+ char **outbuf, size_t *outbytesleft) /* UTF-16-LE string */
+{
+ static const int script_code = kCFStringEncodingUTF8;
+ static CFMutableStringRef cfstring = NULL;
+ size_t outsize;
+ CFRange range;
+
+ (void) cd; /* UNUSED */
+
+ if (0 == *inbytesleft) {
+ return 0;
+ }
+
+ if (NULL == cfstring) {
+ /*
+ * A version with an external backing store as in the
+ * push function should have been more efficient, but
+ * testing shows, that it is actually slower (!).
+ * Maybe kCFAllocatorDefault gets shortcut evaluation
+ * internally, while kCFAllocatorNull doesn't.
+ */
+ cfstring = CFStringCreateMutable(kCFAllocatorDefault,0);
+ }
+
+ /*
+ * Three methods of appending to a CFString, choose the most
+ * efficient.
+ */
+ if (0 == (*inbuf)[*inbytesleft-1]) {
+ CFStringAppendCString(cfstring, *inbuf, script_code);
+ } else if (*inbytesleft <= 255) {
+ Str255 buffer;
+ buffer[0] = *inbytesleft;
+ memcpy(buffer+1, *inbuf, buffer[0]);
+ CFStringAppendPascalString(cfstring, buffer, script_code);
+ } else {
+ /*
+ * We would like to use a fixed buffer and a loop
+ * here, but then we can't guarantee that the input is
+ * well-formed UTF-8, as we are supposed to do.
+ */
+ static char *buffer = NULL;
+ static size_t buflen = 0;
+ buffer = resize_buffer(buffer, &buflen, *inbytesleft+1);
+ memcpy(buffer, *inbuf, *inbytesleft);
+ buffer[*inbytesleft] = 0;
+ CFStringAppendCString(cfstring, *inbuf, script_code);
+ }
+
+ /*
+ * Compose characters, using the non-canonical composition
+ * form.
+ */
+ CFStringNormalize(cfstring, kCFStringNormalizationFormC);
+
+ outsize = CFStringGetLength(cfstring);
+ range = CFRangeMake(0,outsize);
+
+ if (outsize == 0) {
+ /*
+ * HACK: smbd/mangle_hash2.c:is_legal_name() expects
+ * errors here. That function will always pass 2
+ * characters. smbd/open.c:check_for_pipe() cuts a
+ * patchname to 10 characters blindly. Suppress the
+ * debug output in those cases.
+ */
+ if(2 != *inbytesleft && 10 != *inbytesleft) {
+ debug_out("String conversion: "
+ "An unknown error occurred\n");
+ hexdump("UTF8->UTF16LE (old) input",
+ *inbuf, *inbytesleft);
+ }
+ errno = EILSEQ; /* Not sure, but this is what we have
+ * actually seen. */
+ return -1;
+ }
+ if (outsize*2 > *outbytesleft) {
+ CFStringDelete(cfstring, range);
+ debug_out("String conversion: "
+ "Output buffer too small\n");
+ hexdump("UTF8->UTF16LE (old) input",
+ *inbuf, *inbytesleft);
+ errno = E2BIG;
+ return -1;
+ }
+
+ CFStringGetCharacters(cfstring, range, (UniChar*)*outbuf);
+ CFStringDelete(cfstring, range);
+
+ native_to_le(*outbuf, outsize*2);
+
+ /*
+ * Add a converted null byte, if the CFString conversions
+ * prevented that until now.
+ */
+ if (0 == (*inbuf)[*inbytesleft-1] &&
+ (0 != (*outbuf)[outsize*2-1] || 0 != (*outbuf)[outsize*2-2])) {
+
+ if ((outsize*2+2) > *outbytesleft) {
+ debug_out("String conversion: "
+ "Output buffer too small\n");
+ hexdump("UTF8->UTF16LE (old) input",
+ *inbuf, *inbytesleft);
+ errno = E2BIG;
+ return -1;
+ }
+
+ (*outbuf)[outsize*2] = (*outbuf)[outsize*2+1] = 0;
+ outsize += 2;
+ }
+
+ *inbuf += *inbytesleft;
+ *inbytesleft = 0;
+ *outbuf += outsize*2;
+ *outbytesleft -= outsize*2;
+
+ return 0;
+}
+
+size_t macosxfs_encoding_push(
+ void *cd, /* Encoder handle */
+ const char **inbuf, size_t *inbytesleft, /* UTF-16-LE string */
+ char **outbuf, size_t *outbytesleft) /* Script string */
+{
+ static const int script_code = kCFStringEncodingUTF8;
+ static CFMutableStringRef cfstring = NULL;
+ static UniChar *buffer = NULL;
+ static size_t buflen = 0;
+ CFIndex outsize, cfsize, charsconverted;
+
+ (void) cd; /* UNUSED */
+
+ if (0 == *inbytesleft) {
+ return 0;
+ }
+
+ /*
+ * We need a buffer that can hold 4 times the original data,
+ * because that is the theoretical maximum that decomposition
+ * can create currently (in Unicode 4.0).
+ */
+ buffer = set_ucbuffer_with_le_copy(
+ buffer, &buflen, *inbuf, *inbytesleft, 3 * *inbytesleft);
+
+ if (NULL == cfstring) {
+ cfstring = CFStringCreateMutableWithExternalCharactersNoCopy(
+ kCFAllocatorDefault,
+ buffer, *inbytesleft/2, buflen/2,
+ kCFAllocatorNull);
+ } else {
+ CFStringSetExternalCharactersNoCopy(
+ cfstring,
+ buffer, *inbytesleft/2, buflen/2);
+ }
+
+ /*
+ * Decompose characters, using the non-canonical decomposition
+ * form.
+ *
+ * NB: This isn't exactly what HFS+ wants (see note on
+ * kCFStringEncodingUseHFSPlusCanonical in
+ * CFStringEncodingConverter.h), but AFAIK it's the best that
+ * the official API can do.
+ */
+ CFStringNormalize(cfstring, kCFStringNormalizationFormD);
+
+ cfsize = CFStringGetLength(cfstring);
+ charsconverted = CFStringGetBytes(
+ cfstring, CFRangeMake(0,cfsize),
+ script_code, 0, false,
+ *(UInt8 **)outbuf, *outbytesleft, &outsize);
+
+ if (0 == charsconverted) {
+ debug_out("String conversion: "
+ "Buffer too small or not convertible\n");
+ hexdump("UTF16LE->UTF8 (old) input",
+ *inbuf, *inbytesleft);
+ errno = EILSEQ; /* Probably more likely. */
+ return -1;
+ }
+
+ /*
+ * Add a converted null byte, if the CFString conversions
+ * prevented that until now.
+ */
+ if (0 == (*inbuf)[*inbytesleft-1] && 0 == (*inbuf)[*inbytesleft-2] &&
+ (0 != (*outbuf)[outsize-1])) {
+
+ if (((size_t)outsize+1) > *outbytesleft) {
+ debug_out("String conversion: "
+ "Output buffer too small\n");
+ hexdump("UTF16LE->UTF8 (old) input",
+ *inbuf, *inbytesleft);
+ errno = E2BIG;
+ return -1;
+ }
+
+ (*outbuf)[outsize] = 0;
+ ++outsize;
+ }
+
+ *inbuf += *inbytesleft;
+ *inbytesleft = 0;
+ *outbuf += outsize;
+ *outbytesleft -= outsize;
+
+ return 0;
+}
+
+#else /* USE_INTERNAL_API */
+
+/*
+ * An implementation based on internal code as known from the
+ * OpenDarwin CVS.
+ *
+ * This code doesn't need much memory management because it uses
+ * functions that operate on the raw memory directly.
+ *
+ * The push routine here is faster and more compatible with HFS+ than
+ * the other implementation above. The pull routine is only faster
+ * for some strings, slightly slower for others. The pull routine
+ * looses because it has to iterate over the data twice, once to
+ * decode UTF-8 and than to do the character composition required by
+ * Windows.
+ */
+static size_t macosxfs_encoding_pull(
+ void *cd, /* Encoder handle */
+ const char **inbuf, size_t *inbytesleft, /* Script string */
+ char **outbuf, size_t *outbytesleft) /* UTF-16-LE string */
+{
+ static const int script_code = kCFStringEncodingUTF8;
+ UInt32 srcCharsUsed = 0;
+ UInt32 dstCharsUsed = 0;
+ UInt32 result;
+ uint32_t dstDecomposedUsed = 0;
+ uint32_t dstPrecomposedUsed = 0;
+
+ (void) cd; /* UNUSED */
+
+ if (0 == *inbytesleft) {
+ return 0;
+ }
+
+ result = CFStringEncodingBytesToUnicode(
+ script_code, kCFStringEncodingComposeCombinings,
+ *inbuf, *inbytesleft, &srcCharsUsed,
+ (UniChar*)*outbuf, *outbytesleft, &dstCharsUsed);
+
+ switch(result) {
+ case kCFStringEncodingConversionSuccess:
+ if (*inbytesleft == srcCharsUsed) {
+ break;
+ }
+
+ FALL_THROUGH;
+ case kCFStringEncodingInsufficientOutputBufferLength:
+ debug_out("String conversion: "
+ "Output buffer too small\n");
+ hexdump("UTF8->UTF16LE (new) input",
+ *inbuf, *inbytesleft);
+ errno = E2BIG;
+ return -1;
+ case kCFStringEncodingInvalidInputStream:
+ /*
+ * HACK: smbd/mangle_hash2.c:is_legal_name() expects
+ * errors here. That function will always pass 2
+ * characters. smbd/open.c:check_for_pipe() cuts a
+ * patchname to 10 characters blindly. Suppress the
+ * debug output in those cases.
+ */
+ if(2 != *inbytesleft && 10 != *inbytesleft) {
+ debug_out("String conversion: "
+ "Invalid input sequence\n");
+ hexdump("UTF8->UTF16LE (new) input",
+ *inbuf, *inbytesleft);
+ }
+ errno = EILSEQ;
+ return -1;
+ case kCFStringEncodingConverterUnavailable:
+ debug_out("String conversion: "
+ "Unknown encoding\n");
+ hexdump("UTF8->UTF16LE (new) input",
+ *inbuf, *inbytesleft);
+ errno = EINVAL;
+ return -1;
+ }
+
+ /*
+ * It doesn't look like CFStringEncodingBytesToUnicode() can
+ * produce precomposed characters (flags=ComposeCombinings
+ * doesn't do it), so we need another pass over the data here.
+ * We can do this in-place, as the string can only get
+ * shorter.
+ *
+ * (Actually in theory there should be an internal
+ * decomposition and reordering before the actual composition
+ * step. But we should be able to rely on that we always get
+ * fully decomposed strings for input, so this can't create
+ * problems in reality.)
+ */
+ CFUniCharPrecompose(
+ (const UTF16Char *)*outbuf, dstCharsUsed, &dstDecomposedUsed,
+ (UTF16Char *)*outbuf, dstCharsUsed, &dstPrecomposedUsed);
+
+ native_to_le(*outbuf, dstPrecomposedUsed*2);
+
+ *inbuf += srcCharsUsed;
+ *inbytesleft -= srcCharsUsed;
+ *outbuf += dstPrecomposedUsed*2;
+ *outbytesleft -= dstPrecomposedUsed*2;
+
+ return 0;
+}
+
+static size_t macosxfs_encoding_push(
+ void *cd, /* Encoder handle */
+ const char **inbuf, size_t *inbytesleft, /* UTF-16-LE string */
+ char **outbuf, size_t *outbytesleft) /* Script string */
+{
+ static const int script_code = kCFStringEncodingUTF8;
+ static UniChar *buffer = NULL;
+ static size_t buflen = 0;
+ UInt32 srcCharsUsed=0, dstCharsUsed=0, result;
+
+ (void) cd; /* UNUSED */
+
+ if (0 == *inbytesleft) {
+ return 0;
+ }
+
+ buffer = set_ucbuffer_with_le(
+ buffer, &buflen, *inbuf, *inbytesleft);
+
+ result = CFStringEncodingUnicodeToBytes(
+ script_code, kCFStringEncodingUseHFSPlusCanonical,
+ buffer, *inbytesleft/2, &srcCharsUsed,
+ *outbuf, *outbytesleft, &dstCharsUsed);
+
+ switch(result) {
+ case kCFStringEncodingConversionSuccess:
+ if (*inbytesleft/2 == srcCharsUsed) {
+ break;
+ }
+
+ FALL_THROUGH;
+ case kCFStringEncodingInsufficientOutputBufferLength:
+ debug_out("String conversion: "
+ "Output buffer too small\n");
+ hexdump("UTF16LE->UTF8 (new) input",
+ *inbuf, *inbytesleft);
+ errno = E2BIG;
+ return -1;
+ case kCFStringEncodingInvalidInputStream:
+ /*
+ * HACK: smbd/open.c:check_for_pipe():is_legal_name()
+ * cuts a pathname to 10 characters blindly. Suppress
+ * the debug output in those cases.
+ */
+ if(10 != *inbytesleft) {
+ debug_out("String conversion: "
+ "Invalid input sequence\n");
+ hexdump("UTF16LE->UTF8 (new) input",
+ *inbuf, *inbytesleft);
+ }
+ errno = EILSEQ;
+ return -1;
+ case kCFStringEncodingConverterUnavailable:
+ debug_out("String conversion: "
+ "Unknown encoding\n");
+ hexdump("UTF16LE->UTF8 (new) input",
+ *inbuf, *inbytesleft);
+ errno = EINVAL;
+ return -1;
+ }
+
+ *inbuf += srcCharsUsed*2;
+ *inbytesleft -= srcCharsUsed*2;
+ *outbuf += dstCharsUsed;
+ *outbytesleft -= dstCharsUsed;
+
+ return 0;
+}
+
+#endif /* USE_INTERNAL_API */
+
+#else /* DARWIN */
+
+void charset_macosfs_dummy(void);
+void charset_macosfs_dummy(void)
+{
+ return;
+}
+
+#endif /* DARWIN */
diff --git a/lib/util/charset/charset_proto.h b/lib/util/charset/charset_proto.h
new file mode 100644
index 0000000..6da7118
--- /dev/null
+++ b/lib/util/charset/charset_proto.h
@@ -0,0 +1,36 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba charset modules
+ Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Jelmer Vernooij 2002
+ Copyright (C) Benjamin Riefenstahl 2003
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+size_t weird_push(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft);
+size_t weird_pull(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft);
+
+size_t macosxfs_encoding_pull(
+ void *cd, /* Encoder handle */
+ const char **inbuf, size_t *inbytesleft, /* Script string */
+ char **outbuf, size_t *outbytesleft); /* UTF-16-LE string */
+size_t macosxfs_encoding_push(
+ void *cd, /* Encoder handle */
+ const char **inbuf, size_t *inbytesleft, /* UTF-16-LE string */
+ char **outbuf, size_t *outbytesleft); /* Script string */
+
+
diff --git a/lib/util/charset/codepoints.c b/lib/util/charset/codepoints.c
new file mode 100644
index 0000000..ea2c4be
--- /dev/null
+++ b/lib/util/charset/codepoints.c
@@ -0,0 +1,16850 @@
+/*
+ Unix SMB/CIFS implementation.
+ Character set conversion Extensions
+ Copyright (C) Igor Vergeichik <iverg@mail.ru> 2001
+ Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Jelmer Vernooij 2007
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+#include "replace.h"
+#include "lib/util/charset/charset.h"
+#include "system/locale.h"
+#include "dynconfig/dynconfig.h"
+#include "lib/util/debug.h"
+#include "lib/util/byteorder.h"
+
+#ifdef strcasecmp
+#undef strcasecmp
+#endif
+
+/**
+ * @file
+ * @brief Unicode string manipulation
+ */
+
+static const uint16_t lowcase_table[] = {
+ 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
+ 0x0040,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007a,0x005b,0x005c,0x005d,0x005e,0x005f,
+ 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,
+ 0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f,
+ 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,
+ 0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f,
+ 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
+ 0x0088,0x0089,0x008a,0x008b,0x008c,0x008d,0x008e,0x008f,
+ 0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
+ 0x0098,0x0099,0x009a,0x009b,0x009c,0x009d,0x009e,0x009f,
+ 0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,
+ 0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,
+ 0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,
+ 0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,
+ 0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,
+ 0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,
+ 0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00d7,
+ 0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00df,
+ 0x00e0,0x00e1,0x00e2,0x00e3,0x00e4,0x00e5,0x00e6,0x00e7,
+ 0x00e8,0x00e9,0x00ea,0x00eb,0x00ec,0x00ed,0x00ee,0x00ef,
+ 0x00f0,0x00f1,0x00f2,0x00f3,0x00f4,0x00f5,0x00f6,0x00f7,
+ 0x00f8,0x00f9,0x00fa,0x00fb,0x00fc,0x00fd,0x00fe,0x00ff,
+ 0x0101,0x0101,0x0103,0x0103,0x0105,0x0105,0x0107,0x0107,
+ 0x0109,0x0109,0x010b,0x010b,0x010d,0x010d,0x010f,0x010f,
+ 0x0111,0x0111,0x0113,0x0113,0x0115,0x0115,0x0117,0x0117,
+ 0x0119,0x0119,0x011b,0x011b,0x011d,0x011d,0x011f,0x011f,
+ 0x0121,0x0121,0x0123,0x0123,0x0125,0x0125,0x0127,0x0127,
+ 0x0129,0x0129,0x012b,0x012b,0x012d,0x012d,0x012f,0x012f,
+ 0x0130,0x0131,0x0133,0x0133,0x0135,0x0135,0x0137,0x0137,
+ 0x0138,0x013a,0x013a,0x013c,0x013c,0x013e,0x013e,0x0140,
+ 0x0140,0x0142,0x0142,0x0144,0x0144,0x0146,0x0146,0x0148,
+ 0x0148,0x0149,0x014b,0x014b,0x014d,0x014d,0x014f,0x014f,
+ 0x0151,0x0151,0x0153,0x0153,0x0155,0x0155,0x0157,0x0157,
+ 0x0159,0x0159,0x015b,0x015b,0x015d,0x015d,0x015f,0x015f,
+ 0x0161,0x0161,0x0163,0x0163,0x0165,0x0165,0x0167,0x0167,
+ 0x0169,0x0169,0x016b,0x016b,0x016d,0x016d,0x016f,0x016f,
+ 0x0171,0x0171,0x0173,0x0173,0x0175,0x0175,0x0177,0x0177,
+ 0x00ff,0x017a,0x017a,0x017c,0x017c,0x017e,0x017e,0x017f,
+ 0x0180,0x0253,0x0183,0x0183,0x0185,0x0185,0x0254,0x0188,
+ 0x0188,0x0256,0x0257,0x018c,0x018c,0x018d,0x01dd,0x0259,
+ 0x025b,0x0192,0x0192,0x0260,0x0263,0x0195,0x0269,0x0268,
+ 0x0199,0x0199,0x019a,0x019b,0x026f,0x0272,0x019e,0x0275,
+ 0x01a1,0x01a1,0x01a3,0x01a3,0x01a5,0x01a5,0x01a6,0x01a8,
+ 0x01a8,0x0283,0x01aa,0x01ab,0x01ad,0x01ad,0x0288,0x01b0,
+ 0x01b0,0x028a,0x028b,0x01b4,0x01b4,0x01b6,0x01b6,0x0292,
+ 0x01b9,0x01b9,0x01ba,0x01bb,0x01bd,0x01bd,0x01be,0x01bf,
+ 0x01c0,0x01c1,0x01c2,0x01c3,0x01c6,0x01c5,0x01c6,0x01c9,
+ 0x01c8,0x01c9,0x01cc,0x01cb,0x01cc,0x01ce,0x01ce,0x01d0,
+ 0x01d0,0x01d2,0x01d2,0x01d4,0x01d4,0x01d6,0x01d6,0x01d8,
+ 0x01d8,0x01da,0x01da,0x01dc,0x01dc,0x01dd,0x01df,0x01df,
+ 0x01e1,0x01e1,0x01e3,0x01e3,0x01e5,0x01e5,0x01e7,0x01e7,
+ 0x01e9,0x01e9,0x01eb,0x01eb,0x01ed,0x01ed,0x01ef,0x01ef,
+ 0x01f0,0x01f3,0x01f2,0x01f3,0x01f5,0x01f5,0x01f6,0x01f7,
+ 0x01f8,0x01f9,0x01fb,0x01fb,0x01fd,0x01fd,0x01ff,0x01ff,
+ 0x0201,0x0201,0x0203,0x0203,0x0205,0x0205,0x0207,0x0207,
+ 0x0209,0x0209,0x020b,0x020b,0x020d,0x020d,0x020f,0x020f,
+ 0x0211,0x0211,0x0213,0x0213,0x0215,0x0215,0x0217,0x0217,
+ 0x0218,0x0219,0x021a,0x021b,0x021c,0x021d,0x021e,0x021f,
+ 0x0220,0x0221,0x0222,0x0223,0x0224,0x0225,0x0226,0x0227,
+ 0x0228,0x0229,0x022a,0x022b,0x022c,0x022d,0x022e,0x022f,
+ 0x0230,0x0231,0x0232,0x0233,0x0234,0x0235,0x0236,0x0237,
+ 0x0238,0x0239,0x023a,0x023b,0x023c,0x023d,0x023e,0x023f,
+ 0x0240,0x0241,0x0242,0x0243,0x0244,0x0245,0x0246,0x0247,
+ 0x0248,0x0249,0x024a,0x024b,0x024c,0x024d,0x024e,0x024f,
+ 0x0250,0x0251,0x0252,0x0253,0x0254,0x0255,0x0256,0x0257,
+ 0x0258,0x0259,0x025a,0x025b,0x025c,0x025d,0x025e,0x025f,
+ 0x0260,0x0261,0x0262,0x0263,0x0264,0x0265,0x0266,0x0267,
+ 0x0268,0x0269,0x026a,0x026b,0x026c,0x026d,0x026e,0x026f,
+ 0x0270,0x0271,0x0272,0x0273,0x0274,0x0275,0x0276,0x0277,
+ 0x0278,0x0279,0x027a,0x027b,0x027c,0x027d,0x027e,0x027f,
+ 0x0280,0x0281,0x0282,0x0283,0x0284,0x0285,0x0286,0x0287,
+ 0x0288,0x0289,0x028a,0x028b,0x028c,0x028d,0x028e,0x028f,
+ 0x0290,0x0291,0x0292,0x0293,0x0294,0x0295,0x0296,0x0297,
+ 0x0298,0x0299,0x029a,0x029b,0x029c,0x029d,0x029e,0x029f,
+ 0x02a0,0x02a1,0x02a2,0x02a3,0x02a4,0x02a5,0x02a6,0x02a7,
+ 0x02a8,0x02a9,0x02aa,0x02ab,0x02ac,0x02ad,0x02ae,0x02af,
+ 0x02b0,0x02b1,0x02b2,0x02b3,0x02b4,0x02b5,0x02b6,0x02b7,
+ 0x02b8,0x02b9,0x02ba,0x02bb,0x02bc,0x02bd,0x02be,0x02bf,
+ 0x02c0,0x02c1,0x02c2,0x02c3,0x02c4,0x02c5,0x02c6,0x02c7,
+ 0x02c8,0x02c9,0x02ca,0x02cb,0x02cc,0x02cd,0x02ce,0x02cf,
+ 0x02d0,0x02d1,0x02d2,0x02d3,0x02d4,0x02d5,0x02d6,0x02d7,
+ 0x02d8,0x02d9,0x02da,0x02db,0x02dc,0x02dd,0x02de,0x02df,
+ 0x02e0,0x02e1,0x02e2,0x02e3,0x02e4,0x02e5,0x02e6,0x02e7,
+ 0x02e8,0x02e9,0x02ea,0x02eb,0x02ec,0x02ed,0x02ee,0x02ef,
+ 0x02f0,0x02f1,0x02f2,0x02f3,0x02f4,0x02f5,0x02f6,0x02f7,
+ 0x02f8,0x02f9,0x02fa,0x02fb,0x02fc,0x02fd,0x02fe,0x02ff,
+ 0x0300,0x0301,0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,
+ 0x0308,0x0309,0x030a,0x030b,0x030c,0x030d,0x030e,0x030f,
+ 0x0310,0x0311,0x0312,0x0313,0x0314,0x0315,0x0316,0x0317,
+ 0x0318,0x0319,0x031a,0x031b,0x031c,0x031d,0x031e,0x031f,
+ 0x0320,0x0321,0x0322,0x0323,0x0324,0x0325,0x0326,0x0327,
+ 0x0328,0x0329,0x032a,0x032b,0x032c,0x032d,0x032e,0x032f,
+ 0x0330,0x0331,0x0332,0x0333,0x0334,0x0335,0x0336,0x0337,
+ 0x0338,0x0339,0x033a,0x033b,0x033c,0x033d,0x033e,0x033f,
+ 0x0340,0x0341,0x0342,0x0343,0x0344,0x0345,0x0346,0x0347,
+ 0x0348,0x0349,0x034a,0x034b,0x034c,0x034d,0x034e,0x034f,
+ 0x0350,0x0351,0x0352,0x0353,0x0354,0x0355,0x0356,0x0357,
+ 0x0358,0x0359,0x035a,0x035b,0x035c,0x035d,0x035e,0x035f,
+ 0x0360,0x0361,0x0362,0x0363,0x0364,0x0365,0x0366,0x0367,
+ 0x0368,0x0369,0x036a,0x036b,0x036c,0x036d,0x036e,0x036f,
+ 0x0370,0x0371,0x0372,0x0373,0x0374,0x0375,0x0376,0x0377,
+ 0x0378,0x0379,0x037a,0x037b,0x037c,0x037d,0x037e,0x037f,
+ 0x0380,0x0381,0x0382,0x0383,0x0384,0x0385,0x03ac,0x0387,
+ 0x03ad,0x03ae,0x03af,0x038b,0x03cc,0x038d,0x03cd,0x03ce,
+ 0x0390,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,
+ 0x03b8,0x03b9,0x03ba,0x03bb,0x03bc,0x03bd,0x03be,0x03bf,
+ 0x03c0,0x03c1,0x03a2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,
+ 0x03c8,0x03c9,0x03ca,0x03cb,0x03ac,0x03ad,0x03ae,0x03af,
+ 0x03b0,0x03b1,0x03b2,0x03b3,0x03b4,0x03b5,0x03b6,0x03b7,
+ 0x03b8,0x03b9,0x03ba,0x03bb,0x03bc,0x03bd,0x03be,0x03bf,
+ 0x03c0,0x03c1,0x03c2,0x03c3,0x03c4,0x03c5,0x03c6,0x03c7,
+ 0x03c8,0x03c9,0x03ca,0x03cb,0x03cc,0x03cd,0x03ce,0x03cf,
+ 0x03d0,0x03d1,0x03d2,0x03d3,0x03d4,0x03d5,0x03d6,0x03d7,
+ 0x03d8,0x03d9,0x03da,0x03db,0x03dc,0x03dd,0x03de,0x03df,
+ 0x03e0,0x03e1,0x03e3,0x03e3,0x03e5,0x03e5,0x03e7,0x03e7,
+ 0x03e9,0x03e9,0x03eb,0x03eb,0x03ed,0x03ed,0x03ef,0x03ef,
+ 0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x03f7,
+ 0x03f8,0x03f9,0x03fa,0x03fb,0x03fc,0x03fd,0x03fe,0x03ff,
+ 0x0400,0x0451,0x0452,0x0453,0x0454,0x0455,0x0456,0x0457,
+ 0x0458,0x0459,0x045a,0x045b,0x045c,0x040d,0x045e,0x045f,
+ 0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0436,0x0437,
+ 0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,
+ 0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,0x0446,0x0447,
+ 0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,
+ 0x0430,0x0431,0x0432,0x0433,0x0434,0x0435,0x0436,0x0437,
+ 0x0438,0x0439,0x043a,0x043b,0x043c,0x043d,0x043e,0x043f,
+ 0x0440,0x0441,0x0442,0x0443,0x0444,0x0445,0x0446,0x0447,
+ 0x0448,0x0449,0x044a,0x044b,0x044c,0x044d,0x044e,0x044f,
+ 0x0450,0x0451,0x0452,0x0453,0x0454,0x0455,0x0456,0x0457,
+ 0x0458,0x0459,0x045a,0x045b,0x045c,0x045d,0x045e,0x045f,
+ 0x0461,0x0461,0x0463,0x0463,0x0465,0x0465,0x0467,0x0467,
+ 0x0469,0x0469,0x046b,0x046b,0x046d,0x046d,0x046f,0x046f,
+ 0x0471,0x0471,0x0473,0x0473,0x0475,0x0475,0x0477,0x0477,
+ 0x0479,0x0479,0x047b,0x047b,0x047d,0x047d,0x047f,0x047f,
+ 0x0481,0x0481,0x0482,0x0483,0x0484,0x0485,0x0486,0x0487,
+ 0x0488,0x0489,0x048a,0x048b,0x048c,0x048d,0x048e,0x048f,
+ 0x0491,0x0491,0x0493,0x0493,0x0495,0x0495,0x0497,0x0497,
+ 0x0499,0x0499,0x049b,0x049b,0x049d,0x049d,0x049f,0x049f,
+ 0x04a1,0x04a1,0x04a3,0x04a3,0x04a5,0x04a5,0x04a7,0x04a7,
+ 0x04a9,0x04a9,0x04ab,0x04ab,0x04ad,0x04ad,0x04af,0x04af,
+ 0x04b1,0x04b1,0x04b3,0x04b3,0x04b5,0x04b5,0x04b7,0x04b7,
+ 0x04b9,0x04b9,0x04bb,0x04bb,0x04bd,0x04bd,0x04bf,0x04bf,
+ 0x04c0,0x04c2,0x04c2,0x04c4,0x04c4,0x04c5,0x04c6,0x04c8,
+ 0x04c8,0x04c9,0x04ca,0x04cc,0x04cc,0x04cd,0x04ce,0x04cf,
+ 0x04d1,0x04d1,0x04d3,0x04d3,0x04d5,0x04d5,0x04d7,0x04d7,
+ 0x04d9,0x04d9,0x04db,0x04db,0x04dd,0x04dd,0x04df,0x04df,
+ 0x04e1,0x04e1,0x04e3,0x04e3,0x04e5,0x04e5,0x04e7,0x04e7,
+ 0x04e9,0x04e9,0x04eb,0x04eb,0x04ec,0x04ed,0x04ef,0x04ef,
+ 0x04f1,0x04f1,0x04f3,0x04f3,0x04f5,0x04f5,0x04f6,0x04f7,
+ 0x04f9,0x04f9,0x04fa,0x04fb,0x04fc,0x04fd,0x04fe,0x04ff,
+ 0x0500,0x0501,0x0502,0x0503,0x0504,0x0505,0x0506,0x0507,
+ 0x0508,0x0509,0x050a,0x050b,0x050c,0x050d,0x050e,0x050f,
+ 0x0510,0x0511,0x0512,0x0513,0x0514,0x0515,0x0516,0x0517,
+ 0x0518,0x0519,0x051a,0x051b,0x051c,0x051d,0x051e,0x051f,
+ 0x0520,0x0521,0x0522,0x0523,0x0524,0x0525,0x0526,0x0527,
+ 0x0528,0x0529,0x052a,0x052b,0x052c,0x052d,0x052e,0x052f,
+ 0x0530,0x0561,0x0562,0x0563,0x0564,0x0565,0x0566,0x0567,
+ 0x0568,0x0569,0x056a,0x056b,0x056c,0x056d,0x056e,0x056f,
+ 0x0570,0x0571,0x0572,0x0573,0x0574,0x0575,0x0576,0x0577,
+ 0x0578,0x0579,0x057a,0x057b,0x057c,0x057d,0x057e,0x057f,
+ 0x0580,0x0581,0x0582,0x0583,0x0584,0x0585,0x0586,0x0557,
+ 0x0558,0x0559,0x055a,0x055b,0x055c,0x055d,0x055e,0x055f,
+ 0x0560,0x0561,0x0562,0x0563,0x0564,0x0565,0x0566,0x0567,
+ 0x0568,0x0569,0x056a,0x056b,0x056c,0x056d,0x056e,0x056f,
+ 0x0570,0x0571,0x0572,0x0573,0x0574,0x0575,0x0576,0x0577,
+ 0x0578,0x0579,0x057a,0x057b,0x057c,0x057d,0x057e,0x057f,
+ 0x0580,0x0581,0x0582,0x0583,0x0584,0x0585,0x0586,0x0587,
+ 0x0588,0x0589,0x058a,0x058b,0x058c,0x058d,0x058e,0x058f,
+ 0x0590,0x0591,0x0592,0x0593,0x0594,0x0595,0x0596,0x0597,
+ 0x0598,0x0599,0x059a,0x059b,0x059c,0x059d,0x059e,0x059f,
+ 0x05a0,0x05a1,0x05a2,0x05a3,0x05a4,0x05a5,0x05a6,0x05a7,
+ 0x05a8,0x05a9,0x05aa,0x05ab,0x05ac,0x05ad,0x05ae,0x05af,
+ 0x05b0,0x05b1,0x05b2,0x05b3,0x05b4,0x05b5,0x05b6,0x05b7,
+ 0x05b8,0x05b9,0x05ba,0x05bb,0x05bc,0x05bd,0x05be,0x05bf,
+ 0x05c0,0x05c1,0x05c2,0x05c3,0x05c4,0x05c5,0x05c6,0x05c7,
+ 0x05c8,0x05c9,0x05ca,0x05cb,0x05cc,0x05cd,0x05ce,0x05cf,
+ 0x05d0,0x05d1,0x05d2,0x05d3,0x05d4,0x05d5,0x05d6,0x05d7,
+ 0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,
+ 0x05e0,0x05e1,0x05e2,0x05e3,0x05e4,0x05e5,0x05e6,0x05e7,
+ 0x05e8,0x05e9,0x05ea,0x05eb,0x05ec,0x05ed,0x05ee,0x05ef,
+ 0x05f0,0x05f1,0x05f2,0x05f3,0x05f4,0x05f5,0x05f6,0x05f7,
+ 0x05f8,0x05f9,0x05fa,0x05fb,0x05fc,0x05fd,0x05fe,0x05ff,
+ 0x0600,0x0601,0x0602,0x0603,0x0604,0x0605,0x0606,0x0607,
+ 0x0608,0x0609,0x060a,0x060b,0x060c,0x060d,0x060e,0x060f,
+ 0x0610,0x0611,0x0612,0x0613,0x0614,0x0615,0x0616,0x0617,
+ 0x0618,0x0619,0x061a,0x061b,0x061c,0x061d,0x061e,0x061f,
+ 0x0620,0x0621,0x0622,0x0623,0x0624,0x0625,0x0626,0x0627,
+ 0x0628,0x0629,0x062a,0x062b,0x062c,0x062d,0x062e,0x062f,
+ 0x0630,0x0631,0x0632,0x0633,0x0634,0x0635,0x0636,0x0637,
+ 0x0638,0x0639,0x063a,0x063b,0x063c,0x063d,0x063e,0x063f,
+ 0x0640,0x0641,0x0642,0x0643,0x0644,0x0645,0x0646,0x0647,
+ 0x0648,0x0649,0x064a,0x064b,0x064c,0x064d,0x064e,0x064f,
+ 0x0650,0x0651,0x0652,0x0653,0x0654,0x0655,0x0656,0x0657,
+ 0x0658,0x0659,0x065a,0x065b,0x065c,0x065d,0x065e,0x065f,
+ 0x0660,0x0661,0x0662,0x0663,0x0664,0x0665,0x0666,0x0667,
+ 0x0668,0x0669,0x066a,0x066b,0x066c,0x066d,0x066e,0x066f,
+ 0x0670,0x0671,0x0672,0x0673,0x0674,0x0675,0x0676,0x0677,
+ 0x0678,0x0679,0x067a,0x067b,0x067c,0x067d,0x067e,0x067f,
+ 0x0680,0x0681,0x0682,0x0683,0x0684,0x0685,0x0686,0x0687,
+ 0x0688,0x0689,0x068a,0x068b,0x068c,0x068d,0x068e,0x068f,
+ 0x0690,0x0691,0x0692,0x0693,0x0694,0x0695,0x0696,0x0697,
+ 0x0698,0x0699,0x069a,0x069b,0x069c,0x069d,0x069e,0x069f,
+ 0x06a0,0x06a1,0x06a2,0x06a3,0x06a4,0x06a5,0x06a6,0x06a7,
+ 0x06a8,0x06a9,0x06aa,0x06ab,0x06ac,0x06ad,0x06ae,0x06af,
+ 0x06b0,0x06b1,0x06b2,0x06b3,0x06b4,0x06b5,0x06b6,0x06b7,
+ 0x06b8,0x06b9,0x06ba,0x06bb,0x06bc,0x06bd,0x06be,0x06bf,
+ 0x06c0,0x06c1,0x06c2,0x06c3,0x06c4,0x06c5,0x06c6,0x06c7,
+ 0x06c8,0x06c9,0x06ca,0x06cb,0x06cc,0x06cd,0x06ce,0x06cf,
+ 0x06d0,0x06d1,0x06d2,0x06d3,0x06d4,0x06d5,0x06d6,0x06d7,
+ 0x06d8,0x06d9,0x06da,0x06db,0x06dc,0x06dd,0x06de,0x06df,
+ 0x06e0,0x06e1,0x06e2,0x06e3,0x06e4,0x06e5,0x06e6,0x06e7,
+ 0x06e8,0x06e9,0x06ea,0x06eb,0x06ec,0x06ed,0x06ee,0x06ef,
+ 0x06f0,0x06f1,0x06f2,0x06f3,0x06f4,0x06f5,0x06f6,0x06f7,
+ 0x06f8,0x06f9,0x06fa,0x06fb,0x06fc,0x06fd,0x06fe,0x06ff,
+ 0x0700,0x0701,0x0702,0x0703,0x0704,0x0705,0x0706,0x0707,
+ 0x0708,0x0709,0x070a,0x070b,0x070c,0x070d,0x070e,0x070f,
+ 0x0710,0x0711,0x0712,0x0713,0x0714,0x0715,0x0716,0x0717,
+ 0x0718,0x0719,0x071a,0x071b,0x071c,0x071d,0x071e,0x071f,
+ 0x0720,0x0721,0x0722,0x0723,0x0724,0x0725,0x0726,0x0727,
+ 0x0728,0x0729,0x072a,0x072b,0x072c,0x072d,0x072e,0x072f,
+ 0x0730,0x0731,0x0732,0x0733,0x0734,0x0735,0x0736,0x0737,
+ 0x0738,0x0739,0x073a,0x073b,0x073c,0x073d,0x073e,0x073f,
+ 0x0740,0x0741,0x0742,0x0743,0x0744,0x0745,0x0746,0x0747,
+ 0x0748,0x0749,0x074a,0x074b,0x074c,0x074d,0x074e,0x074f,
+ 0x0750,0x0751,0x0752,0x0753,0x0754,0x0755,0x0756,0x0757,
+ 0x0758,0x0759,0x075a,0x075b,0x075c,0x075d,0x075e,0x075f,
+ 0x0760,0x0761,0x0762,0x0763,0x0764,0x0765,0x0766,0x0767,
+ 0x0768,0x0769,0x076a,0x076b,0x076c,0x076d,0x076e,0x076f,
+ 0x0770,0x0771,0x0772,0x0773,0x0774,0x0775,0x0776,0x0777,
+ 0x0778,0x0779,0x077a,0x077b,0x077c,0x077d,0x077e,0x077f,
+ 0x0780,0x0781,0x0782,0x0783,0x0784,0x0785,0x0786,0x0787,
+ 0x0788,0x0789,0x078a,0x078b,0x078c,0x078d,0x078e,0x078f,
+ 0x0790,0x0791,0x0792,0x0793,0x0794,0x0795,0x0796,0x0797,
+ 0x0798,0x0799,0x079a,0x079b,0x079c,0x079d,0x079e,0x079f,
+ 0x07a0,0x07a1,0x07a2,0x07a3,0x07a4,0x07a5,0x07a6,0x07a7,
+ 0x07a8,0x07a9,0x07aa,0x07ab,0x07ac,0x07ad,0x07ae,0x07af,
+ 0x07b0,0x07b1,0x07b2,0x07b3,0x07b4,0x07b5,0x07b6,0x07b7,
+ 0x07b8,0x07b9,0x07ba,0x07bb,0x07bc,0x07bd,0x07be,0x07bf,
+ 0x07c0,0x07c1,0x07c2,0x07c3,0x07c4,0x07c5,0x07c6,0x07c7,
+ 0x07c8,0x07c9,0x07ca,0x07cb,0x07cc,0x07cd,0x07ce,0x07cf,
+ 0x07d0,0x07d1,0x07d2,0x07d3,0x07d4,0x07d5,0x07d6,0x07d7,
+ 0x07d8,0x07d9,0x07da,0x07db,0x07dc,0x07dd,0x07de,0x07df,
+ 0x07e0,0x07e1,0x07e2,0x07e3,0x07e4,0x07e5,0x07e6,0x07e7,
+ 0x07e8,0x07e9,0x07ea,0x07eb,0x07ec,0x07ed,0x07ee,0x07ef,
+ 0x07f0,0x07f1,0x07f2,0x07f3,0x07f4,0x07f5,0x07f6,0x07f7,
+ 0x07f8,0x07f9,0x07fa,0x07fb,0x07fc,0x07fd,0x07fe,0x07ff,
+ 0x0800,0x0801,0x0802,0x0803,0x0804,0x0805,0x0806,0x0807,
+ 0x0808,0x0809,0x080a,0x080b,0x080c,0x080d,0x080e,0x080f,
+ 0x0810,0x0811,0x0812,0x0813,0x0814,0x0815,0x0816,0x0817,
+ 0x0818,0x0819,0x081a,0x081b,0x081c,0x081d,0x081e,0x081f,
+ 0x0820,0x0821,0x0822,0x0823,0x0824,0x0825,0x0826,0x0827,
+ 0x0828,0x0829,0x082a,0x082b,0x082c,0x082d,0x082e,0x082f,
+ 0x0830,0x0831,0x0832,0x0833,0x0834,0x0835,0x0836,0x0837,
+ 0x0838,0x0839,0x083a,0x083b,0x083c,0x083d,0x083e,0x083f,
+ 0x0840,0x0841,0x0842,0x0843,0x0844,0x0845,0x0846,0x0847,
+ 0x0848,0x0849,0x084a,0x084b,0x084c,0x084d,0x084e,0x084f,
+ 0x0850,0x0851,0x0852,0x0853,0x0854,0x0855,0x0856,0x0857,
+ 0x0858,0x0859,0x085a,0x085b,0x085c,0x085d,0x085e,0x085f,
+ 0x0860,0x0861,0x0862,0x0863,0x0864,0x0865,0x0866,0x0867,
+ 0x0868,0x0869,0x086a,0x086b,0x086c,0x086d,0x086e,0x086f,
+ 0x0870,0x0871,0x0872,0x0873,0x0874,0x0875,0x0876,0x0877,
+ 0x0878,0x0879,0x087a,0x087b,0x087c,0x087d,0x087e,0x087f,
+ 0x0880,0x0881,0x0882,0x0883,0x0884,0x0885,0x0886,0x0887,
+ 0x0888,0x0889,0x088a,0x088b,0x088c,0x088d,0x088e,0x088f,
+ 0x0890,0x0891,0x0892,0x0893,0x0894,0x0895,0x0896,0x0897,
+ 0x0898,0x0899,0x089a,0x089b,0x089c,0x089d,0x089e,0x089f,
+ 0x08a0,0x08a1,0x08a2,0x08a3,0x08a4,0x08a5,0x08a6,0x08a7,
+ 0x08a8,0x08a9,0x08aa,0x08ab,0x08ac,0x08ad,0x08ae,0x08af,
+ 0x08b0,0x08b1,0x08b2,0x08b3,0x08b4,0x08b5,0x08b6,0x08b7,
+ 0x08b8,0x08b9,0x08ba,0x08bb,0x08bc,0x08bd,0x08be,0x08bf,
+ 0x08c0,0x08c1,0x08c2,0x08c3,0x08c4,0x08c5,0x08c6,0x08c7,
+ 0x08c8,0x08c9,0x08ca,0x08cb,0x08cc,0x08cd,0x08ce,0x08cf,
+ 0x08d0,0x08d1,0x08d2,0x08d3,0x08d4,0x08d5,0x08d6,0x08d7,
+ 0x08d8,0x08d9,0x08da,0x08db,0x08dc,0x08dd,0x08de,0x08df,
+ 0x08e0,0x08e1,0x08e2,0x08e3,0x08e4,0x08e5,0x08e6,0x08e7,
+ 0x08e8,0x08e9,0x08ea,0x08eb,0x08ec,0x08ed,0x08ee,0x08ef,
+ 0x08f0,0x08f1,0x08f2,0x08f3,0x08f4,0x08f5,0x08f6,0x08f7,
+ 0x08f8,0x08f9,0x08fa,0x08fb,0x08fc,0x08fd,0x08fe,0x08ff,
+ 0x0900,0x0901,0x0902,0x0903,0x0904,0x0905,0x0906,0x0907,
+ 0x0908,0x0909,0x090a,0x090b,0x090c,0x090d,0x090e,0x090f,
+ 0x0910,0x0911,0x0912,0x0913,0x0914,0x0915,0x0916,0x0917,
+ 0x0918,0x0919,0x091a,0x091b,0x091c,0x091d,0x091e,0x091f,
+ 0x0920,0x0921,0x0922,0x0923,0x0924,0x0925,0x0926,0x0927,
+ 0x0928,0x0929,0x092a,0x092b,0x092c,0x092d,0x092e,0x092f,
+ 0x0930,0x0931,0x0932,0x0933,0x0934,0x0935,0x0936,0x0937,
+ 0x0938,0x0939,0x093a,0x093b,0x093c,0x093d,0x093e,0x093f,
+ 0x0940,0x0941,0x0942,0x0943,0x0944,0x0945,0x0946,0x0947,
+ 0x0948,0x0949,0x094a,0x094b,0x094c,0x094d,0x094e,0x094f,
+ 0x0950,0x0951,0x0952,0x0953,0x0954,0x0955,0x0956,0x0957,
+ 0x0958,0x0959,0x095a,0x095b,0x095c,0x095d,0x095e,0x095f,
+ 0x0960,0x0961,0x0962,0x0963,0x0964,0x0965,0x0966,0x0967,
+ 0x0968,0x0969,0x096a,0x096b,0x096c,0x096d,0x096e,0x096f,
+ 0x0970,0x0971,0x0972,0x0973,0x0974,0x0975,0x0976,0x0977,
+ 0x0978,0x0979,0x097a,0x097b,0x097c,0x097d,0x097e,0x097f,
+ 0x0980,0x0981,0x0982,0x0983,0x0984,0x0985,0x0986,0x0987,
+ 0x0988,0x0989,0x098a,0x098b,0x098c,0x098d,0x098e,0x098f,
+ 0x0990,0x0991,0x0992,0x0993,0x0994,0x0995,0x0996,0x0997,
+ 0x0998,0x0999,0x099a,0x099b,0x099c,0x099d,0x099e,0x099f,
+ 0x09a0,0x09a1,0x09a2,0x09a3,0x09a4,0x09a5,0x09a6,0x09a7,
+ 0x09a8,0x09a9,0x09aa,0x09ab,0x09ac,0x09ad,0x09ae,0x09af,
+ 0x09b0,0x09b1,0x09b2,0x09b3,0x09b4,0x09b5,0x09b6,0x09b7,
+ 0x09b8,0x09b9,0x09ba,0x09bb,0x09bc,0x09bd,0x09be,0x09bf,
+ 0x09c0,0x09c1,0x09c2,0x09c3,0x09c4,0x09c5,0x09c6,0x09c7,
+ 0x09c8,0x09c9,0x09ca,0x09cb,0x09cc,0x09cd,0x09ce,0x09cf,
+ 0x09d0,0x09d1,0x09d2,0x09d3,0x09d4,0x09d5,0x09d6,0x09d7,
+ 0x09d8,0x09d9,0x09da,0x09db,0x09dc,0x09dd,0x09de,0x09df,
+ 0x09e0,0x09e1,0x09e2,0x09e3,0x09e4,0x09e5,0x09e6,0x09e7,
+ 0x09e8,0x09e9,0x09ea,0x09eb,0x09ec,0x09ed,0x09ee,0x09ef,
+ 0x09f0,0x09f1,0x09f2,0x09f3,0x09f4,0x09f5,0x09f6,0x09f7,
+ 0x09f8,0x09f9,0x09fa,0x09fb,0x09fc,0x09fd,0x09fe,0x09ff,
+ 0x0a00,0x0a01,0x0a02,0x0a03,0x0a04,0x0a05,0x0a06,0x0a07,
+ 0x0a08,0x0a09,0x0a0a,0x0a0b,0x0a0c,0x0a0d,0x0a0e,0x0a0f,
+ 0x0a10,0x0a11,0x0a12,0x0a13,0x0a14,0x0a15,0x0a16,0x0a17,
+ 0x0a18,0x0a19,0x0a1a,0x0a1b,0x0a1c,0x0a1d,0x0a1e,0x0a1f,
+ 0x0a20,0x0a21,0x0a22,0x0a23,0x0a24,0x0a25,0x0a26,0x0a27,
+ 0x0a28,0x0a29,0x0a2a,0x0a2b,0x0a2c,0x0a2d,0x0a2e,0x0a2f,
+ 0x0a30,0x0a31,0x0a32,0x0a33,0x0a34,0x0a35,0x0a36,0x0a37,
+ 0x0a38,0x0a39,0x0a3a,0x0a3b,0x0a3c,0x0a3d,0x0a3e,0x0a3f,
+ 0x0a40,0x0a41,0x0a42,0x0a43,0x0a44,0x0a45,0x0a46,0x0a47,
+ 0x0a48,0x0a49,0x0a4a,0x0a4b,0x0a4c,0x0a4d,0x0a4e,0x0a4f,
+ 0x0a50,0x0a51,0x0a52,0x0a53,0x0a54,0x0a55,0x0a56,0x0a57,
+ 0x0a58,0x0a59,0x0a5a,0x0a5b,0x0a5c,0x0a5d,0x0a5e,0x0a5f,
+ 0x0a60,0x0a61,0x0a62,0x0a63,0x0a64,0x0a65,0x0a66,0x0a67,
+ 0x0a68,0x0a69,0x0a6a,0x0a6b,0x0a6c,0x0a6d,0x0a6e,0x0a6f,
+ 0x0a70,0x0a71,0x0a72,0x0a73,0x0a74,0x0a75,0x0a76,0x0a77,
+ 0x0a78,0x0a79,0x0a7a,0x0a7b,0x0a7c,0x0a7d,0x0a7e,0x0a7f,
+ 0x0a80,0x0a81,0x0a82,0x0a83,0x0a84,0x0a85,0x0a86,0x0a87,
+ 0x0a88,0x0a89,0x0a8a,0x0a8b,0x0a8c,0x0a8d,0x0a8e,0x0a8f,
+ 0x0a90,0x0a91,0x0a92,0x0a93,0x0a94,0x0a95,0x0a96,0x0a97,
+ 0x0a98,0x0a99,0x0a9a,0x0a9b,0x0a9c,0x0a9d,0x0a9e,0x0a9f,
+ 0x0aa0,0x0aa1,0x0aa2,0x0aa3,0x0aa4,0x0aa5,0x0aa6,0x0aa7,
+ 0x0aa8,0x0aa9,0x0aaa,0x0aab,0x0aac,0x0aad,0x0aae,0x0aaf,
+ 0x0ab0,0x0ab1,0x0ab2,0x0ab3,0x0ab4,0x0ab5,0x0ab6,0x0ab7,
+ 0x0ab8,0x0ab9,0x0aba,0x0abb,0x0abc,0x0abd,0x0abe,0x0abf,
+ 0x0ac0,0x0ac1,0x0ac2,0x0ac3,0x0ac4,0x0ac5,0x0ac6,0x0ac7,
+ 0x0ac8,0x0ac9,0x0aca,0x0acb,0x0acc,0x0acd,0x0ace,0x0acf,
+ 0x0ad0,0x0ad1,0x0ad2,0x0ad3,0x0ad4,0x0ad5,0x0ad6,0x0ad7,
+ 0x0ad8,0x0ad9,0x0ada,0x0adb,0x0adc,0x0add,0x0ade,0x0adf,
+ 0x0ae0,0x0ae1,0x0ae2,0x0ae3,0x0ae4,0x0ae5,0x0ae6,0x0ae7,
+ 0x0ae8,0x0ae9,0x0aea,0x0aeb,0x0aec,0x0aed,0x0aee,0x0aef,
+ 0x0af0,0x0af1,0x0af2,0x0af3,0x0af4,0x0af5,0x0af6,0x0af7,
+ 0x0af8,0x0af9,0x0afa,0x0afb,0x0afc,0x0afd,0x0afe,0x0aff,
+ 0x0b00,0x0b01,0x0b02,0x0b03,0x0b04,0x0b05,0x0b06,0x0b07,
+ 0x0b08,0x0b09,0x0b0a,0x0b0b,0x0b0c,0x0b0d,0x0b0e,0x0b0f,
+ 0x0b10,0x0b11,0x0b12,0x0b13,0x0b14,0x0b15,0x0b16,0x0b17,
+ 0x0b18,0x0b19,0x0b1a,0x0b1b,0x0b1c,0x0b1d,0x0b1e,0x0b1f,
+ 0x0b20,0x0b21,0x0b22,0x0b23,0x0b24,0x0b25,0x0b26,0x0b27,
+ 0x0b28,0x0b29,0x0b2a,0x0b2b,0x0b2c,0x0b2d,0x0b2e,0x0b2f,
+ 0x0b30,0x0b31,0x0b32,0x0b33,0x0b34,0x0b35,0x0b36,0x0b37,
+ 0x0b38,0x0b39,0x0b3a,0x0b3b,0x0b3c,0x0b3d,0x0b3e,0x0b3f,
+ 0x0b40,0x0b41,0x0b42,0x0b43,0x0b44,0x0b45,0x0b46,0x0b47,
+ 0x0b48,0x0b49,0x0b4a,0x0b4b,0x0b4c,0x0b4d,0x0b4e,0x0b4f,
+ 0x0b50,0x0b51,0x0b52,0x0b53,0x0b54,0x0b55,0x0b56,0x0b57,
+ 0x0b58,0x0b59,0x0b5a,0x0b5b,0x0b5c,0x0b5d,0x0b5e,0x0b5f,
+ 0x0b60,0x0b61,0x0b62,0x0b63,0x0b64,0x0b65,0x0b66,0x0b67,
+ 0x0b68,0x0b69,0x0b6a,0x0b6b,0x0b6c,0x0b6d,0x0b6e,0x0b6f,
+ 0x0b70,0x0b71,0x0b72,0x0b73,0x0b74,0x0b75,0x0b76,0x0b77,
+ 0x0b78,0x0b79,0x0b7a,0x0b7b,0x0b7c,0x0b7d,0x0b7e,0x0b7f,
+ 0x0b80,0x0b81,0x0b82,0x0b83,0x0b84,0x0b85,0x0b86,0x0b87,
+ 0x0b88,0x0b89,0x0b8a,0x0b8b,0x0b8c,0x0b8d,0x0b8e,0x0b8f,
+ 0x0b90,0x0b91,0x0b92,0x0b93,0x0b94,0x0b95,0x0b96,0x0b97,
+ 0x0b98,0x0b99,0x0b9a,0x0b9b,0x0b9c,0x0b9d,0x0b9e,0x0b9f,
+ 0x0ba0,0x0ba1,0x0ba2,0x0ba3,0x0ba4,0x0ba5,0x0ba6,0x0ba7,
+ 0x0ba8,0x0ba9,0x0baa,0x0bab,0x0bac,0x0bad,0x0bae,0x0baf,
+ 0x0bb0,0x0bb1,0x0bb2,0x0bb3,0x0bb4,0x0bb5,0x0bb6,0x0bb7,
+ 0x0bb8,0x0bb9,0x0bba,0x0bbb,0x0bbc,0x0bbd,0x0bbe,0x0bbf,
+ 0x0bc0,0x0bc1,0x0bc2,0x0bc3,0x0bc4,0x0bc5,0x0bc6,0x0bc7,
+ 0x0bc8,0x0bc9,0x0bca,0x0bcb,0x0bcc,0x0bcd,0x0bce,0x0bcf,
+ 0x0bd0,0x0bd1,0x0bd2,0x0bd3,0x0bd4,0x0bd5,0x0bd6,0x0bd7,
+ 0x0bd8,0x0bd9,0x0bda,0x0bdb,0x0bdc,0x0bdd,0x0bde,0x0bdf,
+ 0x0be0,0x0be1,0x0be2,0x0be3,0x0be4,0x0be5,0x0be6,0x0be7,
+ 0x0be8,0x0be9,0x0bea,0x0beb,0x0bec,0x0bed,0x0bee,0x0bef,
+ 0x0bf0,0x0bf1,0x0bf2,0x0bf3,0x0bf4,0x0bf5,0x0bf6,0x0bf7,
+ 0x0bf8,0x0bf9,0x0bfa,0x0bfb,0x0bfc,0x0bfd,0x0bfe,0x0bff,
+ 0x0c00,0x0c01,0x0c02,0x0c03,0x0c04,0x0c05,0x0c06,0x0c07,
+ 0x0c08,0x0c09,0x0c0a,0x0c0b,0x0c0c,0x0c0d,0x0c0e,0x0c0f,
+ 0x0c10,0x0c11,0x0c12,0x0c13,0x0c14,0x0c15,0x0c16,0x0c17,
+ 0x0c18,0x0c19,0x0c1a,0x0c1b,0x0c1c,0x0c1d,0x0c1e,0x0c1f,
+ 0x0c20,0x0c21,0x0c22,0x0c23,0x0c24,0x0c25,0x0c26,0x0c27,
+ 0x0c28,0x0c29,0x0c2a,0x0c2b,0x0c2c,0x0c2d,0x0c2e,0x0c2f,
+ 0x0c30,0x0c31,0x0c32,0x0c33,0x0c34,0x0c35,0x0c36,0x0c37,
+ 0x0c38,0x0c39,0x0c3a,0x0c3b,0x0c3c,0x0c3d,0x0c3e,0x0c3f,
+ 0x0c40,0x0c41,0x0c42,0x0c43,0x0c44,0x0c45,0x0c46,0x0c47,
+ 0x0c48,0x0c49,0x0c4a,0x0c4b,0x0c4c,0x0c4d,0x0c4e,0x0c4f,
+ 0x0c50,0x0c51,0x0c52,0x0c53,0x0c54,0x0c55,0x0c56,0x0c57,
+ 0x0c58,0x0c59,0x0c5a,0x0c5b,0x0c5c,0x0c5d,0x0c5e,0x0c5f,
+ 0x0c60,0x0c61,0x0c62,0x0c63,0x0c64,0x0c65,0x0c66,0x0c67,
+ 0x0c68,0x0c69,0x0c6a,0x0c6b,0x0c6c,0x0c6d,0x0c6e,0x0c6f,
+ 0x0c70,0x0c71,0x0c72,0x0c73,0x0c74,0x0c75,0x0c76,0x0c77,
+ 0x0c78,0x0c79,0x0c7a,0x0c7b,0x0c7c,0x0c7d,0x0c7e,0x0c7f,
+ 0x0c80,0x0c81,0x0c82,0x0c83,0x0c84,0x0c85,0x0c86,0x0c87,
+ 0x0c88,0x0c89,0x0c8a,0x0c8b,0x0c8c,0x0c8d,0x0c8e,0x0c8f,
+ 0x0c90,0x0c91,0x0c92,0x0c93,0x0c94,0x0c95,0x0c96,0x0c97,
+ 0x0c98,0x0c99,0x0c9a,0x0c9b,0x0c9c,0x0c9d,0x0c9e,0x0c9f,
+ 0x0ca0,0x0ca1,0x0ca2,0x0ca3,0x0ca4,0x0ca5,0x0ca6,0x0ca7,
+ 0x0ca8,0x0ca9,0x0caa,0x0cab,0x0cac,0x0cad,0x0cae,0x0caf,
+ 0x0cb0,0x0cb1,0x0cb2,0x0cb3,0x0cb4,0x0cb5,0x0cb6,0x0cb7,
+ 0x0cb8,0x0cb9,0x0cba,0x0cbb,0x0cbc,0x0cbd,0x0cbe,0x0cbf,
+ 0x0cc0,0x0cc1,0x0cc2,0x0cc3,0x0cc4,0x0cc5,0x0cc6,0x0cc7,
+ 0x0cc8,0x0cc9,0x0cca,0x0ccb,0x0ccc,0x0ccd,0x0cce,0x0ccf,
+ 0x0cd0,0x0cd1,0x0cd2,0x0cd3,0x0cd4,0x0cd5,0x0cd6,0x0cd7,
+ 0x0cd8,0x0cd9,0x0cda,0x0cdb,0x0cdc,0x0cdd,0x0cde,0x0cdf,
+ 0x0ce0,0x0ce1,0x0ce2,0x0ce3,0x0ce4,0x0ce5,0x0ce6,0x0ce7,
+ 0x0ce8,0x0ce9,0x0cea,0x0ceb,0x0cec,0x0ced,0x0cee,0x0cef,
+ 0x0cf0,0x0cf1,0x0cf2,0x0cf3,0x0cf4,0x0cf5,0x0cf6,0x0cf7,
+ 0x0cf8,0x0cf9,0x0cfa,0x0cfb,0x0cfc,0x0cfd,0x0cfe,0x0cff,
+ 0x0d00,0x0d01,0x0d02,0x0d03,0x0d04,0x0d05,0x0d06,0x0d07,
+ 0x0d08,0x0d09,0x0d0a,0x0d0b,0x0d0c,0x0d0d,0x0d0e,0x0d0f,
+ 0x0d10,0x0d11,0x0d12,0x0d13,0x0d14,0x0d15,0x0d16,0x0d17,
+ 0x0d18,0x0d19,0x0d1a,0x0d1b,0x0d1c,0x0d1d,0x0d1e,0x0d1f,
+ 0x0d20,0x0d21,0x0d22,0x0d23,0x0d24,0x0d25,0x0d26,0x0d27,
+ 0x0d28,0x0d29,0x0d2a,0x0d2b,0x0d2c,0x0d2d,0x0d2e,0x0d2f,
+ 0x0d30,0x0d31,0x0d32,0x0d33,0x0d34,0x0d35,0x0d36,0x0d37,
+ 0x0d38,0x0d39,0x0d3a,0x0d3b,0x0d3c,0x0d3d,0x0d3e,0x0d3f,
+ 0x0d40,0x0d41,0x0d42,0x0d43,0x0d44,0x0d45,0x0d46,0x0d47,
+ 0x0d48,0x0d49,0x0d4a,0x0d4b,0x0d4c,0x0d4d,0x0d4e,0x0d4f,
+ 0x0d50,0x0d51,0x0d52,0x0d53,0x0d54,0x0d55,0x0d56,0x0d57,
+ 0x0d58,0x0d59,0x0d5a,0x0d5b,0x0d5c,0x0d5d,0x0d5e,0x0d5f,
+ 0x0d60,0x0d61,0x0d62,0x0d63,0x0d64,0x0d65,0x0d66,0x0d67,
+ 0x0d68,0x0d69,0x0d6a,0x0d6b,0x0d6c,0x0d6d,0x0d6e,0x0d6f,
+ 0x0d70,0x0d71,0x0d72,0x0d73,0x0d74,0x0d75,0x0d76,0x0d77,
+ 0x0d78,0x0d79,0x0d7a,0x0d7b,0x0d7c,0x0d7d,0x0d7e,0x0d7f,
+ 0x0d80,0x0d81,0x0d82,0x0d83,0x0d84,0x0d85,0x0d86,0x0d87,
+ 0x0d88,0x0d89,0x0d8a,0x0d8b,0x0d8c,0x0d8d,0x0d8e,0x0d8f,
+ 0x0d90,0x0d91,0x0d92,0x0d93,0x0d94,0x0d95,0x0d96,0x0d97,
+ 0x0d98,0x0d99,0x0d9a,0x0d9b,0x0d9c,0x0d9d,0x0d9e,0x0d9f,
+ 0x0da0,0x0da1,0x0da2,0x0da3,0x0da4,0x0da5,0x0da6,0x0da7,
+ 0x0da8,0x0da9,0x0daa,0x0dab,0x0dac,0x0dad,0x0dae,0x0daf,
+ 0x0db0,0x0db1,0x0db2,0x0db3,0x0db4,0x0db5,0x0db6,0x0db7,
+ 0x0db8,0x0db9,0x0dba,0x0dbb,0x0dbc,0x0dbd,0x0dbe,0x0dbf,
+ 0x0dc0,0x0dc1,0x0dc2,0x0dc3,0x0dc4,0x0dc5,0x0dc6,0x0dc7,
+ 0x0dc8,0x0dc9,0x0dca,0x0dcb,0x0dcc,0x0dcd,0x0dce,0x0dcf,
+ 0x0dd0,0x0dd1,0x0dd2,0x0dd3,0x0dd4,0x0dd5,0x0dd6,0x0dd7,
+ 0x0dd8,0x0dd9,0x0dda,0x0ddb,0x0ddc,0x0ddd,0x0dde,0x0ddf,
+ 0x0de0,0x0de1,0x0de2,0x0de3,0x0de4,0x0de5,0x0de6,0x0de7,
+ 0x0de8,0x0de9,0x0dea,0x0deb,0x0dec,0x0ded,0x0dee,0x0def,
+ 0x0df0,0x0df1,0x0df2,0x0df3,0x0df4,0x0df5,0x0df6,0x0df7,
+ 0x0df8,0x0df9,0x0dfa,0x0dfb,0x0dfc,0x0dfd,0x0dfe,0x0dff,
+ 0x0e00,0x0e01,0x0e02,0x0e03,0x0e04,0x0e05,0x0e06,0x0e07,
+ 0x0e08,0x0e09,0x0e0a,0x0e0b,0x0e0c,0x0e0d,0x0e0e,0x0e0f,
+ 0x0e10,0x0e11,0x0e12,0x0e13,0x0e14,0x0e15,0x0e16,0x0e17,
+ 0x0e18,0x0e19,0x0e1a,0x0e1b,0x0e1c,0x0e1d,0x0e1e,0x0e1f,
+ 0x0e20,0x0e21,0x0e22,0x0e23,0x0e24,0x0e25,0x0e26,0x0e27,
+ 0x0e28,0x0e29,0x0e2a,0x0e2b,0x0e2c,0x0e2d,0x0e2e,0x0e2f,
+ 0x0e30,0x0e31,0x0e32,0x0e33,0x0e34,0x0e35,0x0e36,0x0e37,
+ 0x0e38,0x0e39,0x0e3a,0x0e3b,0x0e3c,0x0e3d,0x0e3e,0x0e3f,
+ 0x0e40,0x0e41,0x0e42,0x0e43,0x0e44,0x0e45,0x0e46,0x0e47,
+ 0x0e48,0x0e49,0x0e4a,0x0e4b,0x0e4c,0x0e4d,0x0e4e,0x0e4f,
+ 0x0e50,0x0e51,0x0e52,0x0e53,0x0e54,0x0e55,0x0e56,0x0e57,
+ 0x0e58,0x0e59,0x0e5a,0x0e5b,0x0e5c,0x0e5d,0x0e5e,0x0e5f,
+ 0x0e60,0x0e61,0x0e62,0x0e63,0x0e64,0x0e65,0x0e66,0x0e67,
+ 0x0e68,0x0e69,0x0e6a,0x0e6b,0x0e6c,0x0e6d,0x0e6e,0x0e6f,
+ 0x0e70,0x0e71,0x0e72,0x0e73,0x0e74,0x0e75,0x0e76,0x0e77,
+ 0x0e78,0x0e79,0x0e7a,0x0e7b,0x0e7c,0x0e7d,0x0e7e,0x0e7f,
+ 0x0e80,0x0e81,0x0e82,0x0e83,0x0e84,0x0e85,0x0e86,0x0e87,
+ 0x0e88,0x0e89,0x0e8a,0x0e8b,0x0e8c,0x0e8d,0x0e8e,0x0e8f,
+ 0x0e90,0x0e91,0x0e92,0x0e93,0x0e94,0x0e95,0x0e96,0x0e97,
+ 0x0e98,0x0e99,0x0e9a,0x0e9b,0x0e9c,0x0e9d,0x0e9e,0x0e9f,
+ 0x0ea0,0x0ea1,0x0ea2,0x0ea3,0x0ea4,0x0ea5,0x0ea6,0x0ea7,
+ 0x0ea8,0x0ea9,0x0eaa,0x0eab,0x0eac,0x0ead,0x0eae,0x0eaf,
+ 0x0eb0,0x0eb1,0x0eb2,0x0eb3,0x0eb4,0x0eb5,0x0eb6,0x0eb7,
+ 0x0eb8,0x0eb9,0x0eba,0x0ebb,0x0ebc,0x0ebd,0x0ebe,0x0ebf,
+ 0x0ec0,0x0ec1,0x0ec2,0x0ec3,0x0ec4,0x0ec5,0x0ec6,0x0ec7,
+ 0x0ec8,0x0ec9,0x0eca,0x0ecb,0x0ecc,0x0ecd,0x0ece,0x0ecf,
+ 0x0ed0,0x0ed1,0x0ed2,0x0ed3,0x0ed4,0x0ed5,0x0ed6,0x0ed7,
+ 0x0ed8,0x0ed9,0x0eda,0x0edb,0x0edc,0x0edd,0x0ede,0x0edf,
+ 0x0ee0,0x0ee1,0x0ee2,0x0ee3,0x0ee4,0x0ee5,0x0ee6,0x0ee7,
+ 0x0ee8,0x0ee9,0x0eea,0x0eeb,0x0eec,0x0eed,0x0eee,0x0eef,
+ 0x0ef0,0x0ef1,0x0ef2,0x0ef3,0x0ef4,0x0ef5,0x0ef6,0x0ef7,
+ 0x0ef8,0x0ef9,0x0efa,0x0efb,0x0efc,0x0efd,0x0efe,0x0eff,
+ 0x0f00,0x0f01,0x0f02,0x0f03,0x0f04,0x0f05,0x0f06,0x0f07,
+ 0x0f08,0x0f09,0x0f0a,0x0f0b,0x0f0c,0x0f0d,0x0f0e,0x0f0f,
+ 0x0f10,0x0f11,0x0f12,0x0f13,0x0f14,0x0f15,0x0f16,0x0f17,
+ 0x0f18,0x0f19,0x0f1a,0x0f1b,0x0f1c,0x0f1d,0x0f1e,0x0f1f,
+ 0x0f20,0x0f21,0x0f22,0x0f23,0x0f24,0x0f25,0x0f26,0x0f27,
+ 0x0f28,0x0f29,0x0f2a,0x0f2b,0x0f2c,0x0f2d,0x0f2e,0x0f2f,
+ 0x0f30,0x0f31,0x0f32,0x0f33,0x0f34,0x0f35,0x0f36,0x0f37,
+ 0x0f38,0x0f39,0x0f3a,0x0f3b,0x0f3c,0x0f3d,0x0f3e,0x0f3f,
+ 0x0f40,0x0f41,0x0f42,0x0f43,0x0f44,0x0f45,0x0f46,0x0f47,
+ 0x0f48,0x0f49,0x0f4a,0x0f4b,0x0f4c,0x0f4d,0x0f4e,0x0f4f,
+ 0x0f50,0x0f51,0x0f52,0x0f53,0x0f54,0x0f55,0x0f56,0x0f57,
+ 0x0f58,0x0f59,0x0f5a,0x0f5b,0x0f5c,0x0f5d,0x0f5e,0x0f5f,
+ 0x0f60,0x0f61,0x0f62,0x0f63,0x0f64,0x0f65,0x0f66,0x0f67,
+ 0x0f68,0x0f69,0x0f6a,0x0f6b,0x0f6c,0x0f6d,0x0f6e,0x0f6f,
+ 0x0f70,0x0f71,0x0f72,0x0f73,0x0f74,0x0f75,0x0f76,0x0f77,
+ 0x0f78,0x0f79,0x0f7a,0x0f7b,0x0f7c,0x0f7d,0x0f7e,0x0f7f,
+ 0x0f80,0x0f81,0x0f82,0x0f83,0x0f84,0x0f85,0x0f86,0x0f87,
+ 0x0f88,0x0f89,0x0f8a,0x0f8b,0x0f8c,0x0f8d,0x0f8e,0x0f8f,
+ 0x0f90,0x0f91,0x0f92,0x0f93,0x0f94,0x0f95,0x0f96,0x0f97,
+ 0x0f98,0x0f99,0x0f9a,0x0f9b,0x0f9c,0x0f9d,0x0f9e,0x0f9f,
+ 0x0fa0,0x0fa1,0x0fa2,0x0fa3,0x0fa4,0x0fa5,0x0fa6,0x0fa7,
+ 0x0fa8,0x0fa9,0x0faa,0x0fab,0x0fac,0x0fad,0x0fae,0x0faf,
+ 0x0fb0,0x0fb1,0x0fb2,0x0fb3,0x0fb4,0x0fb5,0x0fb6,0x0fb7,
+ 0x0fb8,0x0fb9,0x0fba,0x0fbb,0x0fbc,0x0fbd,0x0fbe,0x0fbf,
+ 0x0fc0,0x0fc1,0x0fc2,0x0fc3,0x0fc4,0x0fc5,0x0fc6,0x0fc7,
+ 0x0fc8,0x0fc9,0x0fca,0x0fcb,0x0fcc,0x0fcd,0x0fce,0x0fcf,
+ 0x0fd0,0x0fd1,0x0fd2,0x0fd3,0x0fd4,0x0fd5,0x0fd6,0x0fd7,
+ 0x0fd8,0x0fd9,0x0fda,0x0fdb,0x0fdc,0x0fdd,0x0fde,0x0fdf,
+ 0x0fe0,0x0fe1,0x0fe2,0x0fe3,0x0fe4,0x0fe5,0x0fe6,0x0fe7,
+ 0x0fe8,0x0fe9,0x0fea,0x0feb,0x0fec,0x0fed,0x0fee,0x0fef,
+ 0x0ff0,0x0ff1,0x0ff2,0x0ff3,0x0ff4,0x0ff5,0x0ff6,0x0ff7,
+ 0x0ff8,0x0ff9,0x0ffa,0x0ffb,0x0ffc,0x0ffd,0x0ffe,0x0fff,
+ 0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007,
+ 0x1008,0x1009,0x100a,0x100b,0x100c,0x100d,0x100e,0x100f,
+ 0x1010,0x1011,0x1012,0x1013,0x1014,0x1015,0x1016,0x1017,
+ 0x1018,0x1019,0x101a,0x101b,0x101c,0x101d,0x101e,0x101f,
+ 0x1020,0x1021,0x1022,0x1023,0x1024,0x1025,0x1026,0x1027,
+ 0x1028,0x1029,0x102a,0x102b,0x102c,0x102d,0x102e,0x102f,
+ 0x1030,0x1031,0x1032,0x1033,0x1034,0x1035,0x1036,0x1037,
+ 0x1038,0x1039,0x103a,0x103b,0x103c,0x103d,0x103e,0x103f,
+ 0x1040,0x1041,0x1042,0x1043,0x1044,0x1045,0x1046,0x1047,
+ 0x1048,0x1049,0x104a,0x104b,0x104c,0x104d,0x104e,0x104f,
+ 0x1050,0x1051,0x1052,0x1053,0x1054,0x1055,0x1056,0x1057,
+ 0x1058,0x1059,0x105a,0x105b,0x105c,0x105d,0x105e,0x105f,
+ 0x1060,0x1061,0x1062,0x1063,0x1064,0x1065,0x1066,0x1067,
+ 0x1068,0x1069,0x106a,0x106b,0x106c,0x106d,0x106e,0x106f,
+ 0x1070,0x1071,0x1072,0x1073,0x1074,0x1075,0x1076,0x1077,
+ 0x1078,0x1079,0x107a,0x107b,0x107c,0x107d,0x107e,0x107f,
+ 0x1080,0x1081,0x1082,0x1083,0x1084,0x1085,0x1086,0x1087,
+ 0x1088,0x1089,0x108a,0x108b,0x108c,0x108d,0x108e,0x108f,
+ 0x1090,0x1091,0x1092,0x1093,0x1094,0x1095,0x1096,0x1097,
+ 0x1098,0x1099,0x109a,0x109b,0x109c,0x109d,0x109e,0x109f,
+ 0x10a0,0x10a1,0x10a2,0x10a3,0x10a4,0x10a5,0x10a6,0x10a7,
+ 0x10a8,0x10a9,0x10aa,0x10ab,0x10ac,0x10ad,0x10ae,0x10af,
+ 0x10b0,0x10b1,0x10b2,0x10b3,0x10b4,0x10b5,0x10b6,0x10b7,
+ 0x10b8,0x10b9,0x10ba,0x10bb,0x10bc,0x10bd,0x10be,0x10bf,
+ 0x10c0,0x10c1,0x10c2,0x10c3,0x10c4,0x10c5,0x10c6,0x10c7,
+ 0x10c8,0x10c9,0x10ca,0x10cb,0x10cc,0x10cd,0x10ce,0x10cf,
+ 0x10d0,0x10d1,0x10d2,0x10d3,0x10d4,0x10d5,0x10d6,0x10d7,
+ 0x10d8,0x10d9,0x10da,0x10db,0x10dc,0x10dd,0x10de,0x10df,
+ 0x10e0,0x10e1,0x10e2,0x10e3,0x10e4,0x10e5,0x10e6,0x10e7,
+ 0x10e8,0x10e9,0x10ea,0x10eb,0x10ec,0x10ed,0x10ee,0x10ef,
+ 0x10f0,0x10f1,0x10f2,0x10f3,0x10f4,0x10f5,0x10f6,0x10f7,
+ 0x10f8,0x10f9,0x10fa,0x10fb,0x10fc,0x10fd,0x10fe,0x10ff,
+ 0x1100,0x1101,0x1102,0x1103,0x1104,0x1105,0x1106,0x1107,
+ 0x1108,0x1109,0x110a,0x110b,0x110c,0x110d,0x110e,0x110f,
+ 0x1110,0x1111,0x1112,0x1113,0x1114,0x1115,0x1116,0x1117,
+ 0x1118,0x1119,0x111a,0x111b,0x111c,0x111d,0x111e,0x111f,
+ 0x1120,0x1121,0x1122,0x1123,0x1124,0x1125,0x1126,0x1127,
+ 0x1128,0x1129,0x112a,0x112b,0x112c,0x112d,0x112e,0x112f,
+ 0x1130,0x1131,0x1132,0x1133,0x1134,0x1135,0x1136,0x1137,
+ 0x1138,0x1139,0x113a,0x113b,0x113c,0x113d,0x113e,0x113f,
+ 0x1140,0x1141,0x1142,0x1143,0x1144,0x1145,0x1146,0x1147,
+ 0x1148,0x1149,0x114a,0x114b,0x114c,0x114d,0x114e,0x114f,
+ 0x1150,0x1151,0x1152,0x1153,0x1154,0x1155,0x1156,0x1157,
+ 0x1158,0x1159,0x115a,0x115b,0x115c,0x115d,0x115e,0x115f,
+ 0x1160,0x1161,0x1162,0x1163,0x1164,0x1165,0x1166,0x1167,
+ 0x1168,0x1169,0x116a,0x116b,0x116c,0x116d,0x116e,0x116f,
+ 0x1170,0x1171,0x1172,0x1173,0x1174,0x1175,0x1176,0x1177,
+ 0x1178,0x1179,0x117a,0x117b,0x117c,0x117d,0x117e,0x117f,
+ 0x1180,0x1181,0x1182,0x1183,0x1184,0x1185,0x1186,0x1187,
+ 0x1188,0x1189,0x118a,0x118b,0x118c,0x118d,0x118e,0x118f,
+ 0x1190,0x1191,0x1192,0x1193,0x1194,0x1195,0x1196,0x1197,
+ 0x1198,0x1199,0x119a,0x119b,0x119c,0x119d,0x119e,0x119f,
+ 0x11a0,0x11a1,0x11a2,0x11a3,0x11a4,0x11a5,0x11a6,0x11a7,
+ 0x11a8,0x11a9,0x11aa,0x11ab,0x11ac,0x11ad,0x11ae,0x11af,
+ 0x11b0,0x11b1,0x11b2,0x11b3,0x11b4,0x11b5,0x11b6,0x11b7,
+ 0x11b8,0x11b9,0x11ba,0x11bb,0x11bc,0x11bd,0x11be,0x11bf,
+ 0x11c0,0x11c1,0x11c2,0x11c3,0x11c4,0x11c5,0x11c6,0x11c7,
+ 0x11c8,0x11c9,0x11ca,0x11cb,0x11cc,0x11cd,0x11ce,0x11cf,
+ 0x11d0,0x11d1,0x11d2,0x11d3,0x11d4,0x11d5,0x11d6,0x11d7,
+ 0x11d8,0x11d9,0x11da,0x11db,0x11dc,0x11dd,0x11de,0x11df,
+ 0x11e0,0x11e1,0x11e2,0x11e3,0x11e4,0x11e5,0x11e6,0x11e7,
+ 0x11e8,0x11e9,0x11ea,0x11eb,0x11ec,0x11ed,0x11ee,0x11ef,
+ 0x11f0,0x11f1,0x11f2,0x11f3,0x11f4,0x11f5,0x11f6,0x11f7,
+ 0x11f8,0x11f9,0x11fa,0x11fb,0x11fc,0x11fd,0x11fe,0x11ff,
+ 0x1200,0x1201,0x1202,0x1203,0x1204,0x1205,0x1206,0x1207,
+ 0x1208,0x1209,0x120a,0x120b,0x120c,0x120d,0x120e,0x120f,
+ 0x1210,0x1211,0x1212,0x1213,0x1214,0x1215,0x1216,0x1217,
+ 0x1218,0x1219,0x121a,0x121b,0x121c,0x121d,0x121e,0x121f,
+ 0x1220,0x1221,0x1222,0x1223,0x1224,0x1225,0x1226,0x1227,
+ 0x1228,0x1229,0x122a,0x122b,0x122c,0x122d,0x122e,0x122f,
+ 0x1230,0x1231,0x1232,0x1233,0x1234,0x1235,0x1236,0x1237,
+ 0x1238,0x1239,0x123a,0x123b,0x123c,0x123d,0x123e,0x123f,
+ 0x1240,0x1241,0x1242,0x1243,0x1244,0x1245,0x1246,0x1247,
+ 0x1248,0x1249,0x124a,0x124b,0x124c,0x124d,0x124e,0x124f,
+ 0x1250,0x1251,0x1252,0x1253,0x1254,0x1255,0x1256,0x1257,
+ 0x1258,0x1259,0x125a,0x125b,0x125c,0x125d,0x125e,0x125f,
+ 0x1260,0x1261,0x1262,0x1263,0x1264,0x1265,0x1266,0x1267,
+ 0x1268,0x1269,0x126a,0x126b,0x126c,0x126d,0x126e,0x126f,
+ 0x1270,0x1271,0x1272,0x1273,0x1274,0x1275,0x1276,0x1277,
+ 0x1278,0x1279,0x127a,0x127b,0x127c,0x127d,0x127e,0x127f,
+ 0x1280,0x1281,0x1282,0x1283,0x1284,0x1285,0x1286,0x1287,
+ 0x1288,0x1289,0x128a,0x128b,0x128c,0x128d,0x128e,0x128f,
+ 0x1290,0x1291,0x1292,0x1293,0x1294,0x1295,0x1296,0x1297,
+ 0x1298,0x1299,0x129a,0x129b,0x129c,0x129d,0x129e,0x129f,
+ 0x12a0,0x12a1,0x12a2,0x12a3,0x12a4,0x12a5,0x12a6,0x12a7,
+ 0x12a8,0x12a9,0x12aa,0x12ab,0x12ac,0x12ad,0x12ae,0x12af,
+ 0x12b0,0x12b1,0x12b2,0x12b3,0x12b4,0x12b5,0x12b6,0x12b7,
+ 0x12b8,0x12b9,0x12ba,0x12bb,0x12bc,0x12bd,0x12be,0x12bf,
+ 0x12c0,0x12c1,0x12c2,0x12c3,0x12c4,0x12c5,0x12c6,0x12c7,
+ 0x12c8,0x12c9,0x12ca,0x12cb,0x12cc,0x12cd,0x12ce,0x12cf,
+ 0x12d0,0x12d1,0x12d2,0x12d3,0x12d4,0x12d5,0x12d6,0x12d7,
+ 0x12d8,0x12d9,0x12da,0x12db,0x12dc,0x12dd,0x12de,0x12df,
+ 0x12e0,0x12e1,0x12e2,0x12e3,0x12e4,0x12e5,0x12e6,0x12e7,
+ 0x12e8,0x12e9,0x12ea,0x12eb,0x12ec,0x12ed,0x12ee,0x12ef,
+ 0x12f0,0x12f1,0x12f2,0x12f3,0x12f4,0x12f5,0x12f6,0x12f7,
+ 0x12f8,0x12f9,0x12fa,0x12fb,0x12fc,0x12fd,0x12fe,0x12ff,
+ 0x1300,0x1301,0x1302,0x1303,0x1304,0x1305,0x1306,0x1307,
+ 0x1308,0x1309,0x130a,0x130b,0x130c,0x130d,0x130e,0x130f,
+ 0x1310,0x1311,0x1312,0x1313,0x1314,0x1315,0x1316,0x1317,
+ 0x1318,0x1319,0x131a,0x131b,0x131c,0x131d,0x131e,0x131f,
+ 0x1320,0x1321,0x1322,0x1323,0x1324,0x1325,0x1326,0x1327,
+ 0x1328,0x1329,0x132a,0x132b,0x132c,0x132d,0x132e,0x132f,
+ 0x1330,0x1331,0x1332,0x1333,0x1334,0x1335,0x1336,0x1337,
+ 0x1338,0x1339,0x133a,0x133b,0x133c,0x133d,0x133e,0x133f,
+ 0x1340,0x1341,0x1342,0x1343,0x1344,0x1345,0x1346,0x1347,
+ 0x1348,0x1349,0x134a,0x134b,0x134c,0x134d,0x134e,0x134f,
+ 0x1350,0x1351,0x1352,0x1353,0x1354,0x1355,0x1356,0x1357,
+ 0x1358,0x1359,0x135a,0x135b,0x135c,0x135d,0x135e,0x135f,
+ 0x1360,0x1361,0x1362,0x1363,0x1364,0x1365,0x1366,0x1367,
+ 0x1368,0x1369,0x136a,0x136b,0x136c,0x136d,0x136e,0x136f,
+ 0x1370,0x1371,0x1372,0x1373,0x1374,0x1375,0x1376,0x1377,
+ 0x1378,0x1379,0x137a,0x137b,0x137c,0x137d,0x137e,0x137f,
+ 0x1380,0x1381,0x1382,0x1383,0x1384,0x1385,0x1386,0x1387,
+ 0x1388,0x1389,0x138a,0x138b,0x138c,0x138d,0x138e,0x138f,
+ 0x1390,0x1391,0x1392,0x1393,0x1394,0x1395,0x1396,0x1397,
+ 0x1398,0x1399,0x139a,0x139b,0x139c,0x139d,0x139e,0x139f,
+ 0x13a0,0x13a1,0x13a2,0x13a3,0x13a4,0x13a5,0x13a6,0x13a7,
+ 0x13a8,0x13a9,0x13aa,0x13ab,0x13ac,0x13ad,0x13ae,0x13af,
+ 0x13b0,0x13b1,0x13b2,0x13b3,0x13b4,0x13b5,0x13b6,0x13b7,
+ 0x13b8,0x13b9,0x13ba,0x13bb,0x13bc,0x13bd,0x13be,0x13bf,
+ 0x13c0,0x13c1,0x13c2,0x13c3,0x13c4,0x13c5,0x13c6,0x13c7,
+ 0x13c8,0x13c9,0x13ca,0x13cb,0x13cc,0x13cd,0x13ce,0x13cf,
+ 0x13d0,0x13d1,0x13d2,0x13d3,0x13d4,0x13d5,0x13d6,0x13d7,
+ 0x13d8,0x13d9,0x13da,0x13db,0x13dc,0x13dd,0x13de,0x13df,
+ 0x13e0,0x13e1,0x13e2,0x13e3,0x13e4,0x13e5,0x13e6,0x13e7,
+ 0x13e8,0x13e9,0x13ea,0x13eb,0x13ec,0x13ed,0x13ee,0x13ef,
+ 0x13f0,0x13f1,0x13f2,0x13f3,0x13f4,0x13f5,0x13f6,0x13f7,
+ 0x13f8,0x13f9,0x13fa,0x13fb,0x13fc,0x13fd,0x13fe,0x13ff,
+ 0x1400,0x1401,0x1402,0x1403,0x1404,0x1405,0x1406,0x1407,
+ 0x1408,0x1409,0x140a,0x140b,0x140c,0x140d,0x140e,0x140f,
+ 0x1410,0x1411,0x1412,0x1413,0x1414,0x1415,0x1416,0x1417,
+ 0x1418,0x1419,0x141a,0x141b,0x141c,0x141d,0x141e,0x141f,
+ 0x1420,0x1421,0x1422,0x1423,0x1424,0x1425,0x1426,0x1427,
+ 0x1428,0x1429,0x142a,0x142b,0x142c,0x142d,0x142e,0x142f,
+ 0x1430,0x1431,0x1432,0x1433,0x1434,0x1435,0x1436,0x1437,
+ 0x1438,0x1439,0x143a,0x143b,0x143c,0x143d,0x143e,0x143f,
+ 0x1440,0x1441,0x1442,0x1443,0x1444,0x1445,0x1446,0x1447,
+ 0x1448,0x1449,0x144a,0x144b,0x144c,0x144d,0x144e,0x144f,
+ 0x1450,0x1451,0x1452,0x1453,0x1454,0x1455,0x1456,0x1457,
+ 0x1458,0x1459,0x145a,0x145b,0x145c,0x145d,0x145e,0x145f,
+ 0x1460,0x1461,0x1462,0x1463,0x1464,0x1465,0x1466,0x1467,
+ 0x1468,0x1469,0x146a,0x146b,0x146c,0x146d,0x146e,0x146f,
+ 0x1470,0x1471,0x1472,0x1473,0x1474,0x1475,0x1476,0x1477,
+ 0x1478,0x1479,0x147a,0x147b,0x147c,0x147d,0x147e,0x147f,
+ 0x1480,0x1481,0x1482,0x1483,0x1484,0x1485,0x1486,0x1487,
+ 0x1488,0x1489,0x148a,0x148b,0x148c,0x148d,0x148e,0x148f,
+ 0x1490,0x1491,0x1492,0x1493,0x1494,0x1495,0x1496,0x1497,
+ 0x1498,0x1499,0x149a,0x149b,0x149c,0x149d,0x149e,0x149f,
+ 0x14a0,0x14a1,0x14a2,0x14a3,0x14a4,0x14a5,0x14a6,0x14a7,
+ 0x14a8,0x14a9,0x14aa,0x14ab,0x14ac,0x14ad,0x14ae,0x14af,
+ 0x14b0,0x14b1,0x14b2,0x14b3,0x14b4,0x14b5,0x14b6,0x14b7,
+ 0x14b8,0x14b9,0x14ba,0x14bb,0x14bc,0x14bd,0x14be,0x14bf,
+ 0x14c0,0x14c1,0x14c2,0x14c3,0x14c4,0x14c5,0x14c6,0x14c7,
+ 0x14c8,0x14c9,0x14ca,0x14cb,0x14cc,0x14cd,0x14ce,0x14cf,
+ 0x14d0,0x14d1,0x14d2,0x14d3,0x14d4,0x14d5,0x14d6,0x14d7,
+ 0x14d8,0x14d9,0x14da,0x14db,0x14dc,0x14dd,0x14de,0x14df,
+ 0x14e0,0x14e1,0x14e2,0x14e3,0x14e4,0x14e5,0x14e6,0x14e7,
+ 0x14e8,0x14e9,0x14ea,0x14eb,0x14ec,0x14ed,0x14ee,0x14ef,
+ 0x14f0,0x14f1,0x14f2,0x14f3,0x14f4,0x14f5,0x14f6,0x14f7,
+ 0x14f8,0x14f9,0x14fa,0x14fb,0x14fc,0x14fd,0x14fe,0x14ff,
+ 0x1500,0x1501,0x1502,0x1503,0x1504,0x1505,0x1506,0x1507,
+ 0x1508,0x1509,0x150a,0x150b,0x150c,0x150d,0x150e,0x150f,
+ 0x1510,0x1511,0x1512,0x1513,0x1514,0x1515,0x1516,0x1517,
+ 0x1518,0x1519,0x151a,0x151b,0x151c,0x151d,0x151e,0x151f,
+ 0x1520,0x1521,0x1522,0x1523,0x1524,0x1525,0x1526,0x1527,
+ 0x1528,0x1529,0x152a,0x152b,0x152c,0x152d,0x152e,0x152f,
+ 0x1530,0x1531,0x1532,0x1533,0x1534,0x1535,0x1536,0x1537,
+ 0x1538,0x1539,0x153a,0x153b,0x153c,0x153d,0x153e,0x153f,
+ 0x1540,0x1541,0x1542,0x1543,0x1544,0x1545,0x1546,0x1547,
+ 0x1548,0x1549,0x154a,0x154b,0x154c,0x154d,0x154e,0x154f,
+ 0x1550,0x1551,0x1552,0x1553,0x1554,0x1555,0x1556,0x1557,
+ 0x1558,0x1559,0x155a,0x155b,0x155c,0x155d,0x155e,0x155f,
+ 0x1560,0x1561,0x1562,0x1563,0x1564,0x1565,0x1566,0x1567,
+ 0x1568,0x1569,0x156a,0x156b,0x156c,0x156d,0x156e,0x156f,
+ 0x1570,0x1571,0x1572,0x1573,0x1574,0x1575,0x1576,0x1577,
+ 0x1578,0x1579,0x157a,0x157b,0x157c,0x157d,0x157e,0x157f,
+ 0x1580,0x1581,0x1582,0x1583,0x1584,0x1585,0x1586,0x1587,
+ 0x1588,0x1589,0x158a,0x158b,0x158c,0x158d,0x158e,0x158f,
+ 0x1590,0x1591,0x1592,0x1593,0x1594,0x1595,0x1596,0x1597,
+ 0x1598,0x1599,0x159a,0x159b,0x159c,0x159d,0x159e,0x159f,
+ 0x15a0,0x15a1,0x15a2,0x15a3,0x15a4,0x15a5,0x15a6,0x15a7,
+ 0x15a8,0x15a9,0x15aa,0x15ab,0x15ac,0x15ad,0x15ae,0x15af,
+ 0x15b0,0x15b1,0x15b2,0x15b3,0x15b4,0x15b5,0x15b6,0x15b7,
+ 0x15b8,0x15b9,0x15ba,0x15bb,0x15bc,0x15bd,0x15be,0x15bf,
+ 0x15c0,0x15c1,0x15c2,0x15c3,0x15c4,0x15c5,0x15c6,0x15c7,
+ 0x15c8,0x15c9,0x15ca,0x15cb,0x15cc,0x15cd,0x15ce,0x15cf,
+ 0x15d0,0x15d1,0x15d2,0x15d3,0x15d4,0x15d5,0x15d6,0x15d7,
+ 0x15d8,0x15d9,0x15da,0x15db,0x15dc,0x15dd,0x15de,0x15df,
+ 0x15e0,0x15e1,0x15e2,0x15e3,0x15e4,0x15e5,0x15e6,0x15e7,
+ 0x15e8,0x15e9,0x15ea,0x15eb,0x15ec,0x15ed,0x15ee,0x15ef,
+ 0x15f0,0x15f1,0x15f2,0x15f3,0x15f4,0x15f5,0x15f6,0x15f7,
+ 0x15f8,0x15f9,0x15fa,0x15fb,0x15fc,0x15fd,0x15fe,0x15ff,
+ 0x1600,0x1601,0x1602,0x1603,0x1604,0x1605,0x1606,0x1607,
+ 0x1608,0x1609,0x160a,0x160b,0x160c,0x160d,0x160e,0x160f,
+ 0x1610,0x1611,0x1612,0x1613,0x1614,0x1615,0x1616,0x1617,
+ 0x1618,0x1619,0x161a,0x161b,0x161c,0x161d,0x161e,0x161f,
+ 0x1620,0x1621,0x1622,0x1623,0x1624,0x1625,0x1626,0x1627,
+ 0x1628,0x1629,0x162a,0x162b,0x162c,0x162d,0x162e,0x162f,
+ 0x1630,0x1631,0x1632,0x1633,0x1634,0x1635,0x1636,0x1637,
+ 0x1638,0x1639,0x163a,0x163b,0x163c,0x163d,0x163e,0x163f,
+ 0x1640,0x1641,0x1642,0x1643,0x1644,0x1645,0x1646,0x1647,
+ 0x1648,0x1649,0x164a,0x164b,0x164c,0x164d,0x164e,0x164f,
+ 0x1650,0x1651,0x1652,0x1653,0x1654,0x1655,0x1656,0x1657,
+ 0x1658,0x1659,0x165a,0x165b,0x165c,0x165d,0x165e,0x165f,
+ 0x1660,0x1661,0x1662,0x1663,0x1664,0x1665,0x1666,0x1667,
+ 0x1668,0x1669,0x166a,0x166b,0x166c,0x166d,0x166e,0x166f,
+ 0x1670,0x1671,0x1672,0x1673,0x1674,0x1675,0x1676,0x1677,
+ 0x1678,0x1679,0x167a,0x167b,0x167c,0x167d,0x167e,0x167f,
+ 0x1680,0x1681,0x1682,0x1683,0x1684,0x1685,0x1686,0x1687,
+ 0x1688,0x1689,0x168a,0x168b,0x168c,0x168d,0x168e,0x168f,
+ 0x1690,0x1691,0x1692,0x1693,0x1694,0x1695,0x1696,0x1697,
+ 0x1698,0x1699,0x169a,0x169b,0x169c,0x169d,0x169e,0x169f,
+ 0x16a0,0x16a1,0x16a2,0x16a3,0x16a4,0x16a5,0x16a6,0x16a7,
+ 0x16a8,0x16a9,0x16aa,0x16ab,0x16ac,0x16ad,0x16ae,0x16af,
+ 0x16b0,0x16b1,0x16b2,0x16b3,0x16b4,0x16b5,0x16b6,0x16b7,
+ 0x16b8,0x16b9,0x16ba,0x16bb,0x16bc,0x16bd,0x16be,0x16bf,
+ 0x16c0,0x16c1,0x16c2,0x16c3,0x16c4,0x16c5,0x16c6,0x16c7,
+ 0x16c8,0x16c9,0x16ca,0x16cb,0x16cc,0x16cd,0x16ce,0x16cf,
+ 0x16d0,0x16d1,0x16d2,0x16d3,0x16d4,0x16d5,0x16d6,0x16d7,
+ 0x16d8,0x16d9,0x16da,0x16db,0x16dc,0x16dd,0x16de,0x16df,
+ 0x16e0,0x16e1,0x16e2,0x16e3,0x16e4,0x16e5,0x16e6,0x16e7,
+ 0x16e8,0x16e9,0x16ea,0x16eb,0x16ec,0x16ed,0x16ee,0x16ef,
+ 0x16f0,0x16f1,0x16f2,0x16f3,0x16f4,0x16f5,0x16f6,0x16f7,
+ 0x16f8,0x16f9,0x16fa,0x16fb,0x16fc,0x16fd,0x16fe,0x16ff,
+ 0x1700,0x1701,0x1702,0x1703,0x1704,0x1705,0x1706,0x1707,
+ 0x1708,0x1709,0x170a,0x170b,0x170c,0x170d,0x170e,0x170f,
+ 0x1710,0x1711,0x1712,0x1713,0x1714,0x1715,0x1716,0x1717,
+ 0x1718,0x1719,0x171a,0x171b,0x171c,0x171d,0x171e,0x171f,
+ 0x1720,0x1721,0x1722,0x1723,0x1724,0x1725,0x1726,0x1727,
+ 0x1728,0x1729,0x172a,0x172b,0x172c,0x172d,0x172e,0x172f,
+ 0x1730,0x1731,0x1732,0x1733,0x1734,0x1735,0x1736,0x1737,
+ 0x1738,0x1739,0x173a,0x173b,0x173c,0x173d,0x173e,0x173f,
+ 0x1740,0x1741,0x1742,0x1743,0x1744,0x1745,0x1746,0x1747,
+ 0x1748,0x1749,0x174a,0x174b,0x174c,0x174d,0x174e,0x174f,
+ 0x1750,0x1751,0x1752,0x1753,0x1754,0x1755,0x1756,0x1757,
+ 0x1758,0x1759,0x175a,0x175b,0x175c,0x175d,0x175e,0x175f,
+ 0x1760,0x1761,0x1762,0x1763,0x1764,0x1765,0x1766,0x1767,
+ 0x1768,0x1769,0x176a,0x176b,0x176c,0x176d,0x176e,0x176f,
+ 0x1770,0x1771,0x1772,0x1773,0x1774,0x1775,0x1776,0x1777,
+ 0x1778,0x1779,0x177a,0x177b,0x177c,0x177d,0x177e,0x177f,
+ 0x1780,0x1781,0x1782,0x1783,0x1784,0x1785,0x1786,0x1787,
+ 0x1788,0x1789,0x178a,0x178b,0x178c,0x178d,0x178e,0x178f,
+ 0x1790,0x1791,0x1792,0x1793,0x1794,0x1795,0x1796,0x1797,
+ 0x1798,0x1799,0x179a,0x179b,0x179c,0x179d,0x179e,0x179f,
+ 0x17a0,0x17a1,0x17a2,0x17a3,0x17a4,0x17a5,0x17a6,0x17a7,
+ 0x17a8,0x17a9,0x17aa,0x17ab,0x17ac,0x17ad,0x17ae,0x17af,
+ 0x17b0,0x17b1,0x17b2,0x17b3,0x17b4,0x17b5,0x17b6,0x17b7,
+ 0x17b8,0x17b9,0x17ba,0x17bb,0x17bc,0x17bd,0x17be,0x17bf,
+ 0x17c0,0x17c1,0x17c2,0x17c3,0x17c4,0x17c5,0x17c6,0x17c7,
+ 0x17c8,0x17c9,0x17ca,0x17cb,0x17cc,0x17cd,0x17ce,0x17cf,
+ 0x17d0,0x17d1,0x17d2,0x17d3,0x17d4,0x17d5,0x17d6,0x17d7,
+ 0x17d8,0x17d9,0x17da,0x17db,0x17dc,0x17dd,0x17de,0x17df,
+ 0x17e0,0x17e1,0x17e2,0x17e3,0x17e4,0x17e5,0x17e6,0x17e7,
+ 0x17e8,0x17e9,0x17ea,0x17eb,0x17ec,0x17ed,0x17ee,0x17ef,
+ 0x17f0,0x17f1,0x17f2,0x17f3,0x17f4,0x17f5,0x17f6,0x17f7,
+ 0x17f8,0x17f9,0x17fa,0x17fb,0x17fc,0x17fd,0x17fe,0x17ff,
+ 0x1800,0x1801,0x1802,0x1803,0x1804,0x1805,0x1806,0x1807,
+ 0x1808,0x1809,0x180a,0x180b,0x180c,0x180d,0x180e,0x180f,
+ 0x1810,0x1811,0x1812,0x1813,0x1814,0x1815,0x1816,0x1817,
+ 0x1818,0x1819,0x181a,0x181b,0x181c,0x181d,0x181e,0x181f,
+ 0x1820,0x1821,0x1822,0x1823,0x1824,0x1825,0x1826,0x1827,
+ 0x1828,0x1829,0x182a,0x182b,0x182c,0x182d,0x182e,0x182f,
+ 0x1830,0x1831,0x1832,0x1833,0x1834,0x1835,0x1836,0x1837,
+ 0x1838,0x1839,0x183a,0x183b,0x183c,0x183d,0x183e,0x183f,
+ 0x1840,0x1841,0x1842,0x1843,0x1844,0x1845,0x1846,0x1847,
+ 0x1848,0x1849,0x184a,0x184b,0x184c,0x184d,0x184e,0x184f,
+ 0x1850,0x1851,0x1852,0x1853,0x1854,0x1855,0x1856,0x1857,
+ 0x1858,0x1859,0x185a,0x185b,0x185c,0x185d,0x185e,0x185f,
+ 0x1860,0x1861,0x1862,0x1863,0x1864,0x1865,0x1866,0x1867,
+ 0x1868,0x1869,0x186a,0x186b,0x186c,0x186d,0x186e,0x186f,
+ 0x1870,0x1871,0x1872,0x1873,0x1874,0x1875,0x1876,0x1877,
+ 0x1878,0x1879,0x187a,0x187b,0x187c,0x187d,0x187e,0x187f,
+ 0x1880,0x1881,0x1882,0x1883,0x1884,0x1885,0x1886,0x1887,
+ 0x1888,0x1889,0x188a,0x188b,0x188c,0x188d,0x188e,0x188f,
+ 0x1890,0x1891,0x1892,0x1893,0x1894,0x1895,0x1896,0x1897,
+ 0x1898,0x1899,0x189a,0x189b,0x189c,0x189d,0x189e,0x189f,
+ 0x18a0,0x18a1,0x18a2,0x18a3,0x18a4,0x18a5,0x18a6,0x18a7,
+ 0x18a8,0x18a9,0x18aa,0x18ab,0x18ac,0x18ad,0x18ae,0x18af,
+ 0x18b0,0x18b1,0x18b2,0x18b3,0x18b4,0x18b5,0x18b6,0x18b7,
+ 0x18b8,0x18b9,0x18ba,0x18bb,0x18bc,0x18bd,0x18be,0x18bf,
+ 0x18c0,0x18c1,0x18c2,0x18c3,0x18c4,0x18c5,0x18c6,0x18c7,
+ 0x18c8,0x18c9,0x18ca,0x18cb,0x18cc,0x18cd,0x18ce,0x18cf,
+ 0x18d0,0x18d1,0x18d2,0x18d3,0x18d4,0x18d5,0x18d6,0x18d7,
+ 0x18d8,0x18d9,0x18da,0x18db,0x18dc,0x18dd,0x18de,0x18df,
+ 0x18e0,0x18e1,0x18e2,0x18e3,0x18e4,0x18e5,0x18e6,0x18e7,
+ 0x18e8,0x18e9,0x18ea,0x18eb,0x18ec,0x18ed,0x18ee,0x18ef,
+ 0x18f0,0x18f1,0x18f2,0x18f3,0x18f4,0x18f5,0x18f6,0x18f7,
+ 0x18f8,0x18f9,0x18fa,0x18fb,0x18fc,0x18fd,0x18fe,0x18ff,
+ 0x1900,0x1901,0x1902,0x1903,0x1904,0x1905,0x1906,0x1907,
+ 0x1908,0x1909,0x190a,0x190b,0x190c,0x190d,0x190e,0x190f,
+ 0x1910,0x1911,0x1912,0x1913,0x1914,0x1915,0x1916,0x1917,
+ 0x1918,0x1919,0x191a,0x191b,0x191c,0x191d,0x191e,0x191f,
+ 0x1920,0x1921,0x1922,0x1923,0x1924,0x1925,0x1926,0x1927,
+ 0x1928,0x1929,0x192a,0x192b,0x192c,0x192d,0x192e,0x192f,
+ 0x1930,0x1931,0x1932,0x1933,0x1934,0x1935,0x1936,0x1937,
+ 0x1938,0x1939,0x193a,0x193b,0x193c,0x193d,0x193e,0x193f,
+ 0x1940,0x1941,0x1942,0x1943,0x1944,0x1945,0x1946,0x1947,
+ 0x1948,0x1949,0x194a,0x194b,0x194c,0x194d,0x194e,0x194f,
+ 0x1950,0x1951,0x1952,0x1953,0x1954,0x1955,0x1956,0x1957,
+ 0x1958,0x1959,0x195a,0x195b,0x195c,0x195d,0x195e,0x195f,
+ 0x1960,0x1961,0x1962,0x1963,0x1964,0x1965,0x1966,0x1967,
+ 0x1968,0x1969,0x196a,0x196b,0x196c,0x196d,0x196e,0x196f,
+ 0x1970,0x1971,0x1972,0x1973,0x1974,0x1975,0x1976,0x1977,
+ 0x1978,0x1979,0x197a,0x197b,0x197c,0x197d,0x197e,0x197f,
+ 0x1980,0x1981,0x1982,0x1983,0x1984,0x1985,0x1986,0x1987,
+ 0x1988,0x1989,0x198a,0x198b,0x198c,0x198d,0x198e,0x198f,
+ 0x1990,0x1991,0x1992,0x1993,0x1994,0x1995,0x1996,0x1997,
+ 0x1998,0x1999,0x199a,0x199b,0x199c,0x199d,0x199e,0x199f,
+ 0x19a0,0x19a1,0x19a2,0x19a3,0x19a4,0x19a5,0x19a6,0x19a7,
+ 0x19a8,0x19a9,0x19aa,0x19ab,0x19ac,0x19ad,0x19ae,0x19af,
+ 0x19b0,0x19b1,0x19b2,0x19b3,0x19b4,0x19b5,0x19b6,0x19b7,
+ 0x19b8,0x19b9,0x19ba,0x19bb,0x19bc,0x19bd,0x19be,0x19bf,
+ 0x19c0,0x19c1,0x19c2,0x19c3,0x19c4,0x19c5,0x19c6,0x19c7,
+ 0x19c8,0x19c9,0x19ca,0x19cb,0x19cc,0x19cd,0x19ce,0x19cf,
+ 0x19d0,0x19d1,0x19d2,0x19d3,0x19d4,0x19d5,0x19d6,0x19d7,
+ 0x19d8,0x19d9,0x19da,0x19db,0x19dc,0x19dd,0x19de,0x19df,
+ 0x19e0,0x19e1,0x19e2,0x19e3,0x19e4,0x19e5,0x19e6,0x19e7,
+ 0x19e8,0x19e9,0x19ea,0x19eb,0x19ec,0x19ed,0x19ee,0x19ef,
+ 0x19f0,0x19f1,0x19f2,0x19f3,0x19f4,0x19f5,0x19f6,0x19f7,
+ 0x19f8,0x19f9,0x19fa,0x19fb,0x19fc,0x19fd,0x19fe,0x19ff,
+ 0x1a00,0x1a01,0x1a02,0x1a03,0x1a04,0x1a05,0x1a06,0x1a07,
+ 0x1a08,0x1a09,0x1a0a,0x1a0b,0x1a0c,0x1a0d,0x1a0e,0x1a0f,
+ 0x1a10,0x1a11,0x1a12,0x1a13,0x1a14,0x1a15,0x1a16,0x1a17,
+ 0x1a18,0x1a19,0x1a1a,0x1a1b,0x1a1c,0x1a1d,0x1a1e,0x1a1f,
+ 0x1a20,0x1a21,0x1a22,0x1a23,0x1a24,0x1a25,0x1a26,0x1a27,
+ 0x1a28,0x1a29,0x1a2a,0x1a2b,0x1a2c,0x1a2d,0x1a2e,0x1a2f,
+ 0x1a30,0x1a31,0x1a32,0x1a33,0x1a34,0x1a35,0x1a36,0x1a37,
+ 0x1a38,0x1a39,0x1a3a,0x1a3b,0x1a3c,0x1a3d,0x1a3e,0x1a3f,
+ 0x1a40,0x1a41,0x1a42,0x1a43,0x1a44,0x1a45,0x1a46,0x1a47,
+ 0x1a48,0x1a49,0x1a4a,0x1a4b,0x1a4c,0x1a4d,0x1a4e,0x1a4f,
+ 0x1a50,0x1a51,0x1a52,0x1a53,0x1a54,0x1a55,0x1a56,0x1a57,
+ 0x1a58,0x1a59,0x1a5a,0x1a5b,0x1a5c,0x1a5d,0x1a5e,0x1a5f,
+ 0x1a60,0x1a61,0x1a62,0x1a63,0x1a64,0x1a65,0x1a66,0x1a67,
+ 0x1a68,0x1a69,0x1a6a,0x1a6b,0x1a6c,0x1a6d,0x1a6e,0x1a6f,
+ 0x1a70,0x1a71,0x1a72,0x1a73,0x1a74,0x1a75,0x1a76,0x1a77,
+ 0x1a78,0x1a79,0x1a7a,0x1a7b,0x1a7c,0x1a7d,0x1a7e,0x1a7f,
+ 0x1a80,0x1a81,0x1a82,0x1a83,0x1a84,0x1a85,0x1a86,0x1a87,
+ 0x1a88,0x1a89,0x1a8a,0x1a8b,0x1a8c,0x1a8d,0x1a8e,0x1a8f,
+ 0x1a90,0x1a91,0x1a92,0x1a93,0x1a94,0x1a95,0x1a96,0x1a97,
+ 0x1a98,0x1a99,0x1a9a,0x1a9b,0x1a9c,0x1a9d,0x1a9e,0x1a9f,
+ 0x1aa0,0x1aa1,0x1aa2,0x1aa3,0x1aa4,0x1aa5,0x1aa6,0x1aa7,
+ 0x1aa8,0x1aa9,0x1aaa,0x1aab,0x1aac,0x1aad,0x1aae,0x1aaf,
+ 0x1ab0,0x1ab1,0x1ab2,0x1ab3,0x1ab4,0x1ab5,0x1ab6,0x1ab7,
+ 0x1ab8,0x1ab9,0x1aba,0x1abb,0x1abc,0x1abd,0x1abe,0x1abf,
+ 0x1ac0,0x1ac1,0x1ac2,0x1ac3,0x1ac4,0x1ac5,0x1ac6,0x1ac7,
+ 0x1ac8,0x1ac9,0x1aca,0x1acb,0x1acc,0x1acd,0x1ace,0x1acf,
+ 0x1ad0,0x1ad1,0x1ad2,0x1ad3,0x1ad4,0x1ad5,0x1ad6,0x1ad7,
+ 0x1ad8,0x1ad9,0x1ada,0x1adb,0x1adc,0x1add,0x1ade,0x1adf,
+ 0x1ae0,0x1ae1,0x1ae2,0x1ae3,0x1ae4,0x1ae5,0x1ae6,0x1ae7,
+ 0x1ae8,0x1ae9,0x1aea,0x1aeb,0x1aec,0x1aed,0x1aee,0x1aef,
+ 0x1af0,0x1af1,0x1af2,0x1af3,0x1af4,0x1af5,0x1af6,0x1af7,
+ 0x1af8,0x1af9,0x1afa,0x1afb,0x1afc,0x1afd,0x1afe,0x1aff,
+ 0x1b00,0x1b01,0x1b02,0x1b03,0x1b04,0x1b05,0x1b06,0x1b07,
+ 0x1b08,0x1b09,0x1b0a,0x1b0b,0x1b0c,0x1b0d,0x1b0e,0x1b0f,
+ 0x1b10,0x1b11,0x1b12,0x1b13,0x1b14,0x1b15,0x1b16,0x1b17,
+ 0x1b18,0x1b19,0x1b1a,0x1b1b,0x1b1c,0x1b1d,0x1b1e,0x1b1f,
+ 0x1b20,0x1b21,0x1b22,0x1b23,0x1b24,0x1b25,0x1b26,0x1b27,
+ 0x1b28,0x1b29,0x1b2a,0x1b2b,0x1b2c,0x1b2d,0x1b2e,0x1b2f,
+ 0x1b30,0x1b31,0x1b32,0x1b33,0x1b34,0x1b35,0x1b36,0x1b37,
+ 0x1b38,0x1b39,0x1b3a,0x1b3b,0x1b3c,0x1b3d,0x1b3e,0x1b3f,
+ 0x1b40,0x1b41,0x1b42,0x1b43,0x1b44,0x1b45,0x1b46,0x1b47,
+ 0x1b48,0x1b49,0x1b4a,0x1b4b,0x1b4c,0x1b4d,0x1b4e,0x1b4f,
+ 0x1b50,0x1b51,0x1b52,0x1b53,0x1b54,0x1b55,0x1b56,0x1b57,
+ 0x1b58,0x1b59,0x1b5a,0x1b5b,0x1b5c,0x1b5d,0x1b5e,0x1b5f,
+ 0x1b60,0x1b61,0x1b62,0x1b63,0x1b64,0x1b65,0x1b66,0x1b67,
+ 0x1b68,0x1b69,0x1b6a,0x1b6b,0x1b6c,0x1b6d,0x1b6e,0x1b6f,
+ 0x1b70,0x1b71,0x1b72,0x1b73,0x1b74,0x1b75,0x1b76,0x1b77,
+ 0x1b78,0x1b79,0x1b7a,0x1b7b,0x1b7c,0x1b7d,0x1b7e,0x1b7f,
+ 0x1b80,0x1b81,0x1b82,0x1b83,0x1b84,0x1b85,0x1b86,0x1b87,
+ 0x1b88,0x1b89,0x1b8a,0x1b8b,0x1b8c,0x1b8d,0x1b8e,0x1b8f,
+ 0x1b90,0x1b91,0x1b92,0x1b93,0x1b94,0x1b95,0x1b96,0x1b97,
+ 0x1b98,0x1b99,0x1b9a,0x1b9b,0x1b9c,0x1b9d,0x1b9e,0x1b9f,
+ 0x1ba0,0x1ba1,0x1ba2,0x1ba3,0x1ba4,0x1ba5,0x1ba6,0x1ba7,
+ 0x1ba8,0x1ba9,0x1baa,0x1bab,0x1bac,0x1bad,0x1bae,0x1baf,
+ 0x1bb0,0x1bb1,0x1bb2,0x1bb3,0x1bb4,0x1bb5,0x1bb6,0x1bb7,
+ 0x1bb8,0x1bb9,0x1bba,0x1bbb,0x1bbc,0x1bbd,0x1bbe,0x1bbf,
+ 0x1bc0,0x1bc1,0x1bc2,0x1bc3,0x1bc4,0x1bc5,0x1bc6,0x1bc7,
+ 0x1bc8,0x1bc9,0x1bca,0x1bcb,0x1bcc,0x1bcd,0x1bce,0x1bcf,
+ 0x1bd0,0x1bd1,0x1bd2,0x1bd3,0x1bd4,0x1bd5,0x1bd6,0x1bd7,
+ 0x1bd8,0x1bd9,0x1bda,0x1bdb,0x1bdc,0x1bdd,0x1bde,0x1bdf,
+ 0x1be0,0x1be1,0x1be2,0x1be3,0x1be4,0x1be5,0x1be6,0x1be7,
+ 0x1be8,0x1be9,0x1bea,0x1beb,0x1bec,0x1bed,0x1bee,0x1bef,
+ 0x1bf0,0x1bf1,0x1bf2,0x1bf3,0x1bf4,0x1bf5,0x1bf6,0x1bf7,
+ 0x1bf8,0x1bf9,0x1bfa,0x1bfb,0x1bfc,0x1bfd,0x1bfe,0x1bff,
+ 0x1c00,0x1c01,0x1c02,0x1c03,0x1c04,0x1c05,0x1c06,0x1c07,
+ 0x1c08,0x1c09,0x1c0a,0x1c0b,0x1c0c,0x1c0d,0x1c0e,0x1c0f,
+ 0x1c10,0x1c11,0x1c12,0x1c13,0x1c14,0x1c15,0x1c16,0x1c17,
+ 0x1c18,0x1c19,0x1c1a,0x1c1b,0x1c1c,0x1c1d,0x1c1e,0x1c1f,
+ 0x1c20,0x1c21,0x1c22,0x1c23,0x1c24,0x1c25,0x1c26,0x1c27,
+ 0x1c28,0x1c29,0x1c2a,0x1c2b,0x1c2c,0x1c2d,0x1c2e,0x1c2f,
+ 0x1c30,0x1c31,0x1c32,0x1c33,0x1c34,0x1c35,0x1c36,0x1c37,
+ 0x1c38,0x1c39,0x1c3a,0x1c3b,0x1c3c,0x1c3d,0x1c3e,0x1c3f,
+ 0x1c40,0x1c41,0x1c42,0x1c43,0x1c44,0x1c45,0x1c46,0x1c47,
+ 0x1c48,0x1c49,0x1c4a,0x1c4b,0x1c4c,0x1c4d,0x1c4e,0x1c4f,
+ 0x1c50,0x1c51,0x1c52,0x1c53,0x1c54,0x1c55,0x1c56,0x1c57,
+ 0x1c58,0x1c59,0x1c5a,0x1c5b,0x1c5c,0x1c5d,0x1c5e,0x1c5f,
+ 0x1c60,0x1c61,0x1c62,0x1c63,0x1c64,0x1c65,0x1c66,0x1c67,
+ 0x1c68,0x1c69,0x1c6a,0x1c6b,0x1c6c,0x1c6d,0x1c6e,0x1c6f,
+ 0x1c70,0x1c71,0x1c72,0x1c73,0x1c74,0x1c75,0x1c76,0x1c77,
+ 0x1c78,0x1c79,0x1c7a,0x1c7b,0x1c7c,0x1c7d,0x1c7e,0x1c7f,
+ 0x1c80,0x1c81,0x1c82,0x1c83,0x1c84,0x1c85,0x1c86,0x1c87,
+ 0x1c88,0x1c89,0x1c8a,0x1c8b,0x1c8c,0x1c8d,0x1c8e,0x1c8f,
+ 0x1c90,0x1c91,0x1c92,0x1c93,0x1c94,0x1c95,0x1c96,0x1c97,
+ 0x1c98,0x1c99,0x1c9a,0x1c9b,0x1c9c,0x1c9d,0x1c9e,0x1c9f,
+ 0x1ca0,0x1ca1,0x1ca2,0x1ca3,0x1ca4,0x1ca5,0x1ca6,0x1ca7,
+ 0x1ca8,0x1ca9,0x1caa,0x1cab,0x1cac,0x1cad,0x1cae,0x1caf,
+ 0x1cb0,0x1cb1,0x1cb2,0x1cb3,0x1cb4,0x1cb5,0x1cb6,0x1cb7,
+ 0x1cb8,0x1cb9,0x1cba,0x1cbb,0x1cbc,0x1cbd,0x1cbe,0x1cbf,
+ 0x1cc0,0x1cc1,0x1cc2,0x1cc3,0x1cc4,0x1cc5,0x1cc6,0x1cc7,
+ 0x1cc8,0x1cc9,0x1cca,0x1ccb,0x1ccc,0x1ccd,0x1cce,0x1ccf,
+ 0x1cd0,0x1cd1,0x1cd2,0x1cd3,0x1cd4,0x1cd5,0x1cd6,0x1cd7,
+ 0x1cd8,0x1cd9,0x1cda,0x1cdb,0x1cdc,0x1cdd,0x1cde,0x1cdf,
+ 0x1ce0,0x1ce1,0x1ce2,0x1ce3,0x1ce4,0x1ce5,0x1ce6,0x1ce7,
+ 0x1ce8,0x1ce9,0x1cea,0x1ceb,0x1cec,0x1ced,0x1cee,0x1cef,
+ 0x1cf0,0x1cf1,0x1cf2,0x1cf3,0x1cf4,0x1cf5,0x1cf6,0x1cf7,
+ 0x1cf8,0x1cf9,0x1cfa,0x1cfb,0x1cfc,0x1cfd,0x1cfe,0x1cff,
+ 0x1d00,0x1d01,0x1d02,0x1d03,0x1d04,0x1d05,0x1d06,0x1d07,
+ 0x1d08,0x1d09,0x1d0a,0x1d0b,0x1d0c,0x1d0d,0x1d0e,0x1d0f,
+ 0x1d10,0x1d11,0x1d12,0x1d13,0x1d14,0x1d15,0x1d16,0x1d17,
+ 0x1d18,0x1d19,0x1d1a,0x1d1b,0x1d1c,0x1d1d,0x1d1e,0x1d1f,
+ 0x1d20,0x1d21,0x1d22,0x1d23,0x1d24,0x1d25,0x1d26,0x1d27,
+ 0x1d28,0x1d29,0x1d2a,0x1d2b,0x1d2c,0x1d2d,0x1d2e,0x1d2f,
+ 0x1d30,0x1d31,0x1d32,0x1d33,0x1d34,0x1d35,0x1d36,0x1d37,
+ 0x1d38,0x1d39,0x1d3a,0x1d3b,0x1d3c,0x1d3d,0x1d3e,0x1d3f,
+ 0x1d40,0x1d41,0x1d42,0x1d43,0x1d44,0x1d45,0x1d46,0x1d47,
+ 0x1d48,0x1d49,0x1d4a,0x1d4b,0x1d4c,0x1d4d,0x1d4e,0x1d4f,
+ 0x1d50,0x1d51,0x1d52,0x1d53,0x1d54,0x1d55,0x1d56,0x1d57,
+ 0x1d58,0x1d59,0x1d5a,0x1d5b,0x1d5c,0x1d5d,0x1d5e,0x1d5f,
+ 0x1d60,0x1d61,0x1d62,0x1d63,0x1d64,0x1d65,0x1d66,0x1d67,
+ 0x1d68,0x1d69,0x1d6a,0x1d6b,0x1d6c,0x1d6d,0x1d6e,0x1d6f,
+ 0x1d70,0x1d71,0x1d72,0x1d73,0x1d74,0x1d75,0x1d76,0x1d77,
+ 0x1d78,0x1d79,0x1d7a,0x1d7b,0x1d7c,0x1d7d,0x1d7e,0x1d7f,
+ 0x1d80,0x1d81,0x1d82,0x1d83,0x1d84,0x1d85,0x1d86,0x1d87,
+ 0x1d88,0x1d89,0x1d8a,0x1d8b,0x1d8c,0x1d8d,0x1d8e,0x1d8f,
+ 0x1d90,0x1d91,0x1d92,0x1d93,0x1d94,0x1d95,0x1d96,0x1d97,
+ 0x1d98,0x1d99,0x1d9a,0x1d9b,0x1d9c,0x1d9d,0x1d9e,0x1d9f,
+ 0x1da0,0x1da1,0x1da2,0x1da3,0x1da4,0x1da5,0x1da6,0x1da7,
+ 0x1da8,0x1da9,0x1daa,0x1dab,0x1dac,0x1dad,0x1dae,0x1daf,
+ 0x1db0,0x1db1,0x1db2,0x1db3,0x1db4,0x1db5,0x1db6,0x1db7,
+ 0x1db8,0x1db9,0x1dba,0x1dbb,0x1dbc,0x1dbd,0x1dbe,0x1dbf,
+ 0x1dc0,0x1dc1,0x1dc2,0x1dc3,0x1dc4,0x1dc5,0x1dc6,0x1dc7,
+ 0x1dc8,0x1dc9,0x1dca,0x1dcb,0x1dcc,0x1dcd,0x1dce,0x1dcf,
+ 0x1dd0,0x1dd1,0x1dd2,0x1dd3,0x1dd4,0x1dd5,0x1dd6,0x1dd7,
+ 0x1dd8,0x1dd9,0x1dda,0x1ddb,0x1ddc,0x1ddd,0x1dde,0x1ddf,
+ 0x1de0,0x1de1,0x1de2,0x1de3,0x1de4,0x1de5,0x1de6,0x1de7,
+ 0x1de8,0x1de9,0x1dea,0x1deb,0x1dec,0x1ded,0x1dee,0x1def,
+ 0x1df0,0x1df1,0x1df2,0x1df3,0x1df4,0x1df5,0x1df6,0x1df7,
+ 0x1df8,0x1df9,0x1dfa,0x1dfb,0x1dfc,0x1dfd,0x1dfe,0x1dff,
+ 0x1e01,0x1e01,0x1e03,0x1e03,0x1e05,0x1e05,0x1e07,0x1e07,
+ 0x1e09,0x1e09,0x1e0b,0x1e0b,0x1e0d,0x1e0d,0x1e0f,0x1e0f,
+ 0x1e11,0x1e11,0x1e13,0x1e13,0x1e15,0x1e15,0x1e17,0x1e17,
+ 0x1e19,0x1e19,0x1e1b,0x1e1b,0x1e1d,0x1e1d,0x1e1f,0x1e1f,
+ 0x1e21,0x1e21,0x1e23,0x1e23,0x1e25,0x1e25,0x1e27,0x1e27,
+ 0x1e29,0x1e29,0x1e2b,0x1e2b,0x1e2d,0x1e2d,0x1e2f,0x1e2f,
+ 0x1e31,0x1e31,0x1e33,0x1e33,0x1e35,0x1e35,0x1e37,0x1e37,
+ 0x1e39,0x1e39,0x1e3b,0x1e3b,0x1e3d,0x1e3d,0x1e3f,0x1e3f,
+ 0x1e41,0x1e41,0x1e43,0x1e43,0x1e45,0x1e45,0x1e47,0x1e47,
+ 0x1e49,0x1e49,0x1e4b,0x1e4b,0x1e4d,0x1e4d,0x1e4f,0x1e4f,
+ 0x1e51,0x1e51,0x1e53,0x1e53,0x1e55,0x1e55,0x1e57,0x1e57,
+ 0x1e59,0x1e59,0x1e5b,0x1e5b,0x1e5d,0x1e5d,0x1e5f,0x1e5f,
+ 0x1e61,0x1e61,0x1e63,0x1e63,0x1e65,0x1e65,0x1e67,0x1e67,
+ 0x1e69,0x1e69,0x1e6b,0x1e6b,0x1e6d,0x1e6d,0x1e6f,0x1e6f,
+ 0x1e71,0x1e71,0x1e73,0x1e73,0x1e75,0x1e75,0x1e77,0x1e77,
+ 0x1e79,0x1e79,0x1e7b,0x1e7b,0x1e7d,0x1e7d,0x1e7f,0x1e7f,
+ 0x1e81,0x1e81,0x1e83,0x1e83,0x1e85,0x1e85,0x1e87,0x1e87,
+ 0x1e89,0x1e89,0x1e8b,0x1e8b,0x1e8d,0x1e8d,0x1e8f,0x1e8f,
+ 0x1e91,0x1e91,0x1e93,0x1e93,0x1e95,0x1e95,0x1e96,0x1e97,
+ 0x1e98,0x1e99,0x1e9a,0x1e9b,0x1e9c,0x1e9d,0x1e9e,0x1e9f,
+ 0x1ea1,0x1ea1,0x1ea3,0x1ea3,0x1ea5,0x1ea5,0x1ea7,0x1ea7,
+ 0x1ea9,0x1ea9,0x1eab,0x1eab,0x1ead,0x1ead,0x1eaf,0x1eaf,
+ 0x1eb1,0x1eb1,0x1eb3,0x1eb3,0x1eb5,0x1eb5,0x1eb7,0x1eb7,
+ 0x1eb9,0x1eb9,0x1ebb,0x1ebb,0x1ebd,0x1ebd,0x1ebf,0x1ebf,
+ 0x1ec1,0x1ec1,0x1ec3,0x1ec3,0x1ec5,0x1ec5,0x1ec7,0x1ec7,
+ 0x1ec9,0x1ec9,0x1ecb,0x1ecb,0x1ecd,0x1ecd,0x1ecf,0x1ecf,
+ 0x1ed1,0x1ed1,0x1ed3,0x1ed3,0x1ed5,0x1ed5,0x1ed7,0x1ed7,
+ 0x1ed9,0x1ed9,0x1edb,0x1edb,0x1edd,0x1edd,0x1edf,0x1edf,
+ 0x1ee1,0x1ee1,0x1ee3,0x1ee3,0x1ee5,0x1ee5,0x1ee7,0x1ee7,
+ 0x1ee9,0x1ee9,0x1eeb,0x1eeb,0x1eed,0x1eed,0x1eef,0x1eef,
+ 0x1ef1,0x1ef1,0x1ef3,0x1ef3,0x1ef5,0x1ef5,0x1ef7,0x1ef7,
+ 0x1ef9,0x1ef9,0x1efa,0x1efb,0x1efc,0x1efd,0x1efe,0x1eff,
+ 0x1f00,0x1f01,0x1f02,0x1f03,0x1f04,0x1f05,0x1f06,0x1f07,
+ 0x1f00,0x1f01,0x1f02,0x1f03,0x1f04,0x1f05,0x1f06,0x1f07,
+ 0x1f10,0x1f11,0x1f12,0x1f13,0x1f14,0x1f15,0x1f16,0x1f17,
+ 0x1f10,0x1f11,0x1f12,0x1f13,0x1f14,0x1f15,0x1f1e,0x1f1f,
+ 0x1f20,0x1f21,0x1f22,0x1f23,0x1f24,0x1f25,0x1f26,0x1f27,
+ 0x1f20,0x1f21,0x1f22,0x1f23,0x1f24,0x1f25,0x1f26,0x1f27,
+ 0x1f30,0x1f31,0x1f32,0x1f33,0x1f34,0x1f35,0x1f36,0x1f37,
+ 0x1f30,0x1f31,0x1f32,0x1f33,0x1f34,0x1f35,0x1f36,0x1f37,
+ 0x1f40,0x1f41,0x1f42,0x1f43,0x1f44,0x1f45,0x1f46,0x1f47,
+ 0x1f40,0x1f41,0x1f42,0x1f43,0x1f44,0x1f45,0x1f4e,0x1f4f,
+ 0x1f50,0x1f51,0x1f52,0x1f53,0x1f54,0x1f55,0x1f56,0x1f57,
+ 0x1f58,0x1f51,0x1f5a,0x1f53,0x1f5c,0x1f55,0x1f5e,0x1f57,
+ 0x1f60,0x1f61,0x1f62,0x1f63,0x1f64,0x1f65,0x1f66,0x1f67,
+ 0x1f60,0x1f61,0x1f62,0x1f63,0x1f64,0x1f65,0x1f66,0x1f67,
+ 0x1f70,0x1f71,0x1f72,0x1f73,0x1f74,0x1f75,0x1f76,0x1f77,
+ 0x1f78,0x1f79,0x1f7a,0x1f7b,0x1f7c,0x1f7d,0x1f7e,0x1f7f,
+ 0x1f80,0x1f81,0x1f82,0x1f83,0x1f84,0x1f85,0x1f86,0x1f87,
+ 0x1f88,0x1f89,0x1f8a,0x1f8b,0x1f8c,0x1f8d,0x1f8e,0x1f8f,
+ 0x1f90,0x1f91,0x1f92,0x1f93,0x1f94,0x1f95,0x1f96,0x1f97,
+ 0x1f98,0x1f99,0x1f9a,0x1f9b,0x1f9c,0x1f9d,0x1f9e,0x1f9f,
+ 0x1fa0,0x1fa1,0x1fa2,0x1fa3,0x1fa4,0x1fa5,0x1fa6,0x1fa7,
+ 0x1fa8,0x1fa9,0x1faa,0x1fab,0x1fac,0x1fad,0x1fae,0x1faf,
+ 0x1fb0,0x1fb1,0x1fb2,0x1fb3,0x1fb4,0x1fb5,0x1fb6,0x1fb7,
+ 0x1fb0,0x1fb1,0x1f70,0x1f71,0x1fbc,0x1fbd,0x1fbe,0x1fbf,
+ 0x1fc0,0x1fc1,0x1fc2,0x1fc3,0x1fc4,0x1fc5,0x1fc6,0x1fc7,
+ 0x1f72,0x1f73,0x1f74,0x1f75,0x1fcc,0x1fcd,0x1fce,0x1fcf,
+ 0x1fd0,0x1fd1,0x1fd2,0x1fd3,0x1fd4,0x1fd5,0x1fd6,0x1fd7,
+ 0x1fd0,0x1fd1,0x1f76,0x1f77,0x1fdc,0x1fdd,0x1fde,0x1fdf,
+ 0x1fe0,0x1fe1,0x1fe2,0x1fe3,0x1fe4,0x1fe5,0x1fe6,0x1fe7,
+ 0x1fe0,0x1fe1,0x1f7a,0x1f7b,0x1fe5,0x1fed,0x1fee,0x1fef,
+ 0x1ff0,0x1ff1,0x1ff2,0x1ff3,0x1ff4,0x1ff5,0x1ff6,0x1ff7,
+ 0x1f78,0x1f79,0x1f7c,0x1f7d,0x1ffc,0x1ffd,0x1ffe,0x1fff,
+ 0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,
+ 0x2008,0x2009,0x200a,0x200b,0x200c,0x200d,0x200e,0x200f,
+ 0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,
+ 0x2018,0x2019,0x201a,0x201b,0x201c,0x201d,0x201e,0x201f,
+ 0x2020,0x2021,0x2022,0x2023,0x2024,0x2025,0x2026,0x2027,
+ 0x2028,0x2029,0x202a,0x202b,0x202c,0x202d,0x202e,0x202f,
+ 0x2030,0x2031,0x2032,0x2033,0x2034,0x2035,0x2036,0x2037,
+ 0x2038,0x2039,0x203a,0x203b,0x203c,0x203d,0x203e,0x203f,
+ 0x2040,0x2041,0x2042,0x2043,0x2044,0x2045,0x2046,0x2047,
+ 0x2048,0x2049,0x204a,0x204b,0x204c,0x204d,0x204e,0x204f,
+ 0x2050,0x2051,0x2052,0x2053,0x2054,0x2055,0x2056,0x2057,
+ 0x2058,0x2059,0x205a,0x205b,0x205c,0x205d,0x205e,0x205f,
+ 0x2060,0x2061,0x2062,0x2063,0x2064,0x2065,0x2066,0x2067,
+ 0x2068,0x2069,0x206a,0x206b,0x206c,0x206d,0x206e,0x206f,
+ 0x2070,0x2071,0x2072,0x2073,0x2074,0x2075,0x2076,0x2077,
+ 0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,
+ 0x2080,0x2081,0x2082,0x2083,0x2084,0x2085,0x2086,0x2087,
+ 0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x208f,
+ 0x2090,0x2091,0x2092,0x2093,0x2094,0x2095,0x2096,0x2097,
+ 0x2098,0x2099,0x209a,0x209b,0x209c,0x209d,0x209e,0x209f,
+ 0x20a0,0x20a1,0x20a2,0x20a3,0x20a4,0x20a5,0x20a6,0x20a7,
+ 0x20a8,0x20a9,0x20aa,0x20ab,0x20ac,0x20ad,0x20ae,0x20af,
+ 0x20b0,0x20b1,0x20b2,0x20b3,0x20b4,0x20b5,0x20b6,0x20b7,
+ 0x20b8,0x20b9,0x20ba,0x20bb,0x20bc,0x20bd,0x20be,0x20bf,
+ 0x20c0,0x20c1,0x20c2,0x20c3,0x20c4,0x20c5,0x20c6,0x20c7,
+ 0x20c8,0x20c9,0x20ca,0x20cb,0x20cc,0x20cd,0x20ce,0x20cf,
+ 0x20d0,0x20d1,0x20d2,0x20d3,0x20d4,0x20d5,0x20d6,0x20d7,
+ 0x20d8,0x20d9,0x20da,0x20db,0x20dc,0x20dd,0x20de,0x20df,
+ 0x20e0,0x20e1,0x20e2,0x20e3,0x20e4,0x20e5,0x20e6,0x20e7,
+ 0x20e8,0x20e9,0x20ea,0x20eb,0x20ec,0x20ed,0x20ee,0x20ef,
+ 0x20f0,0x20f1,0x20f2,0x20f3,0x20f4,0x20f5,0x20f6,0x20f7,
+ 0x20f8,0x20f9,0x20fa,0x20fb,0x20fc,0x20fd,0x20fe,0x20ff,
+ 0x2100,0x2101,0x2102,0x2103,0x2104,0x2105,0x2106,0x2107,
+ 0x2108,0x2109,0x210a,0x210b,0x210c,0x210d,0x210e,0x210f,
+ 0x2110,0x2111,0x2112,0x2113,0x2114,0x2115,0x2116,0x2117,
+ 0x2118,0x2119,0x211a,0x211b,0x211c,0x211d,0x211e,0x211f,
+ 0x2120,0x2121,0x2122,0x2123,0x2124,0x2125,0x2126,0x2127,
+ 0x2128,0x2129,0x212a,0x212b,0x212c,0x212d,0x212e,0x212f,
+ 0x2130,0x2131,0x2132,0x2133,0x2134,0x2135,0x2136,0x2137,
+ 0x2138,0x2139,0x213a,0x213b,0x213c,0x213d,0x213e,0x213f,
+ 0x2140,0x2141,0x2142,0x2143,0x2144,0x2145,0x2146,0x2147,
+ 0x2148,0x2149,0x214a,0x214b,0x214c,0x214d,0x214e,0x214f,
+ 0x2150,0x2151,0x2152,0x2153,0x2154,0x2155,0x2156,0x2157,
+ 0x2158,0x2159,0x215a,0x215b,0x215c,0x215d,0x215e,0x215f,
+ 0x2170,0x2171,0x2172,0x2173,0x2174,0x2175,0x2176,0x2177,
+ 0x2178,0x2179,0x217a,0x217b,0x217c,0x217d,0x217e,0x217f,
+ 0x2170,0x2171,0x2172,0x2173,0x2174,0x2175,0x2176,0x2177,
+ 0x2178,0x2179,0x217a,0x217b,0x217c,0x217d,0x217e,0x217f,
+ 0x2180,0x2181,0x2182,0x2183,0x2184,0x2185,0x2186,0x2187,
+ 0x2188,0x2189,0x218a,0x218b,0x218c,0x218d,0x218e,0x218f,
+ 0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x2196,0x2197,
+ 0x2198,0x2199,0x219a,0x219b,0x219c,0x219d,0x219e,0x219f,
+ 0x21a0,0x21a1,0x21a2,0x21a3,0x21a4,0x21a5,0x21a6,0x21a7,
+ 0x21a8,0x21a9,0x21aa,0x21ab,0x21ac,0x21ad,0x21ae,0x21af,
+ 0x21b0,0x21b1,0x21b2,0x21b3,0x21b4,0x21b5,0x21b6,0x21b7,
+ 0x21b8,0x21b9,0x21ba,0x21bb,0x21bc,0x21bd,0x21be,0x21bf,
+ 0x21c0,0x21c1,0x21c2,0x21c3,0x21c4,0x21c5,0x21c6,0x21c7,
+ 0x21c8,0x21c9,0x21ca,0x21cb,0x21cc,0x21cd,0x21ce,0x21cf,
+ 0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x21d6,0x21d7,
+ 0x21d8,0x21d9,0x21da,0x21db,0x21dc,0x21dd,0x21de,0x21df,
+ 0x21e0,0x21e1,0x21e2,0x21e3,0x21e4,0x21e5,0x21e6,0x21e7,
+ 0x21e8,0x21e9,0x21ea,0x21eb,0x21ec,0x21ed,0x21ee,0x21ef,
+ 0x21f0,0x21f1,0x21f2,0x21f3,0x21f4,0x21f5,0x21f6,0x21f7,
+ 0x21f8,0x21f9,0x21fa,0x21fb,0x21fc,0x21fd,0x21fe,0x21ff,
+ 0x2200,0x2201,0x2202,0x2203,0x2204,0x2205,0x2206,0x2207,
+ 0x2208,0x2209,0x220a,0x220b,0x220c,0x220d,0x220e,0x220f,
+ 0x2210,0x2211,0x2212,0x2213,0x2214,0x2215,0x2216,0x2217,
+ 0x2218,0x2219,0x221a,0x221b,0x221c,0x221d,0x221e,0x221f,
+ 0x2220,0x2221,0x2222,0x2223,0x2224,0x2225,0x2226,0x2227,
+ 0x2228,0x2229,0x222a,0x222b,0x222c,0x222d,0x222e,0x222f,
+ 0x2230,0x2231,0x2232,0x2233,0x2234,0x2235,0x2236,0x2237,
+ 0x2238,0x2239,0x223a,0x223b,0x223c,0x223d,0x223e,0x223f,
+ 0x2240,0x2241,0x2242,0x2243,0x2244,0x2245,0x2246,0x2247,
+ 0x2248,0x2249,0x224a,0x224b,0x224c,0x224d,0x224e,0x224f,
+ 0x2250,0x2251,0x2252,0x2253,0x2254,0x2255,0x2256,0x2257,
+ 0x2258,0x2259,0x225a,0x225b,0x225c,0x225d,0x225e,0x225f,
+ 0x2260,0x2261,0x2262,0x2263,0x2264,0x2265,0x2266,0x2267,
+ 0x2268,0x2269,0x226a,0x226b,0x226c,0x226d,0x226e,0x226f,
+ 0x2270,0x2271,0x2272,0x2273,0x2274,0x2275,0x2276,0x2277,
+ 0x2278,0x2279,0x227a,0x227b,0x227c,0x227d,0x227e,0x227f,
+ 0x2280,0x2281,0x2282,0x2283,0x2284,0x2285,0x2286,0x2287,
+ 0x2288,0x2289,0x228a,0x228b,0x228c,0x228d,0x228e,0x228f,
+ 0x2290,0x2291,0x2292,0x2293,0x2294,0x2295,0x2296,0x2297,
+ 0x2298,0x2299,0x229a,0x229b,0x229c,0x229d,0x229e,0x229f,
+ 0x22a0,0x22a1,0x22a2,0x22a3,0x22a4,0x22a5,0x22a6,0x22a7,
+ 0x22a8,0x22a9,0x22aa,0x22ab,0x22ac,0x22ad,0x22ae,0x22af,
+ 0x22b0,0x22b1,0x22b2,0x22b3,0x22b4,0x22b5,0x22b6,0x22b7,
+ 0x22b8,0x22b9,0x22ba,0x22bb,0x22bc,0x22bd,0x22be,0x22bf,
+ 0x22c0,0x22c1,0x22c2,0x22c3,0x22c4,0x22c5,0x22c6,0x22c7,
+ 0x22c8,0x22c9,0x22ca,0x22cb,0x22cc,0x22cd,0x22ce,0x22cf,
+ 0x22d0,0x22d1,0x22d2,0x22d3,0x22d4,0x22d5,0x22d6,0x22d7,
+ 0x22d8,0x22d9,0x22da,0x22db,0x22dc,0x22dd,0x22de,0x22df,
+ 0x22e0,0x22e1,0x22e2,0x22e3,0x22e4,0x22e5,0x22e6,0x22e7,
+ 0x22e8,0x22e9,0x22ea,0x22eb,0x22ec,0x22ed,0x22ee,0x22ef,
+ 0x22f0,0x22f1,0x22f2,0x22f3,0x22f4,0x22f5,0x22f6,0x22f7,
+ 0x22f8,0x22f9,0x22fa,0x22fb,0x22fc,0x22fd,0x22fe,0x22ff,
+ 0x2300,0x2301,0x2302,0x2303,0x2304,0x2305,0x2306,0x2307,
+ 0x2308,0x2309,0x230a,0x230b,0x230c,0x230d,0x230e,0x230f,
+ 0x2310,0x2311,0x2312,0x2313,0x2314,0x2315,0x2316,0x2317,
+ 0x2318,0x2319,0x231a,0x231b,0x231c,0x231d,0x231e,0x231f,
+ 0x2320,0x2321,0x2322,0x2323,0x2324,0x2325,0x2326,0x2327,
+ 0x2328,0x2329,0x232a,0x232b,0x232c,0x232d,0x232e,0x232f,
+ 0x2330,0x2331,0x2332,0x2333,0x2334,0x2335,0x2336,0x2337,
+ 0x2338,0x2339,0x233a,0x233b,0x233c,0x233d,0x233e,0x233f,
+ 0x2340,0x2341,0x2342,0x2343,0x2344,0x2345,0x2346,0x2347,
+ 0x2348,0x2349,0x234a,0x234b,0x234c,0x234d,0x234e,0x234f,
+ 0x2350,0x2351,0x2352,0x2353,0x2354,0x2355,0x2356,0x2357,
+ 0x2358,0x2359,0x235a,0x235b,0x235c,0x235d,0x235e,0x235f,
+ 0x2360,0x2361,0x2362,0x2363,0x2364,0x2365,0x2366,0x2367,
+ 0x2368,0x2369,0x236a,0x236b,0x236c,0x236d,0x236e,0x236f,
+ 0x2370,0x2371,0x2372,0x2373,0x2374,0x2375,0x2376,0x2377,
+ 0x2378,0x2379,0x237a,0x237b,0x237c,0x237d,0x237e,0x237f,
+ 0x2380,0x2381,0x2382,0x2383,0x2384,0x2385,0x2386,0x2387,
+ 0x2388,0x2389,0x238a,0x238b,0x238c,0x238d,0x238e,0x238f,
+ 0x2390,0x2391,0x2392,0x2393,0x2394,0x2395,0x2396,0x2397,
+ 0x2398,0x2399,0x239a,0x239b,0x239c,0x239d,0x239e,0x239f,
+ 0x23a0,0x23a1,0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,
+ 0x23a8,0x23a9,0x23aa,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,
+ 0x23b0,0x23b1,0x23b2,0x23b3,0x23b4,0x23b5,0x23b6,0x23b7,
+ 0x23b8,0x23b9,0x23ba,0x23bb,0x23bc,0x23bd,0x23be,0x23bf,
+ 0x23c0,0x23c1,0x23c2,0x23c3,0x23c4,0x23c5,0x23c6,0x23c7,
+ 0x23c8,0x23c9,0x23ca,0x23cb,0x23cc,0x23cd,0x23ce,0x23cf,
+ 0x23d0,0x23d1,0x23d2,0x23d3,0x23d4,0x23d5,0x23d6,0x23d7,
+ 0x23d8,0x23d9,0x23da,0x23db,0x23dc,0x23dd,0x23de,0x23df,
+ 0x23e0,0x23e1,0x23e2,0x23e3,0x23e4,0x23e5,0x23e6,0x23e7,
+ 0x23e8,0x23e9,0x23ea,0x23eb,0x23ec,0x23ed,0x23ee,0x23ef,
+ 0x23f0,0x23f1,0x23f2,0x23f3,0x23f4,0x23f5,0x23f6,0x23f7,
+ 0x23f8,0x23f9,0x23fa,0x23fb,0x23fc,0x23fd,0x23fe,0x23ff,
+ 0x2400,0x2401,0x2402,0x2403,0x2404,0x2405,0x2406,0x2407,
+ 0x2408,0x2409,0x240a,0x240b,0x240c,0x240d,0x240e,0x240f,
+ 0x2410,0x2411,0x2412,0x2413,0x2414,0x2415,0x2416,0x2417,
+ 0x2418,0x2419,0x241a,0x241b,0x241c,0x241d,0x241e,0x241f,
+ 0x2420,0x2421,0x2422,0x2423,0x2424,0x2425,0x2426,0x2427,
+ 0x2428,0x2429,0x242a,0x242b,0x242c,0x242d,0x242e,0x242f,
+ 0x2430,0x2431,0x2432,0x2433,0x2434,0x2435,0x2436,0x2437,
+ 0x2438,0x2439,0x243a,0x243b,0x243c,0x243d,0x243e,0x243f,
+ 0x2440,0x2441,0x2442,0x2443,0x2444,0x2445,0x2446,0x2447,
+ 0x2448,0x2449,0x244a,0x244b,0x244c,0x244d,0x244e,0x244f,
+ 0x2450,0x2451,0x2452,0x2453,0x2454,0x2455,0x2456,0x2457,
+ 0x2458,0x2459,0x245a,0x245b,0x245c,0x245d,0x245e,0x245f,
+ 0x2460,0x2461,0x2462,0x2463,0x2464,0x2465,0x2466,0x2467,
+ 0x2468,0x2469,0x246a,0x246b,0x246c,0x246d,0x246e,0x246f,
+ 0x2470,0x2471,0x2472,0x2473,0x2474,0x2475,0x2476,0x2477,
+ 0x2478,0x2479,0x247a,0x247b,0x247c,0x247d,0x247e,0x247f,
+ 0x2480,0x2481,0x2482,0x2483,0x2484,0x2485,0x2486,0x2487,
+ 0x2488,0x2489,0x248a,0x248b,0x248c,0x248d,0x248e,0x248f,
+ 0x2490,0x2491,0x2492,0x2493,0x2494,0x2495,0x2496,0x2497,
+ 0x2498,0x2499,0x249a,0x249b,0x249c,0x249d,0x249e,0x249f,
+ 0x24a0,0x24a1,0x24a2,0x24a3,0x24a4,0x24a5,0x24a6,0x24a7,
+ 0x24a8,0x24a9,0x24aa,0x24ab,0x24ac,0x24ad,0x24ae,0x24af,
+ 0x24b0,0x24b1,0x24b2,0x24b3,0x24b4,0x24b5,0x24d0,0x24d1,
+ 0x24d2,0x24d3,0x24d4,0x24d5,0x24d6,0x24d7,0x24d8,0x24d9,
+ 0x24da,0x24db,0x24dc,0x24dd,0x24de,0x24df,0x24e0,0x24e1,
+ 0x24e2,0x24e3,0x24e4,0x24e5,0x24e6,0x24e7,0x24e8,0x24e9,
+ 0x24d0,0x24d1,0x24d2,0x24d3,0x24d4,0x24d5,0x24d6,0x24d7,
+ 0x24d8,0x24d9,0x24da,0x24db,0x24dc,0x24dd,0x24de,0x24df,
+ 0x24e0,0x24e1,0x24e2,0x24e3,0x24e4,0x24e5,0x24e6,0x24e7,
+ 0x24e8,0x24e9,0x24ea,0x24eb,0x24ec,0x24ed,0x24ee,0x24ef,
+ 0x24f0,0x24f1,0x24f2,0x24f3,0x24f4,0x24f5,0x24f6,0x24f7,
+ 0x24f8,0x24f9,0x24fa,0x24fb,0x24fc,0x24fd,0x24fe,0x24ff,
+ 0x2500,0x2501,0x2502,0x2503,0x2504,0x2505,0x2506,0x2507,
+ 0x2508,0x2509,0x250a,0x250b,0x250c,0x250d,0x250e,0x250f,
+ 0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,
+ 0x2518,0x2519,0x251a,0x251b,0x251c,0x251d,0x251e,0x251f,
+ 0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,
+ 0x2528,0x2529,0x252a,0x252b,0x252c,0x252d,0x252e,0x252f,
+ 0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,
+ 0x2538,0x2539,0x253a,0x253b,0x253c,0x253d,0x253e,0x253f,
+ 0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,
+ 0x2548,0x2549,0x254a,0x254b,0x254c,0x254d,0x254e,0x254f,
+ 0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,
+ 0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,
+ 0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,
+ 0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,
+ 0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,
+ 0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,
+ 0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,
+ 0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,
+ 0x2590,0x2591,0x2592,0x2593,0x2594,0x2595,0x2596,0x2597,
+ 0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,
+ 0x25a0,0x25a1,0x25a2,0x25a3,0x25a4,0x25a5,0x25a6,0x25a7,
+ 0x25a8,0x25a9,0x25aa,0x25ab,0x25ac,0x25ad,0x25ae,0x25af,
+ 0x25b0,0x25b1,0x25b2,0x25b3,0x25b4,0x25b5,0x25b6,0x25b7,
+ 0x25b8,0x25b9,0x25ba,0x25bb,0x25bc,0x25bd,0x25be,0x25bf,
+ 0x25c0,0x25c1,0x25c2,0x25c3,0x25c4,0x25c5,0x25c6,0x25c7,
+ 0x25c8,0x25c9,0x25ca,0x25cb,0x25cc,0x25cd,0x25ce,0x25cf,
+ 0x25d0,0x25d1,0x25d2,0x25d3,0x25d4,0x25d5,0x25d6,0x25d7,
+ 0x25d8,0x25d9,0x25da,0x25db,0x25dc,0x25dd,0x25de,0x25df,
+ 0x25e0,0x25e1,0x25e2,0x25e3,0x25e4,0x25e5,0x25e6,0x25e7,
+ 0x25e8,0x25e9,0x25ea,0x25eb,0x25ec,0x25ed,0x25ee,0x25ef,
+ 0x25f0,0x25f1,0x25f2,0x25f3,0x25f4,0x25f5,0x25f6,0x25f7,
+ 0x25f8,0x25f9,0x25fa,0x25fb,0x25fc,0x25fd,0x25fe,0x25ff,
+ 0x2600,0x2601,0x2602,0x2603,0x2604,0x2605,0x2606,0x2607,
+ 0x2608,0x2609,0x260a,0x260b,0x260c,0x260d,0x260e,0x260f,
+ 0x2610,0x2611,0x2612,0x2613,0x2614,0x2615,0x2616,0x2617,
+ 0x2618,0x2619,0x261a,0x261b,0x261c,0x261d,0x261e,0x261f,
+ 0x2620,0x2621,0x2622,0x2623,0x2624,0x2625,0x2626,0x2627,
+ 0x2628,0x2629,0x262a,0x262b,0x262c,0x262d,0x262e,0x262f,
+ 0x2630,0x2631,0x2632,0x2633,0x2634,0x2635,0x2636,0x2637,
+ 0x2638,0x2639,0x263a,0x263b,0x263c,0x263d,0x263e,0x263f,
+ 0x2640,0x2641,0x2642,0x2643,0x2644,0x2645,0x2646,0x2647,
+ 0x2648,0x2649,0x264a,0x264b,0x264c,0x264d,0x264e,0x264f,
+ 0x2650,0x2651,0x2652,0x2653,0x2654,0x2655,0x2656,0x2657,
+ 0x2658,0x2659,0x265a,0x265b,0x265c,0x265d,0x265e,0x265f,
+ 0x2660,0x2661,0x2662,0x2663,0x2664,0x2665,0x2666,0x2667,
+ 0x2668,0x2669,0x266a,0x266b,0x266c,0x266d,0x266e,0x266f,
+ 0x2670,0x2671,0x2672,0x2673,0x2674,0x2675,0x2676,0x2677,
+ 0x2678,0x2679,0x267a,0x267b,0x267c,0x267d,0x267e,0x267f,
+ 0x2680,0x2681,0x2682,0x2683,0x2684,0x2685,0x2686,0x2687,
+ 0x2688,0x2689,0x268a,0x268b,0x268c,0x268d,0x268e,0x268f,
+ 0x2690,0x2691,0x2692,0x2693,0x2694,0x2695,0x2696,0x2697,
+ 0x2698,0x2699,0x269a,0x269b,0x269c,0x269d,0x269e,0x269f,
+ 0x26a0,0x26a1,0x26a2,0x26a3,0x26a4,0x26a5,0x26a6,0x26a7,
+ 0x26a8,0x26a9,0x26aa,0x26ab,0x26ac,0x26ad,0x26ae,0x26af,
+ 0x26b0,0x26b1,0x26b2,0x26b3,0x26b4,0x26b5,0x26b6,0x26b7,
+ 0x26b8,0x26b9,0x26ba,0x26bb,0x26bc,0x26bd,0x26be,0x26bf,
+ 0x26c0,0x26c1,0x26c2,0x26c3,0x26c4,0x26c5,0x26c6,0x26c7,
+ 0x26c8,0x26c9,0x26ca,0x26cb,0x26cc,0x26cd,0x26ce,0x26cf,
+ 0x26d0,0x26d1,0x26d2,0x26d3,0x26d4,0x26d5,0x26d6,0x26d7,
+ 0x26d8,0x26d9,0x26da,0x26db,0x26dc,0x26dd,0x26de,0x26df,
+ 0x26e0,0x26e1,0x26e2,0x26e3,0x26e4,0x26e5,0x26e6,0x26e7,
+ 0x26e8,0x26e9,0x26ea,0x26eb,0x26ec,0x26ed,0x26ee,0x26ef,
+ 0x26f0,0x26f1,0x26f2,0x26f3,0x26f4,0x26f5,0x26f6,0x26f7,
+ 0x26f8,0x26f9,0x26fa,0x26fb,0x26fc,0x26fd,0x26fe,0x26ff,
+ 0x2700,0x2701,0x2702,0x2703,0x2704,0x2705,0x2706,0x2707,
+ 0x2708,0x2709,0x270a,0x270b,0x270c,0x270d,0x270e,0x270f,
+ 0x2710,0x2711,0x2712,0x2713,0x2714,0x2715,0x2716,0x2717,
+ 0x2718,0x2719,0x271a,0x271b,0x271c,0x271d,0x271e,0x271f,
+ 0x2720,0x2721,0x2722,0x2723,0x2724,0x2725,0x2726,0x2727,
+ 0x2728,0x2729,0x272a,0x272b,0x272c,0x272d,0x272e,0x272f,
+ 0x2730,0x2731,0x2732,0x2733,0x2734,0x2735,0x2736,0x2737,
+ 0x2738,0x2739,0x273a,0x273b,0x273c,0x273d,0x273e,0x273f,
+ 0x2740,0x2741,0x2742,0x2743,0x2744,0x2745,0x2746,0x2747,
+ 0x2748,0x2749,0x274a,0x274b,0x274c,0x274d,0x274e,0x274f,
+ 0x2750,0x2751,0x2752,0x2753,0x2754,0x2755,0x2756,0x2757,
+ 0x2758,0x2759,0x275a,0x275b,0x275c,0x275d,0x275e,0x275f,
+ 0x2760,0x2761,0x2762,0x2763,0x2764,0x2765,0x2766,0x2767,
+ 0x2768,0x2769,0x276a,0x276b,0x276c,0x276d,0x276e,0x276f,
+ 0x2770,0x2771,0x2772,0x2773,0x2774,0x2775,0x2776,0x2777,
+ 0x2778,0x2779,0x277a,0x277b,0x277c,0x277d,0x277e,0x277f,
+ 0x2780,0x2781,0x2782,0x2783,0x2784,0x2785,0x2786,0x2787,
+ 0x2788,0x2789,0x278a,0x278b,0x278c,0x278d,0x278e,0x278f,
+ 0x2790,0x2791,0x2792,0x2793,0x2794,0x2795,0x2796,0x2797,
+ 0x2798,0x2799,0x279a,0x279b,0x279c,0x279d,0x279e,0x279f,
+ 0x27a0,0x27a1,0x27a2,0x27a3,0x27a4,0x27a5,0x27a6,0x27a7,
+ 0x27a8,0x27a9,0x27aa,0x27ab,0x27ac,0x27ad,0x27ae,0x27af,
+ 0x27b0,0x27b1,0x27b2,0x27b3,0x27b4,0x27b5,0x27b6,0x27b7,
+ 0x27b8,0x27b9,0x27ba,0x27bb,0x27bc,0x27bd,0x27be,0x27bf,
+ 0x27c0,0x27c1,0x27c2,0x27c3,0x27c4,0x27c5,0x27c6,0x27c7,
+ 0x27c8,0x27c9,0x27ca,0x27cb,0x27cc,0x27cd,0x27ce,0x27cf,
+ 0x27d0,0x27d1,0x27d2,0x27d3,0x27d4,0x27d5,0x27d6,0x27d7,
+ 0x27d8,0x27d9,0x27da,0x27db,0x27dc,0x27dd,0x27de,0x27df,
+ 0x27e0,0x27e1,0x27e2,0x27e3,0x27e4,0x27e5,0x27e6,0x27e7,
+ 0x27e8,0x27e9,0x27ea,0x27eb,0x27ec,0x27ed,0x27ee,0x27ef,
+ 0x27f0,0x27f1,0x27f2,0x27f3,0x27f4,0x27f5,0x27f6,0x27f7,
+ 0x27f8,0x27f9,0x27fa,0x27fb,0x27fc,0x27fd,0x27fe,0x27ff,
+ 0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,
+ 0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,
+ 0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,
+ 0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,
+ 0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,
+ 0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,
+ 0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,
+ 0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,
+ 0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,
+ 0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,
+ 0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,
+ 0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,
+ 0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,
+ 0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,
+ 0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,
+ 0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,
+ 0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,
+ 0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,
+ 0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,
+ 0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,
+ 0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,
+ 0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,
+ 0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,
+ 0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,
+ 0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,
+ 0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,
+ 0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,
+ 0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,
+ 0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,
+ 0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,
+ 0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,
+ 0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,
+ 0x2900,0x2901,0x2902,0x2903,0x2904,0x2905,0x2906,0x2907,
+ 0x2908,0x2909,0x290a,0x290b,0x290c,0x290d,0x290e,0x290f,
+ 0x2910,0x2911,0x2912,0x2913,0x2914,0x2915,0x2916,0x2917,
+ 0x2918,0x2919,0x291a,0x291b,0x291c,0x291d,0x291e,0x291f,
+ 0x2920,0x2921,0x2922,0x2923,0x2924,0x2925,0x2926,0x2927,
+ 0x2928,0x2929,0x292a,0x292b,0x292c,0x292d,0x292e,0x292f,
+ 0x2930,0x2931,0x2932,0x2933,0x2934,0x2935,0x2936,0x2937,
+ 0x2938,0x2939,0x293a,0x293b,0x293c,0x293d,0x293e,0x293f,
+ 0x2940,0x2941,0x2942,0x2943,0x2944,0x2945,0x2946,0x2947,
+ 0x2948,0x2949,0x294a,0x294b,0x294c,0x294d,0x294e,0x294f,
+ 0x2950,0x2951,0x2952,0x2953,0x2954,0x2955,0x2956,0x2957,
+ 0x2958,0x2959,0x295a,0x295b,0x295c,0x295d,0x295e,0x295f,
+ 0x2960,0x2961,0x2962,0x2963,0x2964,0x2965,0x2966,0x2967,
+ 0x2968,0x2969,0x296a,0x296b,0x296c,0x296d,0x296e,0x296f,
+ 0x2970,0x2971,0x2972,0x2973,0x2974,0x2975,0x2976,0x2977,
+ 0x2978,0x2979,0x297a,0x297b,0x297c,0x297d,0x297e,0x297f,
+ 0x2980,0x2981,0x2982,0x2983,0x2984,0x2985,0x2986,0x2987,
+ 0x2988,0x2989,0x298a,0x298b,0x298c,0x298d,0x298e,0x298f,
+ 0x2990,0x2991,0x2992,0x2993,0x2994,0x2995,0x2996,0x2997,
+ 0x2998,0x2999,0x299a,0x299b,0x299c,0x299d,0x299e,0x299f,
+ 0x29a0,0x29a1,0x29a2,0x29a3,0x29a4,0x29a5,0x29a6,0x29a7,
+ 0x29a8,0x29a9,0x29aa,0x29ab,0x29ac,0x29ad,0x29ae,0x29af,
+ 0x29b0,0x29b1,0x29b2,0x29b3,0x29b4,0x29b5,0x29b6,0x29b7,
+ 0x29b8,0x29b9,0x29ba,0x29bb,0x29bc,0x29bd,0x29be,0x29bf,
+ 0x29c0,0x29c1,0x29c2,0x29c3,0x29c4,0x29c5,0x29c6,0x29c7,
+ 0x29c8,0x29c9,0x29ca,0x29cb,0x29cc,0x29cd,0x29ce,0x29cf,
+ 0x29d0,0x29d1,0x29d2,0x29d3,0x29d4,0x29d5,0x29d6,0x29d7,
+ 0x29d8,0x29d9,0x29da,0x29db,0x29dc,0x29dd,0x29de,0x29df,
+ 0x29e0,0x29e1,0x29e2,0x29e3,0x29e4,0x29e5,0x29e6,0x29e7,
+ 0x29e8,0x29e9,0x29ea,0x29eb,0x29ec,0x29ed,0x29ee,0x29ef,
+ 0x29f0,0x29f1,0x29f2,0x29f3,0x29f4,0x29f5,0x29f6,0x29f7,
+ 0x29f8,0x29f9,0x29fa,0x29fb,0x29fc,0x29fd,0x29fe,0x29ff,
+ 0x2a00,0x2a01,0x2a02,0x2a03,0x2a04,0x2a05,0x2a06,0x2a07,
+ 0x2a08,0x2a09,0x2a0a,0x2a0b,0x2a0c,0x2a0d,0x2a0e,0x2a0f,
+ 0x2a10,0x2a11,0x2a12,0x2a13,0x2a14,0x2a15,0x2a16,0x2a17,
+ 0x2a18,0x2a19,0x2a1a,0x2a1b,0x2a1c,0x2a1d,0x2a1e,0x2a1f,
+ 0x2a20,0x2a21,0x2a22,0x2a23,0x2a24,0x2a25,0x2a26,0x2a27,
+ 0x2a28,0x2a29,0x2a2a,0x2a2b,0x2a2c,0x2a2d,0x2a2e,0x2a2f,
+ 0x2a30,0x2a31,0x2a32,0x2a33,0x2a34,0x2a35,0x2a36,0x2a37,
+ 0x2a38,0x2a39,0x2a3a,0x2a3b,0x2a3c,0x2a3d,0x2a3e,0x2a3f,
+ 0x2a40,0x2a41,0x2a42,0x2a43,0x2a44,0x2a45,0x2a46,0x2a47,
+ 0x2a48,0x2a49,0x2a4a,0x2a4b,0x2a4c,0x2a4d,0x2a4e,0x2a4f,
+ 0x2a50,0x2a51,0x2a52,0x2a53,0x2a54,0x2a55,0x2a56,0x2a57,
+ 0x2a58,0x2a59,0x2a5a,0x2a5b,0x2a5c,0x2a5d,0x2a5e,0x2a5f,
+ 0x2a60,0x2a61,0x2a62,0x2a63,0x2a64,0x2a65,0x2a66,0x2a67,
+ 0x2a68,0x2a69,0x2a6a,0x2a6b,0x2a6c,0x2a6d,0x2a6e,0x2a6f,
+ 0x2a70,0x2a71,0x2a72,0x2a73,0x2a74,0x2a75,0x2a76,0x2a77,
+ 0x2a78,0x2a79,0x2a7a,0x2a7b,0x2a7c,0x2a7d,0x2a7e,0x2a7f,
+ 0x2a80,0x2a81,0x2a82,0x2a83,0x2a84,0x2a85,0x2a86,0x2a87,
+ 0x2a88,0x2a89,0x2a8a,0x2a8b,0x2a8c,0x2a8d,0x2a8e,0x2a8f,
+ 0x2a90,0x2a91,0x2a92,0x2a93,0x2a94,0x2a95,0x2a96,0x2a97,
+ 0x2a98,0x2a99,0x2a9a,0x2a9b,0x2a9c,0x2a9d,0x2a9e,0x2a9f,
+ 0x2aa0,0x2aa1,0x2aa2,0x2aa3,0x2aa4,0x2aa5,0x2aa6,0x2aa7,
+ 0x2aa8,0x2aa9,0x2aaa,0x2aab,0x2aac,0x2aad,0x2aae,0x2aaf,
+ 0x2ab0,0x2ab1,0x2ab2,0x2ab3,0x2ab4,0x2ab5,0x2ab6,0x2ab7,
+ 0x2ab8,0x2ab9,0x2aba,0x2abb,0x2abc,0x2abd,0x2abe,0x2abf,
+ 0x2ac0,0x2ac1,0x2ac2,0x2ac3,0x2ac4,0x2ac5,0x2ac6,0x2ac7,
+ 0x2ac8,0x2ac9,0x2aca,0x2acb,0x2acc,0x2acd,0x2ace,0x2acf,
+ 0x2ad0,0x2ad1,0x2ad2,0x2ad3,0x2ad4,0x2ad5,0x2ad6,0x2ad7,
+ 0x2ad8,0x2ad9,0x2ada,0x2adb,0x2adc,0x2add,0x2ade,0x2adf,
+ 0x2ae0,0x2ae1,0x2ae2,0x2ae3,0x2ae4,0x2ae5,0x2ae6,0x2ae7,
+ 0x2ae8,0x2ae9,0x2aea,0x2aeb,0x2aec,0x2aed,0x2aee,0x2aef,
+ 0x2af0,0x2af1,0x2af2,0x2af3,0x2af4,0x2af5,0x2af6,0x2af7,
+ 0x2af8,0x2af9,0x2afa,0x2afb,0x2afc,0x2afd,0x2afe,0x2aff,
+ 0x2b00,0x2b01,0x2b02,0x2b03,0x2b04,0x2b05,0x2b06,0x2b07,
+ 0x2b08,0x2b09,0x2b0a,0x2b0b,0x2b0c,0x2b0d,0x2b0e,0x2b0f,
+ 0x2b10,0x2b11,0x2b12,0x2b13,0x2b14,0x2b15,0x2b16,0x2b17,
+ 0x2b18,0x2b19,0x2b1a,0x2b1b,0x2b1c,0x2b1d,0x2b1e,0x2b1f,
+ 0x2b20,0x2b21,0x2b22,0x2b23,0x2b24,0x2b25,0x2b26,0x2b27,
+ 0x2b28,0x2b29,0x2b2a,0x2b2b,0x2b2c,0x2b2d,0x2b2e,0x2b2f,
+ 0x2b30,0x2b31,0x2b32,0x2b33,0x2b34,0x2b35,0x2b36,0x2b37,
+ 0x2b38,0x2b39,0x2b3a,0x2b3b,0x2b3c,0x2b3d,0x2b3e,0x2b3f,
+ 0x2b40,0x2b41,0x2b42,0x2b43,0x2b44,0x2b45,0x2b46,0x2b47,
+ 0x2b48,0x2b49,0x2b4a,0x2b4b,0x2b4c,0x2b4d,0x2b4e,0x2b4f,
+ 0x2b50,0x2b51,0x2b52,0x2b53,0x2b54,0x2b55,0x2b56,0x2b57,
+ 0x2b58,0x2b59,0x2b5a,0x2b5b,0x2b5c,0x2b5d,0x2b5e,0x2b5f,
+ 0x2b60,0x2b61,0x2b62,0x2b63,0x2b64,0x2b65,0x2b66,0x2b67,
+ 0x2b68,0x2b69,0x2b6a,0x2b6b,0x2b6c,0x2b6d,0x2b6e,0x2b6f,
+ 0x2b70,0x2b71,0x2b72,0x2b73,0x2b74,0x2b75,0x2b76,0x2b77,
+ 0x2b78,0x2b79,0x2b7a,0x2b7b,0x2b7c,0x2b7d,0x2b7e,0x2b7f,
+ 0x2b80,0x2b81,0x2b82,0x2b83,0x2b84,0x2b85,0x2b86,0x2b87,
+ 0x2b88,0x2b89,0x2b8a,0x2b8b,0x2b8c,0x2b8d,0x2b8e,0x2b8f,
+ 0x2b90,0x2b91,0x2b92,0x2b93,0x2b94,0x2b95,0x2b96,0x2b97,
+ 0x2b98,0x2b99,0x2b9a,0x2b9b,0x2b9c,0x2b9d,0x2b9e,0x2b9f,
+ 0x2ba0,0x2ba1,0x2ba2,0x2ba3,0x2ba4,0x2ba5,0x2ba6,0x2ba7,
+ 0x2ba8,0x2ba9,0x2baa,0x2bab,0x2bac,0x2bad,0x2bae,0x2baf,
+ 0x2bb0,0x2bb1,0x2bb2,0x2bb3,0x2bb4,0x2bb5,0x2bb6,0x2bb7,
+ 0x2bb8,0x2bb9,0x2bba,0x2bbb,0x2bbc,0x2bbd,0x2bbe,0x2bbf,
+ 0x2bc0,0x2bc1,0x2bc2,0x2bc3,0x2bc4,0x2bc5,0x2bc6,0x2bc7,
+ 0x2bc8,0x2bc9,0x2bca,0x2bcb,0x2bcc,0x2bcd,0x2bce,0x2bcf,
+ 0x2bd0,0x2bd1,0x2bd2,0x2bd3,0x2bd4,0x2bd5,0x2bd6,0x2bd7,
+ 0x2bd8,0x2bd9,0x2bda,0x2bdb,0x2bdc,0x2bdd,0x2bde,0x2bdf,
+ 0x2be0,0x2be1,0x2be2,0x2be3,0x2be4,0x2be5,0x2be6,0x2be7,
+ 0x2be8,0x2be9,0x2bea,0x2beb,0x2bec,0x2bed,0x2bee,0x2bef,
+ 0x2bf0,0x2bf1,0x2bf2,0x2bf3,0x2bf4,0x2bf5,0x2bf6,0x2bf7,
+ 0x2bf8,0x2bf9,0x2bfa,0x2bfb,0x2bfc,0x2bfd,0x2bfe,0x2bff,
+ 0x2c00,0x2c01,0x2c02,0x2c03,0x2c04,0x2c05,0x2c06,0x2c07,
+ 0x2c08,0x2c09,0x2c0a,0x2c0b,0x2c0c,0x2c0d,0x2c0e,0x2c0f,
+ 0x2c10,0x2c11,0x2c12,0x2c13,0x2c14,0x2c15,0x2c16,0x2c17,
+ 0x2c18,0x2c19,0x2c1a,0x2c1b,0x2c1c,0x2c1d,0x2c1e,0x2c1f,
+ 0x2c20,0x2c21,0x2c22,0x2c23,0x2c24,0x2c25,0x2c26,0x2c27,
+ 0x2c28,0x2c29,0x2c2a,0x2c2b,0x2c2c,0x2c2d,0x2c2e,0x2c2f,
+ 0x2c30,0x2c31,0x2c32,0x2c33,0x2c34,0x2c35,0x2c36,0x2c37,
+ 0x2c38,0x2c39,0x2c3a,0x2c3b,0x2c3c,0x2c3d,0x2c3e,0x2c3f,
+ 0x2c40,0x2c41,0x2c42,0x2c43,0x2c44,0x2c45,0x2c46,0x2c47,
+ 0x2c48,0x2c49,0x2c4a,0x2c4b,0x2c4c,0x2c4d,0x2c4e,0x2c4f,
+ 0x2c50,0x2c51,0x2c52,0x2c53,0x2c54,0x2c55,0x2c56,0x2c57,
+ 0x2c58,0x2c59,0x2c5a,0x2c5b,0x2c5c,0x2c5d,0x2c5e,0x2c5f,
+ 0x2c60,0x2c61,0x2c62,0x2c63,0x2c64,0x2c65,0x2c66,0x2c67,
+ 0x2c68,0x2c69,0x2c6a,0x2c6b,0x2c6c,0x2c6d,0x2c6e,0x2c6f,
+ 0x2c70,0x2c71,0x2c72,0x2c73,0x2c74,0x2c75,0x2c76,0x2c77,
+ 0x2c78,0x2c79,0x2c7a,0x2c7b,0x2c7c,0x2c7d,0x2c7e,0x2c7f,
+ 0x2c80,0x2c81,0x2c82,0x2c83,0x2c84,0x2c85,0x2c86,0x2c87,
+ 0x2c88,0x2c89,0x2c8a,0x2c8b,0x2c8c,0x2c8d,0x2c8e,0x2c8f,
+ 0x2c90,0x2c91,0x2c92,0x2c93,0x2c94,0x2c95,0x2c96,0x2c97,
+ 0x2c98,0x2c99,0x2c9a,0x2c9b,0x2c9c,0x2c9d,0x2c9e,0x2c9f,
+ 0x2ca0,0x2ca1,0x2ca2,0x2ca3,0x2ca4,0x2ca5,0x2ca6,0x2ca7,
+ 0x2ca8,0x2ca9,0x2caa,0x2cab,0x2cac,0x2cad,0x2cae,0x2caf,
+ 0x2cb0,0x2cb1,0x2cb2,0x2cb3,0x2cb4,0x2cb5,0x2cb6,0x2cb7,
+ 0x2cb8,0x2cb9,0x2cba,0x2cbb,0x2cbc,0x2cbd,0x2cbe,0x2cbf,
+ 0x2cc0,0x2cc1,0x2cc2,0x2cc3,0x2cc4,0x2cc5,0x2cc6,0x2cc7,
+ 0x2cc8,0x2cc9,0x2cca,0x2ccb,0x2ccc,0x2ccd,0x2cce,0x2ccf,
+ 0x2cd0,0x2cd1,0x2cd2,0x2cd3,0x2cd4,0x2cd5,0x2cd6,0x2cd7,
+ 0x2cd8,0x2cd9,0x2cda,0x2cdb,0x2cdc,0x2cdd,0x2cde,0x2cdf,
+ 0x2ce0,0x2ce1,0x2ce2,0x2ce3,0x2ce4,0x2ce5,0x2ce6,0x2ce7,
+ 0x2ce8,0x2ce9,0x2cea,0x2ceb,0x2cec,0x2ced,0x2cee,0x2cef,
+ 0x2cf0,0x2cf1,0x2cf2,0x2cf3,0x2cf4,0x2cf5,0x2cf6,0x2cf7,
+ 0x2cf8,0x2cf9,0x2cfa,0x2cfb,0x2cfc,0x2cfd,0x2cfe,0x2cff,
+ 0x2d00,0x2d01,0x2d02,0x2d03,0x2d04,0x2d05,0x2d06,0x2d07,
+ 0x2d08,0x2d09,0x2d0a,0x2d0b,0x2d0c,0x2d0d,0x2d0e,0x2d0f,
+ 0x2d10,0x2d11,0x2d12,0x2d13,0x2d14,0x2d15,0x2d16,0x2d17,
+ 0x2d18,0x2d19,0x2d1a,0x2d1b,0x2d1c,0x2d1d,0x2d1e,0x2d1f,
+ 0x2d20,0x2d21,0x2d22,0x2d23,0x2d24,0x2d25,0x2d26,0x2d27,
+ 0x2d28,0x2d29,0x2d2a,0x2d2b,0x2d2c,0x2d2d,0x2d2e,0x2d2f,
+ 0x2d30,0x2d31,0x2d32,0x2d33,0x2d34,0x2d35,0x2d36,0x2d37,
+ 0x2d38,0x2d39,0x2d3a,0x2d3b,0x2d3c,0x2d3d,0x2d3e,0x2d3f,
+ 0x2d40,0x2d41,0x2d42,0x2d43,0x2d44,0x2d45,0x2d46,0x2d47,
+ 0x2d48,0x2d49,0x2d4a,0x2d4b,0x2d4c,0x2d4d,0x2d4e,0x2d4f,
+ 0x2d50,0x2d51,0x2d52,0x2d53,0x2d54,0x2d55,0x2d56,0x2d57,
+ 0x2d58,0x2d59,0x2d5a,0x2d5b,0x2d5c,0x2d5d,0x2d5e,0x2d5f,
+ 0x2d60,0x2d61,0x2d62,0x2d63,0x2d64,0x2d65,0x2d66,0x2d67,
+ 0x2d68,0x2d69,0x2d6a,0x2d6b,0x2d6c,0x2d6d,0x2d6e,0x2d6f,
+ 0x2d70,0x2d71,0x2d72,0x2d73,0x2d74,0x2d75,0x2d76,0x2d77,
+ 0x2d78,0x2d79,0x2d7a,0x2d7b,0x2d7c,0x2d7d,0x2d7e,0x2d7f,
+ 0x2d80,0x2d81,0x2d82,0x2d83,0x2d84,0x2d85,0x2d86,0x2d87,
+ 0x2d88,0x2d89,0x2d8a,0x2d8b,0x2d8c,0x2d8d,0x2d8e,0x2d8f,
+ 0x2d90,0x2d91,0x2d92,0x2d93,0x2d94,0x2d95,0x2d96,0x2d97,
+ 0x2d98,0x2d99,0x2d9a,0x2d9b,0x2d9c,0x2d9d,0x2d9e,0x2d9f,
+ 0x2da0,0x2da1,0x2da2,0x2da3,0x2da4,0x2da5,0x2da6,0x2da7,
+ 0x2da8,0x2da9,0x2daa,0x2dab,0x2dac,0x2dad,0x2dae,0x2daf,
+ 0x2db0,0x2db1,0x2db2,0x2db3,0x2db4,0x2db5,0x2db6,0x2db7,
+ 0x2db8,0x2db9,0x2dba,0x2dbb,0x2dbc,0x2dbd,0x2dbe,0x2dbf,
+ 0x2dc0,0x2dc1,0x2dc2,0x2dc3,0x2dc4,0x2dc5,0x2dc6,0x2dc7,
+ 0x2dc8,0x2dc9,0x2dca,0x2dcb,0x2dcc,0x2dcd,0x2dce,0x2dcf,
+ 0x2dd0,0x2dd1,0x2dd2,0x2dd3,0x2dd4,0x2dd5,0x2dd6,0x2dd7,
+ 0x2dd8,0x2dd9,0x2dda,0x2ddb,0x2ddc,0x2ddd,0x2dde,0x2ddf,
+ 0x2de0,0x2de1,0x2de2,0x2de3,0x2de4,0x2de5,0x2de6,0x2de7,
+ 0x2de8,0x2de9,0x2dea,0x2deb,0x2dec,0x2ded,0x2dee,0x2def,
+ 0x2df0,0x2df1,0x2df2,0x2df3,0x2df4,0x2df5,0x2df6,0x2df7,
+ 0x2df8,0x2df9,0x2dfa,0x2dfb,0x2dfc,0x2dfd,0x2dfe,0x2dff,
+ 0x2e00,0x2e01,0x2e02,0x2e03,0x2e04,0x2e05,0x2e06,0x2e07,
+ 0x2e08,0x2e09,0x2e0a,0x2e0b,0x2e0c,0x2e0d,0x2e0e,0x2e0f,
+ 0x2e10,0x2e11,0x2e12,0x2e13,0x2e14,0x2e15,0x2e16,0x2e17,
+ 0x2e18,0x2e19,0x2e1a,0x2e1b,0x2e1c,0x2e1d,0x2e1e,0x2e1f,
+ 0x2e20,0x2e21,0x2e22,0x2e23,0x2e24,0x2e25,0x2e26,0x2e27,
+ 0x2e28,0x2e29,0x2e2a,0x2e2b,0x2e2c,0x2e2d,0x2e2e,0x2e2f,
+ 0x2e30,0x2e31,0x2e32,0x2e33,0x2e34,0x2e35,0x2e36,0x2e37,
+ 0x2e38,0x2e39,0x2e3a,0x2e3b,0x2e3c,0x2e3d,0x2e3e,0x2e3f,
+ 0x2e40,0x2e41,0x2e42,0x2e43,0x2e44,0x2e45,0x2e46,0x2e47,
+ 0x2e48,0x2e49,0x2e4a,0x2e4b,0x2e4c,0x2e4d,0x2e4e,0x2e4f,
+ 0x2e50,0x2e51,0x2e52,0x2e53,0x2e54,0x2e55,0x2e56,0x2e57,
+ 0x2e58,0x2e59,0x2e5a,0x2e5b,0x2e5c,0x2e5d,0x2e5e,0x2e5f,
+ 0x2e60,0x2e61,0x2e62,0x2e63,0x2e64,0x2e65,0x2e66,0x2e67,
+ 0x2e68,0x2e69,0x2e6a,0x2e6b,0x2e6c,0x2e6d,0x2e6e,0x2e6f,
+ 0x2e70,0x2e71,0x2e72,0x2e73,0x2e74,0x2e75,0x2e76,0x2e77,
+ 0x2e78,0x2e79,0x2e7a,0x2e7b,0x2e7c,0x2e7d,0x2e7e,0x2e7f,
+ 0x2e80,0x2e81,0x2e82,0x2e83,0x2e84,0x2e85,0x2e86,0x2e87,
+ 0x2e88,0x2e89,0x2e8a,0x2e8b,0x2e8c,0x2e8d,0x2e8e,0x2e8f,
+ 0x2e90,0x2e91,0x2e92,0x2e93,0x2e94,0x2e95,0x2e96,0x2e97,
+ 0x2e98,0x2e99,0x2e9a,0x2e9b,0x2e9c,0x2e9d,0x2e9e,0x2e9f,
+ 0x2ea0,0x2ea1,0x2ea2,0x2ea3,0x2ea4,0x2ea5,0x2ea6,0x2ea7,
+ 0x2ea8,0x2ea9,0x2eaa,0x2eab,0x2eac,0x2ead,0x2eae,0x2eaf,
+ 0x2eb0,0x2eb1,0x2eb2,0x2eb3,0x2eb4,0x2eb5,0x2eb6,0x2eb7,
+ 0x2eb8,0x2eb9,0x2eba,0x2ebb,0x2ebc,0x2ebd,0x2ebe,0x2ebf,
+ 0x2ec0,0x2ec1,0x2ec2,0x2ec3,0x2ec4,0x2ec5,0x2ec6,0x2ec7,
+ 0x2ec8,0x2ec9,0x2eca,0x2ecb,0x2ecc,0x2ecd,0x2ece,0x2ecf,
+ 0x2ed0,0x2ed1,0x2ed2,0x2ed3,0x2ed4,0x2ed5,0x2ed6,0x2ed7,
+ 0x2ed8,0x2ed9,0x2eda,0x2edb,0x2edc,0x2edd,0x2ede,0x2edf,
+ 0x2ee0,0x2ee1,0x2ee2,0x2ee3,0x2ee4,0x2ee5,0x2ee6,0x2ee7,
+ 0x2ee8,0x2ee9,0x2eea,0x2eeb,0x2eec,0x2eed,0x2eee,0x2eef,
+ 0x2ef0,0x2ef1,0x2ef2,0x2ef3,0x2ef4,0x2ef5,0x2ef6,0x2ef7,
+ 0x2ef8,0x2ef9,0x2efa,0x2efb,0x2efc,0x2efd,0x2efe,0x2eff,
+ 0x2f00,0x2f01,0x2f02,0x2f03,0x2f04,0x2f05,0x2f06,0x2f07,
+ 0x2f08,0x2f09,0x2f0a,0x2f0b,0x2f0c,0x2f0d,0x2f0e,0x2f0f,
+ 0x2f10,0x2f11,0x2f12,0x2f13,0x2f14,0x2f15,0x2f16,0x2f17,
+ 0x2f18,0x2f19,0x2f1a,0x2f1b,0x2f1c,0x2f1d,0x2f1e,0x2f1f,
+ 0x2f20,0x2f21,0x2f22,0x2f23,0x2f24,0x2f25,0x2f26,0x2f27,
+ 0x2f28,0x2f29,0x2f2a,0x2f2b,0x2f2c,0x2f2d,0x2f2e,0x2f2f,
+ 0x2f30,0x2f31,0x2f32,0x2f33,0x2f34,0x2f35,0x2f36,0x2f37,
+ 0x2f38,0x2f39,0x2f3a,0x2f3b,0x2f3c,0x2f3d,0x2f3e,0x2f3f,
+ 0x2f40,0x2f41,0x2f42,0x2f43,0x2f44,0x2f45,0x2f46,0x2f47,
+ 0x2f48,0x2f49,0x2f4a,0x2f4b,0x2f4c,0x2f4d,0x2f4e,0x2f4f,
+ 0x2f50,0x2f51,0x2f52,0x2f53,0x2f54,0x2f55,0x2f56,0x2f57,
+ 0x2f58,0x2f59,0x2f5a,0x2f5b,0x2f5c,0x2f5d,0x2f5e,0x2f5f,
+ 0x2f60,0x2f61,0x2f62,0x2f63,0x2f64,0x2f65,0x2f66,0x2f67,
+ 0x2f68,0x2f69,0x2f6a,0x2f6b,0x2f6c,0x2f6d,0x2f6e,0x2f6f,
+ 0x2f70,0x2f71,0x2f72,0x2f73,0x2f74,0x2f75,0x2f76,0x2f77,
+ 0x2f78,0x2f79,0x2f7a,0x2f7b,0x2f7c,0x2f7d,0x2f7e,0x2f7f,
+ 0x2f80,0x2f81,0x2f82,0x2f83,0x2f84,0x2f85,0x2f86,0x2f87,
+ 0x2f88,0x2f89,0x2f8a,0x2f8b,0x2f8c,0x2f8d,0x2f8e,0x2f8f,
+ 0x2f90,0x2f91,0x2f92,0x2f93,0x2f94,0x2f95,0x2f96,0x2f97,
+ 0x2f98,0x2f99,0x2f9a,0x2f9b,0x2f9c,0x2f9d,0x2f9e,0x2f9f,
+ 0x2fa0,0x2fa1,0x2fa2,0x2fa3,0x2fa4,0x2fa5,0x2fa6,0x2fa7,
+ 0x2fa8,0x2fa9,0x2faa,0x2fab,0x2fac,0x2fad,0x2fae,0x2faf,
+ 0x2fb0,0x2fb1,0x2fb2,0x2fb3,0x2fb4,0x2fb5,0x2fb6,0x2fb7,
+ 0x2fb8,0x2fb9,0x2fba,0x2fbb,0x2fbc,0x2fbd,0x2fbe,0x2fbf,
+ 0x2fc0,0x2fc1,0x2fc2,0x2fc3,0x2fc4,0x2fc5,0x2fc6,0x2fc7,
+ 0x2fc8,0x2fc9,0x2fca,0x2fcb,0x2fcc,0x2fcd,0x2fce,0x2fcf,
+ 0x2fd0,0x2fd1,0x2fd2,0x2fd3,0x2fd4,0x2fd5,0x2fd6,0x2fd7,
+ 0x2fd8,0x2fd9,0x2fda,0x2fdb,0x2fdc,0x2fdd,0x2fde,0x2fdf,
+ 0x2fe0,0x2fe1,0x2fe2,0x2fe3,0x2fe4,0x2fe5,0x2fe6,0x2fe7,
+ 0x2fe8,0x2fe9,0x2fea,0x2feb,0x2fec,0x2fed,0x2fee,0x2fef,
+ 0x2ff0,0x2ff1,0x2ff2,0x2ff3,0x2ff4,0x2ff5,0x2ff6,0x2ff7,
+ 0x2ff8,0x2ff9,0x2ffa,0x2ffb,0x2ffc,0x2ffd,0x2ffe,0x2fff,
+ 0x3000,0x3001,0x3002,0x3003,0x3004,0x3005,0x3006,0x3007,
+ 0x3008,0x3009,0x300a,0x300b,0x300c,0x300d,0x300e,0x300f,
+ 0x3010,0x3011,0x3012,0x3013,0x3014,0x3015,0x3016,0x3017,
+ 0x3018,0x3019,0x301a,0x301b,0x301c,0x301d,0x301e,0x301f,
+ 0x3020,0x3021,0x3022,0x3023,0x3024,0x3025,0x3026,0x3027,
+ 0x3028,0x3029,0x302a,0x302b,0x302c,0x302d,0x302e,0x302f,
+ 0x3030,0x3031,0x3032,0x3033,0x3034,0x3035,0x3036,0x3037,
+ 0x3038,0x3039,0x303a,0x303b,0x303c,0x303d,0x303e,0x303f,
+ 0x3040,0x3041,0x3042,0x3043,0x3044,0x3045,0x3046,0x3047,
+ 0x3048,0x3049,0x304a,0x304b,0x304c,0x304d,0x304e,0x304f,
+ 0x3050,0x3051,0x3052,0x3053,0x3054,0x3055,0x3056,0x3057,
+ 0x3058,0x3059,0x305a,0x305b,0x305c,0x305d,0x305e,0x305f,
+ 0x3060,0x3061,0x3062,0x3063,0x3064,0x3065,0x3066,0x3067,
+ 0x3068,0x3069,0x306a,0x306b,0x306c,0x306d,0x306e,0x306f,
+ 0x3070,0x3071,0x3072,0x3073,0x3074,0x3075,0x3076,0x3077,
+ 0x3078,0x3079,0x307a,0x307b,0x307c,0x307d,0x307e,0x307f,
+ 0x3080,0x3081,0x3082,0x3083,0x3084,0x3085,0x3086,0x3087,
+ 0x3088,0x3089,0x308a,0x308b,0x308c,0x308d,0x308e,0x308f,
+ 0x3090,0x3091,0x3092,0x3093,0x3094,0x3095,0x3096,0x3097,
+ 0x3098,0x3099,0x309a,0x309b,0x309c,0x309d,0x309e,0x309f,
+ 0x30a0,0x30a1,0x30a2,0x30a3,0x30a4,0x30a5,0x30a6,0x30a7,
+ 0x30a8,0x30a9,0x30aa,0x30ab,0x30ac,0x30ad,0x30ae,0x30af,
+ 0x30b0,0x30b1,0x30b2,0x30b3,0x30b4,0x30b5,0x30b6,0x30b7,
+ 0x30b8,0x30b9,0x30ba,0x30bb,0x30bc,0x30bd,0x30be,0x30bf,
+ 0x30c0,0x30c1,0x30c2,0x30c3,0x30c4,0x30c5,0x30c6,0x30c7,
+ 0x30c8,0x30c9,0x30ca,0x30cb,0x30cc,0x30cd,0x30ce,0x30cf,
+ 0x30d0,0x30d1,0x30d2,0x30d3,0x30d4,0x30d5,0x30d6,0x30d7,
+ 0x30d8,0x30d9,0x30da,0x30db,0x30dc,0x30dd,0x30de,0x30df,
+ 0x30e0,0x30e1,0x30e2,0x30e3,0x30e4,0x30e5,0x30e6,0x30e7,
+ 0x30e8,0x30e9,0x30ea,0x30eb,0x30ec,0x30ed,0x30ee,0x30ef,
+ 0x30f0,0x30f1,0x30f2,0x30f3,0x30f4,0x30f5,0x30f6,0x30f7,
+ 0x30f8,0x30f9,0x30fa,0x30fb,0x30fc,0x30fd,0x30fe,0x30ff,
+ 0x3100,0x3101,0x3102,0x3103,0x3104,0x3105,0x3106,0x3107,
+ 0x3108,0x3109,0x310a,0x310b,0x310c,0x310d,0x310e,0x310f,
+ 0x3110,0x3111,0x3112,0x3113,0x3114,0x3115,0x3116,0x3117,
+ 0x3118,0x3119,0x311a,0x311b,0x311c,0x311d,0x311e,0x311f,
+ 0x3120,0x3121,0x3122,0x3123,0x3124,0x3125,0x3126,0x3127,
+ 0x3128,0x3129,0x312a,0x312b,0x312c,0x312d,0x312e,0x312f,
+ 0x3130,0x3131,0x3132,0x3133,0x3134,0x3135,0x3136,0x3137,
+ 0x3138,0x3139,0x313a,0x313b,0x313c,0x313d,0x313e,0x313f,
+ 0x3140,0x3141,0x3142,0x3143,0x3144,0x3145,0x3146,0x3147,
+ 0x3148,0x3149,0x314a,0x314b,0x314c,0x314d,0x314e,0x314f,
+ 0x3150,0x3151,0x3152,0x3153,0x3154,0x3155,0x3156,0x3157,
+ 0x3158,0x3159,0x315a,0x315b,0x315c,0x315d,0x315e,0x315f,
+ 0x3160,0x3161,0x3162,0x3163,0x3164,0x3165,0x3166,0x3167,
+ 0x3168,0x3169,0x316a,0x316b,0x316c,0x316d,0x316e,0x316f,
+ 0x3170,0x3171,0x3172,0x3173,0x3174,0x3175,0x3176,0x3177,
+ 0x3178,0x3179,0x317a,0x317b,0x317c,0x317d,0x317e,0x317f,
+ 0x3180,0x3181,0x3182,0x3183,0x3184,0x3185,0x3186,0x3187,
+ 0x3188,0x3189,0x318a,0x318b,0x318c,0x318d,0x318e,0x318f,
+ 0x3190,0x3191,0x3192,0x3193,0x3194,0x3195,0x3196,0x3197,
+ 0x3198,0x3199,0x319a,0x319b,0x319c,0x319d,0x319e,0x319f,
+ 0x31a0,0x31a1,0x31a2,0x31a3,0x31a4,0x31a5,0x31a6,0x31a7,
+ 0x31a8,0x31a9,0x31aa,0x31ab,0x31ac,0x31ad,0x31ae,0x31af,
+ 0x31b0,0x31b1,0x31b2,0x31b3,0x31b4,0x31b5,0x31b6,0x31b7,
+ 0x31b8,0x31b9,0x31ba,0x31bb,0x31bc,0x31bd,0x31be,0x31bf,
+ 0x31c0,0x31c1,0x31c2,0x31c3,0x31c4,0x31c5,0x31c6,0x31c7,
+ 0x31c8,0x31c9,0x31ca,0x31cb,0x31cc,0x31cd,0x31ce,0x31cf,
+ 0x31d0,0x31d1,0x31d2,0x31d3,0x31d4,0x31d5,0x31d6,0x31d7,
+ 0x31d8,0x31d9,0x31da,0x31db,0x31dc,0x31dd,0x31de,0x31df,
+ 0x31e0,0x31e1,0x31e2,0x31e3,0x31e4,0x31e5,0x31e6,0x31e7,
+ 0x31e8,0x31e9,0x31ea,0x31eb,0x31ec,0x31ed,0x31ee,0x31ef,
+ 0x31f0,0x31f1,0x31f2,0x31f3,0x31f4,0x31f5,0x31f6,0x31f7,
+ 0x31f8,0x31f9,0x31fa,0x31fb,0x31fc,0x31fd,0x31fe,0x31ff,
+ 0x3200,0x3201,0x3202,0x3203,0x3204,0x3205,0x3206,0x3207,
+ 0x3208,0x3209,0x320a,0x320b,0x320c,0x320d,0x320e,0x320f,
+ 0x3210,0x3211,0x3212,0x3213,0x3214,0x3215,0x3216,0x3217,
+ 0x3218,0x3219,0x321a,0x321b,0x321c,0x321d,0x321e,0x321f,
+ 0x3220,0x3221,0x3222,0x3223,0x3224,0x3225,0x3226,0x3227,
+ 0x3228,0x3229,0x322a,0x322b,0x322c,0x322d,0x322e,0x322f,
+ 0x3230,0x3231,0x3232,0x3233,0x3234,0x3235,0x3236,0x3237,
+ 0x3238,0x3239,0x323a,0x323b,0x323c,0x323d,0x323e,0x323f,
+ 0x3240,0x3241,0x3242,0x3243,0x3244,0x3245,0x3246,0x3247,
+ 0x3248,0x3249,0x324a,0x324b,0x324c,0x324d,0x324e,0x324f,
+ 0x3250,0x3251,0x3252,0x3253,0x3254,0x3255,0x3256,0x3257,
+ 0x3258,0x3259,0x325a,0x325b,0x325c,0x325d,0x325e,0x325f,
+ 0x3260,0x3261,0x3262,0x3263,0x3264,0x3265,0x3266,0x3267,
+ 0x3268,0x3269,0x326a,0x326b,0x326c,0x326d,0x326e,0x326f,
+ 0x3270,0x3271,0x3272,0x3273,0x3274,0x3275,0x3276,0x3277,
+ 0x3278,0x3279,0x327a,0x327b,0x327c,0x327d,0x327e,0x327f,
+ 0x3280,0x3281,0x3282,0x3283,0x3284,0x3285,0x3286,0x3287,
+ 0x3288,0x3289,0x328a,0x328b,0x328c,0x328d,0x328e,0x328f,
+ 0x3290,0x3291,0x3292,0x3293,0x3294,0x3295,0x3296,0x3297,
+ 0x3298,0x3299,0x329a,0x329b,0x329c,0x329d,0x329e,0x329f,
+ 0x32a0,0x32a1,0x32a2,0x32a3,0x32a4,0x32a5,0x32a6,0x32a7,
+ 0x32a8,0x32a9,0x32aa,0x32ab,0x32ac,0x32ad,0x32ae,0x32af,
+ 0x32b0,0x32b1,0x32b2,0x32b3,0x32b4,0x32b5,0x32b6,0x32b7,
+ 0x32b8,0x32b9,0x32ba,0x32bb,0x32bc,0x32bd,0x32be,0x32bf,
+ 0x32c0,0x32c1,0x32c2,0x32c3,0x32c4,0x32c5,0x32c6,0x32c7,
+ 0x32c8,0x32c9,0x32ca,0x32cb,0x32cc,0x32cd,0x32ce,0x32cf,
+ 0x32d0,0x32d1,0x32d2,0x32d3,0x32d4,0x32d5,0x32d6,0x32d7,
+ 0x32d8,0x32d9,0x32da,0x32db,0x32dc,0x32dd,0x32de,0x32df,
+ 0x32e0,0x32e1,0x32e2,0x32e3,0x32e4,0x32e5,0x32e6,0x32e7,
+ 0x32e8,0x32e9,0x32ea,0x32eb,0x32ec,0x32ed,0x32ee,0x32ef,
+ 0x32f0,0x32f1,0x32f2,0x32f3,0x32f4,0x32f5,0x32f6,0x32f7,
+ 0x32f8,0x32f9,0x32fa,0x32fb,0x32fc,0x32fd,0x32fe,0x32ff,
+ 0x3300,0x3301,0x3302,0x3303,0x3304,0x3305,0x3306,0x3307,
+ 0x3308,0x3309,0x330a,0x330b,0x330c,0x330d,0x330e,0x330f,
+ 0x3310,0x3311,0x3312,0x3313,0x3314,0x3315,0x3316,0x3317,
+ 0x3318,0x3319,0x331a,0x331b,0x331c,0x331d,0x331e,0x331f,
+ 0x3320,0x3321,0x3322,0x3323,0x3324,0x3325,0x3326,0x3327,
+ 0x3328,0x3329,0x332a,0x332b,0x332c,0x332d,0x332e,0x332f,
+ 0x3330,0x3331,0x3332,0x3333,0x3334,0x3335,0x3336,0x3337,
+ 0x3338,0x3339,0x333a,0x333b,0x333c,0x333d,0x333e,0x333f,
+ 0x3340,0x3341,0x3342,0x3343,0x3344,0x3345,0x3346,0x3347,
+ 0x3348,0x3349,0x334a,0x334b,0x334c,0x334d,0x334e,0x334f,
+ 0x3350,0x3351,0x3352,0x3353,0x3354,0x3355,0x3356,0x3357,
+ 0x3358,0x3359,0x335a,0x335b,0x335c,0x335d,0x335e,0x335f,
+ 0x3360,0x3361,0x3362,0x3363,0x3364,0x3365,0x3366,0x3367,
+ 0x3368,0x3369,0x336a,0x336b,0x336c,0x336d,0x336e,0x336f,
+ 0x3370,0x3371,0x3372,0x3373,0x3374,0x3375,0x3376,0x3377,
+ 0x3378,0x3379,0x337a,0x337b,0x337c,0x337d,0x337e,0x337f,
+ 0x3380,0x3381,0x3382,0x3383,0x3384,0x3385,0x3386,0x3387,
+ 0x3388,0x3389,0x338a,0x338b,0x338c,0x338d,0x338e,0x338f,
+ 0x3390,0x3391,0x3392,0x3393,0x3394,0x3395,0x3396,0x3397,
+ 0x3398,0x3399,0x339a,0x339b,0x339c,0x339d,0x339e,0x339f,
+ 0x33a0,0x33a1,0x33a2,0x33a3,0x33a4,0x33a5,0x33a6,0x33a7,
+ 0x33a8,0x33a9,0x33aa,0x33ab,0x33ac,0x33ad,0x33ae,0x33af,
+ 0x33b0,0x33b1,0x33b2,0x33b3,0x33b4,0x33b5,0x33b6,0x33b7,
+ 0x33b8,0x33b9,0x33ba,0x33bb,0x33bc,0x33bd,0x33be,0x33bf,
+ 0x33c0,0x33c1,0x33c2,0x33c3,0x33c4,0x33c5,0x33c6,0x33c7,
+ 0x33c8,0x33c9,0x33ca,0x33cb,0x33cc,0x33cd,0x33ce,0x33cf,
+ 0x33d0,0x33d1,0x33d2,0x33d3,0x33d4,0x33d5,0x33d6,0x33d7,
+ 0x33d8,0x33d9,0x33da,0x33db,0x33dc,0x33dd,0x33de,0x33df,
+ 0x33e0,0x33e1,0x33e2,0x33e3,0x33e4,0x33e5,0x33e6,0x33e7,
+ 0x33e8,0x33e9,0x33ea,0x33eb,0x33ec,0x33ed,0x33ee,0x33ef,
+ 0x33f0,0x33f1,0x33f2,0x33f3,0x33f4,0x33f5,0x33f6,0x33f7,
+ 0x33f8,0x33f9,0x33fa,0x33fb,0x33fc,0x33fd,0x33fe,0x33ff,
+ 0x3400,0x3401,0x3402,0x3403,0x3404,0x3405,0x3406,0x3407,
+ 0x3408,0x3409,0x340a,0x340b,0x340c,0x340d,0x340e,0x340f,
+ 0x3410,0x3411,0x3412,0x3413,0x3414,0x3415,0x3416,0x3417,
+ 0x3418,0x3419,0x341a,0x341b,0x341c,0x341d,0x341e,0x341f,
+ 0x3420,0x3421,0x3422,0x3423,0x3424,0x3425,0x3426,0x3427,
+ 0x3428,0x3429,0x342a,0x342b,0x342c,0x342d,0x342e,0x342f,
+ 0x3430,0x3431,0x3432,0x3433,0x3434,0x3435,0x3436,0x3437,
+ 0x3438,0x3439,0x343a,0x343b,0x343c,0x343d,0x343e,0x343f,
+ 0x3440,0x3441,0x3442,0x3443,0x3444,0x3445,0x3446,0x3447,
+ 0x3448,0x3449,0x344a,0x344b,0x344c,0x344d,0x344e,0x344f,
+ 0x3450,0x3451,0x3452,0x3453,0x3454,0x3455,0x3456,0x3457,
+ 0x3458,0x3459,0x345a,0x345b,0x345c,0x345d,0x345e,0x345f,
+ 0x3460,0x3461,0x3462,0x3463,0x3464,0x3465,0x3466,0x3467,
+ 0x3468,0x3469,0x346a,0x346b,0x346c,0x346d,0x346e,0x346f,
+ 0x3470,0x3471,0x3472,0x3473,0x3474,0x3475,0x3476,0x3477,
+ 0x3478,0x3479,0x347a,0x347b,0x347c,0x347d,0x347e,0x347f,
+ 0x3480,0x3481,0x3482,0x3483,0x3484,0x3485,0x3486,0x3487,
+ 0x3488,0x3489,0x348a,0x348b,0x348c,0x348d,0x348e,0x348f,
+ 0x3490,0x3491,0x3492,0x3493,0x3494,0x3495,0x3496,0x3497,
+ 0x3498,0x3499,0x349a,0x349b,0x349c,0x349d,0x349e,0x349f,
+ 0x34a0,0x34a1,0x34a2,0x34a3,0x34a4,0x34a5,0x34a6,0x34a7,
+ 0x34a8,0x34a9,0x34aa,0x34ab,0x34ac,0x34ad,0x34ae,0x34af,
+ 0x34b0,0x34b1,0x34b2,0x34b3,0x34b4,0x34b5,0x34b6,0x34b7,
+ 0x34b8,0x34b9,0x34ba,0x34bb,0x34bc,0x34bd,0x34be,0x34bf,
+ 0x34c0,0x34c1,0x34c2,0x34c3,0x34c4,0x34c5,0x34c6,0x34c7,
+ 0x34c8,0x34c9,0x34ca,0x34cb,0x34cc,0x34cd,0x34ce,0x34cf,
+ 0x34d0,0x34d1,0x34d2,0x34d3,0x34d4,0x34d5,0x34d6,0x34d7,
+ 0x34d8,0x34d9,0x34da,0x34db,0x34dc,0x34dd,0x34de,0x34df,
+ 0x34e0,0x34e1,0x34e2,0x34e3,0x34e4,0x34e5,0x34e6,0x34e7,
+ 0x34e8,0x34e9,0x34ea,0x34eb,0x34ec,0x34ed,0x34ee,0x34ef,
+ 0x34f0,0x34f1,0x34f2,0x34f3,0x34f4,0x34f5,0x34f6,0x34f7,
+ 0x34f8,0x34f9,0x34fa,0x34fb,0x34fc,0x34fd,0x34fe,0x34ff,
+ 0x3500,0x3501,0x3502,0x3503,0x3504,0x3505,0x3506,0x3507,
+ 0x3508,0x3509,0x350a,0x350b,0x350c,0x350d,0x350e,0x350f,
+ 0x3510,0x3511,0x3512,0x3513,0x3514,0x3515,0x3516,0x3517,
+ 0x3518,0x3519,0x351a,0x351b,0x351c,0x351d,0x351e,0x351f,
+ 0x3520,0x3521,0x3522,0x3523,0x3524,0x3525,0x3526,0x3527,
+ 0x3528,0x3529,0x352a,0x352b,0x352c,0x352d,0x352e,0x352f,
+ 0x3530,0x3531,0x3532,0x3533,0x3534,0x3535,0x3536,0x3537,
+ 0x3538,0x3539,0x353a,0x353b,0x353c,0x353d,0x353e,0x353f,
+ 0x3540,0x3541,0x3542,0x3543,0x3544,0x3545,0x3546,0x3547,
+ 0x3548,0x3549,0x354a,0x354b,0x354c,0x354d,0x354e,0x354f,
+ 0x3550,0x3551,0x3552,0x3553,0x3554,0x3555,0x3556,0x3557,
+ 0x3558,0x3559,0x355a,0x355b,0x355c,0x355d,0x355e,0x355f,
+ 0x3560,0x3561,0x3562,0x3563,0x3564,0x3565,0x3566,0x3567,
+ 0x3568,0x3569,0x356a,0x356b,0x356c,0x356d,0x356e,0x356f,
+ 0x3570,0x3571,0x3572,0x3573,0x3574,0x3575,0x3576,0x3577,
+ 0x3578,0x3579,0x357a,0x357b,0x357c,0x357d,0x357e,0x357f,
+ 0x3580,0x3581,0x3582,0x3583,0x3584,0x3585,0x3586,0x3587,
+ 0x3588,0x3589,0x358a,0x358b,0x358c,0x358d,0x358e,0x358f,
+ 0x3590,0x3591,0x3592,0x3593,0x3594,0x3595,0x3596,0x3597,
+ 0x3598,0x3599,0x359a,0x359b,0x359c,0x359d,0x359e,0x359f,
+ 0x35a0,0x35a1,0x35a2,0x35a3,0x35a4,0x35a5,0x35a6,0x35a7,
+ 0x35a8,0x35a9,0x35aa,0x35ab,0x35ac,0x35ad,0x35ae,0x35af,
+ 0x35b0,0x35b1,0x35b2,0x35b3,0x35b4,0x35b5,0x35b6,0x35b7,
+ 0x35b8,0x35b9,0x35ba,0x35bb,0x35bc,0x35bd,0x35be,0x35bf,
+ 0x35c0,0x35c1,0x35c2,0x35c3,0x35c4,0x35c5,0x35c6,0x35c7,
+ 0x35c8,0x35c9,0x35ca,0x35cb,0x35cc,0x35cd,0x35ce,0x35cf,
+ 0x35d0,0x35d1,0x35d2,0x35d3,0x35d4,0x35d5,0x35d6,0x35d7,
+ 0x35d8,0x35d9,0x35da,0x35db,0x35dc,0x35dd,0x35de,0x35df,
+ 0x35e0,0x35e1,0x35e2,0x35e3,0x35e4,0x35e5,0x35e6,0x35e7,
+ 0x35e8,0x35e9,0x35ea,0x35eb,0x35ec,0x35ed,0x35ee,0x35ef,
+ 0x35f0,0x35f1,0x35f2,0x35f3,0x35f4,0x35f5,0x35f6,0x35f7,
+ 0x35f8,0x35f9,0x35fa,0x35fb,0x35fc,0x35fd,0x35fe,0x35ff,
+ 0x3600,0x3601,0x3602,0x3603,0x3604,0x3605,0x3606,0x3607,
+ 0x3608,0x3609,0x360a,0x360b,0x360c,0x360d,0x360e,0x360f,
+ 0x3610,0x3611,0x3612,0x3613,0x3614,0x3615,0x3616,0x3617,
+ 0x3618,0x3619,0x361a,0x361b,0x361c,0x361d,0x361e,0x361f,
+ 0x3620,0x3621,0x3622,0x3623,0x3624,0x3625,0x3626,0x3627,
+ 0x3628,0x3629,0x362a,0x362b,0x362c,0x362d,0x362e,0x362f,
+ 0x3630,0x3631,0x3632,0x3633,0x3634,0x3635,0x3636,0x3637,
+ 0x3638,0x3639,0x363a,0x363b,0x363c,0x363d,0x363e,0x363f,
+ 0x3640,0x3641,0x3642,0x3643,0x3644,0x3645,0x3646,0x3647,
+ 0x3648,0x3649,0x364a,0x364b,0x364c,0x364d,0x364e,0x364f,
+ 0x3650,0x3651,0x3652,0x3653,0x3654,0x3655,0x3656,0x3657,
+ 0x3658,0x3659,0x365a,0x365b,0x365c,0x365d,0x365e,0x365f,
+ 0x3660,0x3661,0x3662,0x3663,0x3664,0x3665,0x3666,0x3667,
+ 0x3668,0x3669,0x366a,0x366b,0x366c,0x366d,0x366e,0x366f,
+ 0x3670,0x3671,0x3672,0x3673,0x3674,0x3675,0x3676,0x3677,
+ 0x3678,0x3679,0x367a,0x367b,0x367c,0x367d,0x367e,0x367f,
+ 0x3680,0x3681,0x3682,0x3683,0x3684,0x3685,0x3686,0x3687,
+ 0x3688,0x3689,0x368a,0x368b,0x368c,0x368d,0x368e,0x368f,
+ 0x3690,0x3691,0x3692,0x3693,0x3694,0x3695,0x3696,0x3697,
+ 0x3698,0x3699,0x369a,0x369b,0x369c,0x369d,0x369e,0x369f,
+ 0x36a0,0x36a1,0x36a2,0x36a3,0x36a4,0x36a5,0x36a6,0x36a7,
+ 0x36a8,0x36a9,0x36aa,0x36ab,0x36ac,0x36ad,0x36ae,0x36af,
+ 0x36b0,0x36b1,0x36b2,0x36b3,0x36b4,0x36b5,0x36b6,0x36b7,
+ 0x36b8,0x36b9,0x36ba,0x36bb,0x36bc,0x36bd,0x36be,0x36bf,
+ 0x36c0,0x36c1,0x36c2,0x36c3,0x36c4,0x36c5,0x36c6,0x36c7,
+ 0x36c8,0x36c9,0x36ca,0x36cb,0x36cc,0x36cd,0x36ce,0x36cf,
+ 0x36d0,0x36d1,0x36d2,0x36d3,0x36d4,0x36d5,0x36d6,0x36d7,
+ 0x36d8,0x36d9,0x36da,0x36db,0x36dc,0x36dd,0x36de,0x36df,
+ 0x36e0,0x36e1,0x36e2,0x36e3,0x36e4,0x36e5,0x36e6,0x36e7,
+ 0x36e8,0x36e9,0x36ea,0x36eb,0x36ec,0x36ed,0x36ee,0x36ef,
+ 0x36f0,0x36f1,0x36f2,0x36f3,0x36f4,0x36f5,0x36f6,0x36f7,
+ 0x36f8,0x36f9,0x36fa,0x36fb,0x36fc,0x36fd,0x36fe,0x36ff,
+ 0x3700,0x3701,0x3702,0x3703,0x3704,0x3705,0x3706,0x3707,
+ 0x3708,0x3709,0x370a,0x370b,0x370c,0x370d,0x370e,0x370f,
+ 0x3710,0x3711,0x3712,0x3713,0x3714,0x3715,0x3716,0x3717,
+ 0x3718,0x3719,0x371a,0x371b,0x371c,0x371d,0x371e,0x371f,
+ 0x3720,0x3721,0x3722,0x3723,0x3724,0x3725,0x3726,0x3727,
+ 0x3728,0x3729,0x372a,0x372b,0x372c,0x372d,0x372e,0x372f,
+ 0x3730,0x3731,0x3732,0x3733,0x3734,0x3735,0x3736,0x3737,
+ 0x3738,0x3739,0x373a,0x373b,0x373c,0x373d,0x373e,0x373f,
+ 0x3740,0x3741,0x3742,0x3743,0x3744,0x3745,0x3746,0x3747,
+ 0x3748,0x3749,0x374a,0x374b,0x374c,0x374d,0x374e,0x374f,
+ 0x3750,0x3751,0x3752,0x3753,0x3754,0x3755,0x3756,0x3757,
+ 0x3758,0x3759,0x375a,0x375b,0x375c,0x375d,0x375e,0x375f,
+ 0x3760,0x3761,0x3762,0x3763,0x3764,0x3765,0x3766,0x3767,
+ 0x3768,0x3769,0x376a,0x376b,0x376c,0x376d,0x376e,0x376f,
+ 0x3770,0x3771,0x3772,0x3773,0x3774,0x3775,0x3776,0x3777,
+ 0x3778,0x3779,0x377a,0x377b,0x377c,0x377d,0x377e,0x377f,
+ 0x3780,0x3781,0x3782,0x3783,0x3784,0x3785,0x3786,0x3787,
+ 0x3788,0x3789,0x378a,0x378b,0x378c,0x378d,0x378e,0x378f,
+ 0x3790,0x3791,0x3792,0x3793,0x3794,0x3795,0x3796,0x3797,
+ 0x3798,0x3799,0x379a,0x379b,0x379c,0x379d,0x379e,0x379f,
+ 0x37a0,0x37a1,0x37a2,0x37a3,0x37a4,0x37a5,0x37a6,0x37a7,
+ 0x37a8,0x37a9,0x37aa,0x37ab,0x37ac,0x37ad,0x37ae,0x37af,
+ 0x37b0,0x37b1,0x37b2,0x37b3,0x37b4,0x37b5,0x37b6,0x37b7,
+ 0x37b8,0x37b9,0x37ba,0x37bb,0x37bc,0x37bd,0x37be,0x37bf,
+ 0x37c0,0x37c1,0x37c2,0x37c3,0x37c4,0x37c5,0x37c6,0x37c7,
+ 0x37c8,0x37c9,0x37ca,0x37cb,0x37cc,0x37cd,0x37ce,0x37cf,
+ 0x37d0,0x37d1,0x37d2,0x37d3,0x37d4,0x37d5,0x37d6,0x37d7,
+ 0x37d8,0x37d9,0x37da,0x37db,0x37dc,0x37dd,0x37de,0x37df,
+ 0x37e0,0x37e1,0x37e2,0x37e3,0x37e4,0x37e5,0x37e6,0x37e7,
+ 0x37e8,0x37e9,0x37ea,0x37eb,0x37ec,0x37ed,0x37ee,0x37ef,
+ 0x37f0,0x37f1,0x37f2,0x37f3,0x37f4,0x37f5,0x37f6,0x37f7,
+ 0x37f8,0x37f9,0x37fa,0x37fb,0x37fc,0x37fd,0x37fe,0x37ff,
+ 0x3800,0x3801,0x3802,0x3803,0x3804,0x3805,0x3806,0x3807,
+ 0x3808,0x3809,0x380a,0x380b,0x380c,0x380d,0x380e,0x380f,
+ 0x3810,0x3811,0x3812,0x3813,0x3814,0x3815,0x3816,0x3817,
+ 0x3818,0x3819,0x381a,0x381b,0x381c,0x381d,0x381e,0x381f,
+ 0x3820,0x3821,0x3822,0x3823,0x3824,0x3825,0x3826,0x3827,
+ 0x3828,0x3829,0x382a,0x382b,0x382c,0x382d,0x382e,0x382f,
+ 0x3830,0x3831,0x3832,0x3833,0x3834,0x3835,0x3836,0x3837,
+ 0x3838,0x3839,0x383a,0x383b,0x383c,0x383d,0x383e,0x383f,
+ 0x3840,0x3841,0x3842,0x3843,0x3844,0x3845,0x3846,0x3847,
+ 0x3848,0x3849,0x384a,0x384b,0x384c,0x384d,0x384e,0x384f,
+ 0x3850,0x3851,0x3852,0x3853,0x3854,0x3855,0x3856,0x3857,
+ 0x3858,0x3859,0x385a,0x385b,0x385c,0x385d,0x385e,0x385f,
+ 0x3860,0x3861,0x3862,0x3863,0x3864,0x3865,0x3866,0x3867,
+ 0x3868,0x3869,0x386a,0x386b,0x386c,0x386d,0x386e,0x386f,
+ 0x3870,0x3871,0x3872,0x3873,0x3874,0x3875,0x3876,0x3877,
+ 0x3878,0x3879,0x387a,0x387b,0x387c,0x387d,0x387e,0x387f,
+ 0x3880,0x3881,0x3882,0x3883,0x3884,0x3885,0x3886,0x3887,
+ 0x3888,0x3889,0x388a,0x388b,0x388c,0x388d,0x388e,0x388f,
+ 0x3890,0x3891,0x3892,0x3893,0x3894,0x3895,0x3896,0x3897,
+ 0x3898,0x3899,0x389a,0x389b,0x389c,0x389d,0x389e,0x389f,
+ 0x38a0,0x38a1,0x38a2,0x38a3,0x38a4,0x38a5,0x38a6,0x38a7,
+ 0x38a8,0x38a9,0x38aa,0x38ab,0x38ac,0x38ad,0x38ae,0x38af,
+ 0x38b0,0x38b1,0x38b2,0x38b3,0x38b4,0x38b5,0x38b6,0x38b7,
+ 0x38b8,0x38b9,0x38ba,0x38bb,0x38bc,0x38bd,0x38be,0x38bf,
+ 0x38c0,0x38c1,0x38c2,0x38c3,0x38c4,0x38c5,0x38c6,0x38c7,
+ 0x38c8,0x38c9,0x38ca,0x38cb,0x38cc,0x38cd,0x38ce,0x38cf,
+ 0x38d0,0x38d1,0x38d2,0x38d3,0x38d4,0x38d5,0x38d6,0x38d7,
+ 0x38d8,0x38d9,0x38da,0x38db,0x38dc,0x38dd,0x38de,0x38df,
+ 0x38e0,0x38e1,0x38e2,0x38e3,0x38e4,0x38e5,0x38e6,0x38e7,
+ 0x38e8,0x38e9,0x38ea,0x38eb,0x38ec,0x38ed,0x38ee,0x38ef,
+ 0x38f0,0x38f1,0x38f2,0x38f3,0x38f4,0x38f5,0x38f6,0x38f7,
+ 0x38f8,0x38f9,0x38fa,0x38fb,0x38fc,0x38fd,0x38fe,0x38ff,
+ 0x3900,0x3901,0x3902,0x3903,0x3904,0x3905,0x3906,0x3907,
+ 0x3908,0x3909,0x390a,0x390b,0x390c,0x390d,0x390e,0x390f,
+ 0x3910,0x3911,0x3912,0x3913,0x3914,0x3915,0x3916,0x3917,
+ 0x3918,0x3919,0x391a,0x391b,0x391c,0x391d,0x391e,0x391f,
+ 0x3920,0x3921,0x3922,0x3923,0x3924,0x3925,0x3926,0x3927,
+ 0x3928,0x3929,0x392a,0x392b,0x392c,0x392d,0x392e,0x392f,
+ 0x3930,0x3931,0x3932,0x3933,0x3934,0x3935,0x3936,0x3937,
+ 0x3938,0x3939,0x393a,0x393b,0x393c,0x393d,0x393e,0x393f,
+ 0x3940,0x3941,0x3942,0x3943,0x3944,0x3945,0x3946,0x3947,
+ 0x3948,0x3949,0x394a,0x394b,0x394c,0x394d,0x394e,0x394f,
+ 0x3950,0x3951,0x3952,0x3953,0x3954,0x3955,0x3956,0x3957,
+ 0x3958,0x3959,0x395a,0x395b,0x395c,0x395d,0x395e,0x395f,
+ 0x3960,0x3961,0x3962,0x3963,0x3964,0x3965,0x3966,0x3967,
+ 0x3968,0x3969,0x396a,0x396b,0x396c,0x396d,0x396e,0x396f,
+ 0x3970,0x3971,0x3972,0x3973,0x3974,0x3975,0x3976,0x3977,
+ 0x3978,0x3979,0x397a,0x397b,0x397c,0x397d,0x397e,0x397f,
+ 0x3980,0x3981,0x3982,0x3983,0x3984,0x3985,0x3986,0x3987,
+ 0x3988,0x3989,0x398a,0x398b,0x398c,0x398d,0x398e,0x398f,
+ 0x3990,0x3991,0x3992,0x3993,0x3994,0x3995,0x3996,0x3997,
+ 0x3998,0x3999,0x399a,0x399b,0x399c,0x399d,0x399e,0x399f,
+ 0x39a0,0x39a1,0x39a2,0x39a3,0x39a4,0x39a5,0x39a6,0x39a7,
+ 0x39a8,0x39a9,0x39aa,0x39ab,0x39ac,0x39ad,0x39ae,0x39af,
+ 0x39b0,0x39b1,0x39b2,0x39b3,0x39b4,0x39b5,0x39b6,0x39b7,
+ 0x39b8,0x39b9,0x39ba,0x39bb,0x39bc,0x39bd,0x39be,0x39bf,
+ 0x39c0,0x39c1,0x39c2,0x39c3,0x39c4,0x39c5,0x39c6,0x39c7,
+ 0x39c8,0x39c9,0x39ca,0x39cb,0x39cc,0x39cd,0x39ce,0x39cf,
+ 0x39d0,0x39d1,0x39d2,0x39d3,0x39d4,0x39d5,0x39d6,0x39d7,
+ 0x39d8,0x39d9,0x39da,0x39db,0x39dc,0x39dd,0x39de,0x39df,
+ 0x39e0,0x39e1,0x39e2,0x39e3,0x39e4,0x39e5,0x39e6,0x39e7,
+ 0x39e8,0x39e9,0x39ea,0x39eb,0x39ec,0x39ed,0x39ee,0x39ef,
+ 0x39f0,0x39f1,0x39f2,0x39f3,0x39f4,0x39f5,0x39f6,0x39f7,
+ 0x39f8,0x39f9,0x39fa,0x39fb,0x39fc,0x39fd,0x39fe,0x39ff,
+ 0x3a00,0x3a01,0x3a02,0x3a03,0x3a04,0x3a05,0x3a06,0x3a07,
+ 0x3a08,0x3a09,0x3a0a,0x3a0b,0x3a0c,0x3a0d,0x3a0e,0x3a0f,
+ 0x3a10,0x3a11,0x3a12,0x3a13,0x3a14,0x3a15,0x3a16,0x3a17,
+ 0x3a18,0x3a19,0x3a1a,0x3a1b,0x3a1c,0x3a1d,0x3a1e,0x3a1f,
+ 0x3a20,0x3a21,0x3a22,0x3a23,0x3a24,0x3a25,0x3a26,0x3a27,
+ 0x3a28,0x3a29,0x3a2a,0x3a2b,0x3a2c,0x3a2d,0x3a2e,0x3a2f,
+ 0x3a30,0x3a31,0x3a32,0x3a33,0x3a34,0x3a35,0x3a36,0x3a37,
+ 0x3a38,0x3a39,0x3a3a,0x3a3b,0x3a3c,0x3a3d,0x3a3e,0x3a3f,
+ 0x3a40,0x3a41,0x3a42,0x3a43,0x3a44,0x3a45,0x3a46,0x3a47,
+ 0x3a48,0x3a49,0x3a4a,0x3a4b,0x3a4c,0x3a4d,0x3a4e,0x3a4f,
+ 0x3a50,0x3a51,0x3a52,0x3a53,0x3a54,0x3a55,0x3a56,0x3a57,
+ 0x3a58,0x3a59,0x3a5a,0x3a5b,0x3a5c,0x3a5d,0x3a5e,0x3a5f,
+ 0x3a60,0x3a61,0x3a62,0x3a63,0x3a64,0x3a65,0x3a66,0x3a67,
+ 0x3a68,0x3a69,0x3a6a,0x3a6b,0x3a6c,0x3a6d,0x3a6e,0x3a6f,
+ 0x3a70,0x3a71,0x3a72,0x3a73,0x3a74,0x3a75,0x3a76,0x3a77,
+ 0x3a78,0x3a79,0x3a7a,0x3a7b,0x3a7c,0x3a7d,0x3a7e,0x3a7f,
+ 0x3a80,0x3a81,0x3a82,0x3a83,0x3a84,0x3a85,0x3a86,0x3a87,
+ 0x3a88,0x3a89,0x3a8a,0x3a8b,0x3a8c,0x3a8d,0x3a8e,0x3a8f,
+ 0x3a90,0x3a91,0x3a92,0x3a93,0x3a94,0x3a95,0x3a96,0x3a97,
+ 0x3a98,0x3a99,0x3a9a,0x3a9b,0x3a9c,0x3a9d,0x3a9e,0x3a9f,
+ 0x3aa0,0x3aa1,0x3aa2,0x3aa3,0x3aa4,0x3aa5,0x3aa6,0x3aa7,
+ 0x3aa8,0x3aa9,0x3aaa,0x3aab,0x3aac,0x3aad,0x3aae,0x3aaf,
+ 0x3ab0,0x3ab1,0x3ab2,0x3ab3,0x3ab4,0x3ab5,0x3ab6,0x3ab7,
+ 0x3ab8,0x3ab9,0x3aba,0x3abb,0x3abc,0x3abd,0x3abe,0x3abf,
+ 0x3ac0,0x3ac1,0x3ac2,0x3ac3,0x3ac4,0x3ac5,0x3ac6,0x3ac7,
+ 0x3ac8,0x3ac9,0x3aca,0x3acb,0x3acc,0x3acd,0x3ace,0x3acf,
+ 0x3ad0,0x3ad1,0x3ad2,0x3ad3,0x3ad4,0x3ad5,0x3ad6,0x3ad7,
+ 0x3ad8,0x3ad9,0x3ada,0x3adb,0x3adc,0x3add,0x3ade,0x3adf,
+ 0x3ae0,0x3ae1,0x3ae2,0x3ae3,0x3ae4,0x3ae5,0x3ae6,0x3ae7,
+ 0x3ae8,0x3ae9,0x3aea,0x3aeb,0x3aec,0x3aed,0x3aee,0x3aef,
+ 0x3af0,0x3af1,0x3af2,0x3af3,0x3af4,0x3af5,0x3af6,0x3af7,
+ 0x3af8,0x3af9,0x3afa,0x3afb,0x3afc,0x3afd,0x3afe,0x3aff,
+ 0x3b00,0x3b01,0x3b02,0x3b03,0x3b04,0x3b05,0x3b06,0x3b07,
+ 0x3b08,0x3b09,0x3b0a,0x3b0b,0x3b0c,0x3b0d,0x3b0e,0x3b0f,
+ 0x3b10,0x3b11,0x3b12,0x3b13,0x3b14,0x3b15,0x3b16,0x3b17,
+ 0x3b18,0x3b19,0x3b1a,0x3b1b,0x3b1c,0x3b1d,0x3b1e,0x3b1f,
+ 0x3b20,0x3b21,0x3b22,0x3b23,0x3b24,0x3b25,0x3b26,0x3b27,
+ 0x3b28,0x3b29,0x3b2a,0x3b2b,0x3b2c,0x3b2d,0x3b2e,0x3b2f,
+ 0x3b30,0x3b31,0x3b32,0x3b33,0x3b34,0x3b35,0x3b36,0x3b37,
+ 0x3b38,0x3b39,0x3b3a,0x3b3b,0x3b3c,0x3b3d,0x3b3e,0x3b3f,
+ 0x3b40,0x3b41,0x3b42,0x3b43,0x3b44,0x3b45,0x3b46,0x3b47,
+ 0x3b48,0x3b49,0x3b4a,0x3b4b,0x3b4c,0x3b4d,0x3b4e,0x3b4f,
+ 0x3b50,0x3b51,0x3b52,0x3b53,0x3b54,0x3b55,0x3b56,0x3b57,
+ 0x3b58,0x3b59,0x3b5a,0x3b5b,0x3b5c,0x3b5d,0x3b5e,0x3b5f,
+ 0x3b60,0x3b61,0x3b62,0x3b63,0x3b64,0x3b65,0x3b66,0x3b67,
+ 0x3b68,0x3b69,0x3b6a,0x3b6b,0x3b6c,0x3b6d,0x3b6e,0x3b6f,
+ 0x3b70,0x3b71,0x3b72,0x3b73,0x3b74,0x3b75,0x3b76,0x3b77,
+ 0x3b78,0x3b79,0x3b7a,0x3b7b,0x3b7c,0x3b7d,0x3b7e,0x3b7f,
+ 0x3b80,0x3b81,0x3b82,0x3b83,0x3b84,0x3b85,0x3b86,0x3b87,
+ 0x3b88,0x3b89,0x3b8a,0x3b8b,0x3b8c,0x3b8d,0x3b8e,0x3b8f,
+ 0x3b90,0x3b91,0x3b92,0x3b93,0x3b94,0x3b95,0x3b96,0x3b97,
+ 0x3b98,0x3b99,0x3b9a,0x3b9b,0x3b9c,0x3b9d,0x3b9e,0x3b9f,
+ 0x3ba0,0x3ba1,0x3ba2,0x3ba3,0x3ba4,0x3ba5,0x3ba6,0x3ba7,
+ 0x3ba8,0x3ba9,0x3baa,0x3bab,0x3bac,0x3bad,0x3bae,0x3baf,
+ 0x3bb0,0x3bb1,0x3bb2,0x3bb3,0x3bb4,0x3bb5,0x3bb6,0x3bb7,
+ 0x3bb8,0x3bb9,0x3bba,0x3bbb,0x3bbc,0x3bbd,0x3bbe,0x3bbf,
+ 0x3bc0,0x3bc1,0x3bc2,0x3bc3,0x3bc4,0x3bc5,0x3bc6,0x3bc7,
+ 0x3bc8,0x3bc9,0x3bca,0x3bcb,0x3bcc,0x3bcd,0x3bce,0x3bcf,
+ 0x3bd0,0x3bd1,0x3bd2,0x3bd3,0x3bd4,0x3bd5,0x3bd6,0x3bd7,
+ 0x3bd8,0x3bd9,0x3bda,0x3bdb,0x3bdc,0x3bdd,0x3bde,0x3bdf,
+ 0x3be0,0x3be1,0x3be2,0x3be3,0x3be4,0x3be5,0x3be6,0x3be7,
+ 0x3be8,0x3be9,0x3bea,0x3beb,0x3bec,0x3bed,0x3bee,0x3bef,
+ 0x3bf0,0x3bf1,0x3bf2,0x3bf3,0x3bf4,0x3bf5,0x3bf6,0x3bf7,
+ 0x3bf8,0x3bf9,0x3bfa,0x3bfb,0x3bfc,0x3bfd,0x3bfe,0x3bff,
+ 0x3c00,0x3c01,0x3c02,0x3c03,0x3c04,0x3c05,0x3c06,0x3c07,
+ 0x3c08,0x3c09,0x3c0a,0x3c0b,0x3c0c,0x3c0d,0x3c0e,0x3c0f,
+ 0x3c10,0x3c11,0x3c12,0x3c13,0x3c14,0x3c15,0x3c16,0x3c17,
+ 0x3c18,0x3c19,0x3c1a,0x3c1b,0x3c1c,0x3c1d,0x3c1e,0x3c1f,
+ 0x3c20,0x3c21,0x3c22,0x3c23,0x3c24,0x3c25,0x3c26,0x3c27,
+ 0x3c28,0x3c29,0x3c2a,0x3c2b,0x3c2c,0x3c2d,0x3c2e,0x3c2f,
+ 0x3c30,0x3c31,0x3c32,0x3c33,0x3c34,0x3c35,0x3c36,0x3c37,
+ 0x3c38,0x3c39,0x3c3a,0x3c3b,0x3c3c,0x3c3d,0x3c3e,0x3c3f,
+ 0x3c40,0x3c41,0x3c42,0x3c43,0x3c44,0x3c45,0x3c46,0x3c47,
+ 0x3c48,0x3c49,0x3c4a,0x3c4b,0x3c4c,0x3c4d,0x3c4e,0x3c4f,
+ 0x3c50,0x3c51,0x3c52,0x3c53,0x3c54,0x3c55,0x3c56,0x3c57,
+ 0x3c58,0x3c59,0x3c5a,0x3c5b,0x3c5c,0x3c5d,0x3c5e,0x3c5f,
+ 0x3c60,0x3c61,0x3c62,0x3c63,0x3c64,0x3c65,0x3c66,0x3c67,
+ 0x3c68,0x3c69,0x3c6a,0x3c6b,0x3c6c,0x3c6d,0x3c6e,0x3c6f,
+ 0x3c70,0x3c71,0x3c72,0x3c73,0x3c74,0x3c75,0x3c76,0x3c77,
+ 0x3c78,0x3c79,0x3c7a,0x3c7b,0x3c7c,0x3c7d,0x3c7e,0x3c7f,
+ 0x3c80,0x3c81,0x3c82,0x3c83,0x3c84,0x3c85,0x3c86,0x3c87,
+ 0x3c88,0x3c89,0x3c8a,0x3c8b,0x3c8c,0x3c8d,0x3c8e,0x3c8f,
+ 0x3c90,0x3c91,0x3c92,0x3c93,0x3c94,0x3c95,0x3c96,0x3c97,
+ 0x3c98,0x3c99,0x3c9a,0x3c9b,0x3c9c,0x3c9d,0x3c9e,0x3c9f,
+ 0x3ca0,0x3ca1,0x3ca2,0x3ca3,0x3ca4,0x3ca5,0x3ca6,0x3ca7,
+ 0x3ca8,0x3ca9,0x3caa,0x3cab,0x3cac,0x3cad,0x3cae,0x3caf,
+ 0x3cb0,0x3cb1,0x3cb2,0x3cb3,0x3cb4,0x3cb5,0x3cb6,0x3cb7,
+ 0x3cb8,0x3cb9,0x3cba,0x3cbb,0x3cbc,0x3cbd,0x3cbe,0x3cbf,
+ 0x3cc0,0x3cc1,0x3cc2,0x3cc3,0x3cc4,0x3cc5,0x3cc6,0x3cc7,
+ 0x3cc8,0x3cc9,0x3cca,0x3ccb,0x3ccc,0x3ccd,0x3cce,0x3ccf,
+ 0x3cd0,0x3cd1,0x3cd2,0x3cd3,0x3cd4,0x3cd5,0x3cd6,0x3cd7,
+ 0x3cd8,0x3cd9,0x3cda,0x3cdb,0x3cdc,0x3cdd,0x3cde,0x3cdf,
+ 0x3ce0,0x3ce1,0x3ce2,0x3ce3,0x3ce4,0x3ce5,0x3ce6,0x3ce7,
+ 0x3ce8,0x3ce9,0x3cea,0x3ceb,0x3cec,0x3ced,0x3cee,0x3cef,
+ 0x3cf0,0x3cf1,0x3cf2,0x3cf3,0x3cf4,0x3cf5,0x3cf6,0x3cf7,
+ 0x3cf8,0x3cf9,0x3cfa,0x3cfb,0x3cfc,0x3cfd,0x3cfe,0x3cff,
+ 0x3d00,0x3d01,0x3d02,0x3d03,0x3d04,0x3d05,0x3d06,0x3d07,
+ 0x3d08,0x3d09,0x3d0a,0x3d0b,0x3d0c,0x3d0d,0x3d0e,0x3d0f,
+ 0x3d10,0x3d11,0x3d12,0x3d13,0x3d14,0x3d15,0x3d16,0x3d17,
+ 0x3d18,0x3d19,0x3d1a,0x3d1b,0x3d1c,0x3d1d,0x3d1e,0x3d1f,
+ 0x3d20,0x3d21,0x3d22,0x3d23,0x3d24,0x3d25,0x3d26,0x3d27,
+ 0x3d28,0x3d29,0x3d2a,0x3d2b,0x3d2c,0x3d2d,0x3d2e,0x3d2f,
+ 0x3d30,0x3d31,0x3d32,0x3d33,0x3d34,0x3d35,0x3d36,0x3d37,
+ 0x3d38,0x3d39,0x3d3a,0x3d3b,0x3d3c,0x3d3d,0x3d3e,0x3d3f,
+ 0x3d40,0x3d41,0x3d42,0x3d43,0x3d44,0x3d45,0x3d46,0x3d47,
+ 0x3d48,0x3d49,0x3d4a,0x3d4b,0x3d4c,0x3d4d,0x3d4e,0x3d4f,
+ 0x3d50,0x3d51,0x3d52,0x3d53,0x3d54,0x3d55,0x3d56,0x3d57,
+ 0x3d58,0x3d59,0x3d5a,0x3d5b,0x3d5c,0x3d5d,0x3d5e,0x3d5f,
+ 0x3d60,0x3d61,0x3d62,0x3d63,0x3d64,0x3d65,0x3d66,0x3d67,
+ 0x3d68,0x3d69,0x3d6a,0x3d6b,0x3d6c,0x3d6d,0x3d6e,0x3d6f,
+ 0x3d70,0x3d71,0x3d72,0x3d73,0x3d74,0x3d75,0x3d76,0x3d77,
+ 0x3d78,0x3d79,0x3d7a,0x3d7b,0x3d7c,0x3d7d,0x3d7e,0x3d7f,
+ 0x3d80,0x3d81,0x3d82,0x3d83,0x3d84,0x3d85,0x3d86,0x3d87,
+ 0x3d88,0x3d89,0x3d8a,0x3d8b,0x3d8c,0x3d8d,0x3d8e,0x3d8f,
+ 0x3d90,0x3d91,0x3d92,0x3d93,0x3d94,0x3d95,0x3d96,0x3d97,
+ 0x3d98,0x3d99,0x3d9a,0x3d9b,0x3d9c,0x3d9d,0x3d9e,0x3d9f,
+ 0x3da0,0x3da1,0x3da2,0x3da3,0x3da4,0x3da5,0x3da6,0x3da7,
+ 0x3da8,0x3da9,0x3daa,0x3dab,0x3dac,0x3dad,0x3dae,0x3daf,
+ 0x3db0,0x3db1,0x3db2,0x3db3,0x3db4,0x3db5,0x3db6,0x3db7,
+ 0x3db8,0x3db9,0x3dba,0x3dbb,0x3dbc,0x3dbd,0x3dbe,0x3dbf,
+ 0x3dc0,0x3dc1,0x3dc2,0x3dc3,0x3dc4,0x3dc5,0x3dc6,0x3dc7,
+ 0x3dc8,0x3dc9,0x3dca,0x3dcb,0x3dcc,0x3dcd,0x3dce,0x3dcf,
+ 0x3dd0,0x3dd1,0x3dd2,0x3dd3,0x3dd4,0x3dd5,0x3dd6,0x3dd7,
+ 0x3dd8,0x3dd9,0x3dda,0x3ddb,0x3ddc,0x3ddd,0x3dde,0x3ddf,
+ 0x3de0,0x3de1,0x3de2,0x3de3,0x3de4,0x3de5,0x3de6,0x3de7,
+ 0x3de8,0x3de9,0x3dea,0x3deb,0x3dec,0x3ded,0x3dee,0x3def,
+ 0x3df0,0x3df1,0x3df2,0x3df3,0x3df4,0x3df5,0x3df6,0x3df7,
+ 0x3df8,0x3df9,0x3dfa,0x3dfb,0x3dfc,0x3dfd,0x3dfe,0x3dff,
+ 0x3e00,0x3e01,0x3e02,0x3e03,0x3e04,0x3e05,0x3e06,0x3e07,
+ 0x3e08,0x3e09,0x3e0a,0x3e0b,0x3e0c,0x3e0d,0x3e0e,0x3e0f,
+ 0x3e10,0x3e11,0x3e12,0x3e13,0x3e14,0x3e15,0x3e16,0x3e17,
+ 0x3e18,0x3e19,0x3e1a,0x3e1b,0x3e1c,0x3e1d,0x3e1e,0x3e1f,
+ 0x3e20,0x3e21,0x3e22,0x3e23,0x3e24,0x3e25,0x3e26,0x3e27,
+ 0x3e28,0x3e29,0x3e2a,0x3e2b,0x3e2c,0x3e2d,0x3e2e,0x3e2f,
+ 0x3e30,0x3e31,0x3e32,0x3e33,0x3e34,0x3e35,0x3e36,0x3e37,
+ 0x3e38,0x3e39,0x3e3a,0x3e3b,0x3e3c,0x3e3d,0x3e3e,0x3e3f,
+ 0x3e40,0x3e41,0x3e42,0x3e43,0x3e44,0x3e45,0x3e46,0x3e47,
+ 0x3e48,0x3e49,0x3e4a,0x3e4b,0x3e4c,0x3e4d,0x3e4e,0x3e4f,
+ 0x3e50,0x3e51,0x3e52,0x3e53,0x3e54,0x3e55,0x3e56,0x3e57,
+ 0x3e58,0x3e59,0x3e5a,0x3e5b,0x3e5c,0x3e5d,0x3e5e,0x3e5f,
+ 0x3e60,0x3e61,0x3e62,0x3e63,0x3e64,0x3e65,0x3e66,0x3e67,
+ 0x3e68,0x3e69,0x3e6a,0x3e6b,0x3e6c,0x3e6d,0x3e6e,0x3e6f,
+ 0x3e70,0x3e71,0x3e72,0x3e73,0x3e74,0x3e75,0x3e76,0x3e77,
+ 0x3e78,0x3e79,0x3e7a,0x3e7b,0x3e7c,0x3e7d,0x3e7e,0x3e7f,
+ 0x3e80,0x3e81,0x3e82,0x3e83,0x3e84,0x3e85,0x3e86,0x3e87,
+ 0x3e88,0x3e89,0x3e8a,0x3e8b,0x3e8c,0x3e8d,0x3e8e,0x3e8f,
+ 0x3e90,0x3e91,0x3e92,0x3e93,0x3e94,0x3e95,0x3e96,0x3e97,
+ 0x3e98,0x3e99,0x3e9a,0x3e9b,0x3e9c,0x3e9d,0x3e9e,0x3e9f,
+ 0x3ea0,0x3ea1,0x3ea2,0x3ea3,0x3ea4,0x3ea5,0x3ea6,0x3ea7,
+ 0x3ea8,0x3ea9,0x3eaa,0x3eab,0x3eac,0x3ead,0x3eae,0x3eaf,
+ 0x3eb0,0x3eb1,0x3eb2,0x3eb3,0x3eb4,0x3eb5,0x3eb6,0x3eb7,
+ 0x3eb8,0x3eb9,0x3eba,0x3ebb,0x3ebc,0x3ebd,0x3ebe,0x3ebf,
+ 0x3ec0,0x3ec1,0x3ec2,0x3ec3,0x3ec4,0x3ec5,0x3ec6,0x3ec7,
+ 0x3ec8,0x3ec9,0x3eca,0x3ecb,0x3ecc,0x3ecd,0x3ece,0x3ecf,
+ 0x3ed0,0x3ed1,0x3ed2,0x3ed3,0x3ed4,0x3ed5,0x3ed6,0x3ed7,
+ 0x3ed8,0x3ed9,0x3eda,0x3edb,0x3edc,0x3edd,0x3ede,0x3edf,
+ 0x3ee0,0x3ee1,0x3ee2,0x3ee3,0x3ee4,0x3ee5,0x3ee6,0x3ee7,
+ 0x3ee8,0x3ee9,0x3eea,0x3eeb,0x3eec,0x3eed,0x3eee,0x3eef,
+ 0x3ef0,0x3ef1,0x3ef2,0x3ef3,0x3ef4,0x3ef5,0x3ef6,0x3ef7,
+ 0x3ef8,0x3ef9,0x3efa,0x3efb,0x3efc,0x3efd,0x3efe,0x3eff,
+ 0x3f00,0x3f01,0x3f02,0x3f03,0x3f04,0x3f05,0x3f06,0x3f07,
+ 0x3f08,0x3f09,0x3f0a,0x3f0b,0x3f0c,0x3f0d,0x3f0e,0x3f0f,
+ 0x3f10,0x3f11,0x3f12,0x3f13,0x3f14,0x3f15,0x3f16,0x3f17,
+ 0x3f18,0x3f19,0x3f1a,0x3f1b,0x3f1c,0x3f1d,0x3f1e,0x3f1f,
+ 0x3f20,0x3f21,0x3f22,0x3f23,0x3f24,0x3f25,0x3f26,0x3f27,
+ 0x3f28,0x3f29,0x3f2a,0x3f2b,0x3f2c,0x3f2d,0x3f2e,0x3f2f,
+ 0x3f30,0x3f31,0x3f32,0x3f33,0x3f34,0x3f35,0x3f36,0x3f37,
+ 0x3f38,0x3f39,0x3f3a,0x3f3b,0x3f3c,0x3f3d,0x3f3e,0x3f3f,
+ 0x3f40,0x3f41,0x3f42,0x3f43,0x3f44,0x3f45,0x3f46,0x3f47,
+ 0x3f48,0x3f49,0x3f4a,0x3f4b,0x3f4c,0x3f4d,0x3f4e,0x3f4f,
+ 0x3f50,0x3f51,0x3f52,0x3f53,0x3f54,0x3f55,0x3f56,0x3f57,
+ 0x3f58,0x3f59,0x3f5a,0x3f5b,0x3f5c,0x3f5d,0x3f5e,0x3f5f,
+ 0x3f60,0x3f61,0x3f62,0x3f63,0x3f64,0x3f65,0x3f66,0x3f67,
+ 0x3f68,0x3f69,0x3f6a,0x3f6b,0x3f6c,0x3f6d,0x3f6e,0x3f6f,
+ 0x3f70,0x3f71,0x3f72,0x3f73,0x3f74,0x3f75,0x3f76,0x3f77,
+ 0x3f78,0x3f79,0x3f7a,0x3f7b,0x3f7c,0x3f7d,0x3f7e,0x3f7f,
+ 0x3f80,0x3f81,0x3f82,0x3f83,0x3f84,0x3f85,0x3f86,0x3f87,
+ 0x3f88,0x3f89,0x3f8a,0x3f8b,0x3f8c,0x3f8d,0x3f8e,0x3f8f,
+ 0x3f90,0x3f91,0x3f92,0x3f93,0x3f94,0x3f95,0x3f96,0x3f97,
+ 0x3f98,0x3f99,0x3f9a,0x3f9b,0x3f9c,0x3f9d,0x3f9e,0x3f9f,
+ 0x3fa0,0x3fa1,0x3fa2,0x3fa3,0x3fa4,0x3fa5,0x3fa6,0x3fa7,
+ 0x3fa8,0x3fa9,0x3faa,0x3fab,0x3fac,0x3fad,0x3fae,0x3faf,
+ 0x3fb0,0x3fb1,0x3fb2,0x3fb3,0x3fb4,0x3fb5,0x3fb6,0x3fb7,
+ 0x3fb8,0x3fb9,0x3fba,0x3fbb,0x3fbc,0x3fbd,0x3fbe,0x3fbf,
+ 0x3fc0,0x3fc1,0x3fc2,0x3fc3,0x3fc4,0x3fc5,0x3fc6,0x3fc7,
+ 0x3fc8,0x3fc9,0x3fca,0x3fcb,0x3fcc,0x3fcd,0x3fce,0x3fcf,
+ 0x3fd0,0x3fd1,0x3fd2,0x3fd3,0x3fd4,0x3fd5,0x3fd6,0x3fd7,
+ 0x3fd8,0x3fd9,0x3fda,0x3fdb,0x3fdc,0x3fdd,0x3fde,0x3fdf,
+ 0x3fe0,0x3fe1,0x3fe2,0x3fe3,0x3fe4,0x3fe5,0x3fe6,0x3fe7,
+ 0x3fe8,0x3fe9,0x3fea,0x3feb,0x3fec,0x3fed,0x3fee,0x3fef,
+ 0x3ff0,0x3ff1,0x3ff2,0x3ff3,0x3ff4,0x3ff5,0x3ff6,0x3ff7,
+ 0x3ff8,0x3ff9,0x3ffa,0x3ffb,0x3ffc,0x3ffd,0x3ffe,0x3fff,
+ 0x4000,0x4001,0x4002,0x4003,0x4004,0x4005,0x4006,0x4007,
+ 0x4008,0x4009,0x400a,0x400b,0x400c,0x400d,0x400e,0x400f,
+ 0x4010,0x4011,0x4012,0x4013,0x4014,0x4015,0x4016,0x4017,
+ 0x4018,0x4019,0x401a,0x401b,0x401c,0x401d,0x401e,0x401f,
+ 0x4020,0x4021,0x4022,0x4023,0x4024,0x4025,0x4026,0x4027,
+ 0x4028,0x4029,0x402a,0x402b,0x402c,0x402d,0x402e,0x402f,
+ 0x4030,0x4031,0x4032,0x4033,0x4034,0x4035,0x4036,0x4037,
+ 0x4038,0x4039,0x403a,0x403b,0x403c,0x403d,0x403e,0x403f,
+ 0x4040,0x4041,0x4042,0x4043,0x4044,0x4045,0x4046,0x4047,
+ 0x4048,0x4049,0x404a,0x404b,0x404c,0x404d,0x404e,0x404f,
+ 0x4050,0x4051,0x4052,0x4053,0x4054,0x4055,0x4056,0x4057,
+ 0x4058,0x4059,0x405a,0x405b,0x405c,0x405d,0x405e,0x405f,
+ 0x4060,0x4061,0x4062,0x4063,0x4064,0x4065,0x4066,0x4067,
+ 0x4068,0x4069,0x406a,0x406b,0x406c,0x406d,0x406e,0x406f,
+ 0x4070,0x4071,0x4072,0x4073,0x4074,0x4075,0x4076,0x4077,
+ 0x4078,0x4079,0x407a,0x407b,0x407c,0x407d,0x407e,0x407f,
+ 0x4080,0x4081,0x4082,0x4083,0x4084,0x4085,0x4086,0x4087,
+ 0x4088,0x4089,0x408a,0x408b,0x408c,0x408d,0x408e,0x408f,
+ 0x4090,0x4091,0x4092,0x4093,0x4094,0x4095,0x4096,0x4097,
+ 0x4098,0x4099,0x409a,0x409b,0x409c,0x409d,0x409e,0x409f,
+ 0x40a0,0x40a1,0x40a2,0x40a3,0x40a4,0x40a5,0x40a6,0x40a7,
+ 0x40a8,0x40a9,0x40aa,0x40ab,0x40ac,0x40ad,0x40ae,0x40af,
+ 0x40b0,0x40b1,0x40b2,0x40b3,0x40b4,0x40b5,0x40b6,0x40b7,
+ 0x40b8,0x40b9,0x40ba,0x40bb,0x40bc,0x40bd,0x40be,0x40bf,
+ 0x40c0,0x40c1,0x40c2,0x40c3,0x40c4,0x40c5,0x40c6,0x40c7,
+ 0x40c8,0x40c9,0x40ca,0x40cb,0x40cc,0x40cd,0x40ce,0x40cf,
+ 0x40d0,0x40d1,0x40d2,0x40d3,0x40d4,0x40d5,0x40d6,0x40d7,
+ 0x40d8,0x40d9,0x40da,0x40db,0x40dc,0x40dd,0x40de,0x40df,
+ 0x40e0,0x40e1,0x40e2,0x40e3,0x40e4,0x40e5,0x40e6,0x40e7,
+ 0x40e8,0x40e9,0x40ea,0x40eb,0x40ec,0x40ed,0x40ee,0x40ef,
+ 0x40f0,0x40f1,0x40f2,0x40f3,0x40f4,0x40f5,0x40f6,0x40f7,
+ 0x40f8,0x40f9,0x40fa,0x40fb,0x40fc,0x40fd,0x40fe,0x40ff,
+ 0x4100,0x4101,0x4102,0x4103,0x4104,0x4105,0x4106,0x4107,
+ 0x4108,0x4109,0x410a,0x410b,0x410c,0x410d,0x410e,0x410f,
+ 0x4110,0x4111,0x4112,0x4113,0x4114,0x4115,0x4116,0x4117,
+ 0x4118,0x4119,0x411a,0x411b,0x411c,0x411d,0x411e,0x411f,
+ 0x4120,0x4121,0x4122,0x4123,0x4124,0x4125,0x4126,0x4127,
+ 0x4128,0x4129,0x412a,0x412b,0x412c,0x412d,0x412e,0x412f,
+ 0x4130,0x4131,0x4132,0x4133,0x4134,0x4135,0x4136,0x4137,
+ 0x4138,0x4139,0x413a,0x413b,0x413c,0x413d,0x413e,0x413f,
+ 0x4140,0x4141,0x4142,0x4143,0x4144,0x4145,0x4146,0x4147,
+ 0x4148,0x4149,0x414a,0x414b,0x414c,0x414d,0x414e,0x414f,
+ 0x4150,0x4151,0x4152,0x4153,0x4154,0x4155,0x4156,0x4157,
+ 0x4158,0x4159,0x415a,0x415b,0x415c,0x415d,0x415e,0x415f,
+ 0x4160,0x4161,0x4162,0x4163,0x4164,0x4165,0x4166,0x4167,
+ 0x4168,0x4169,0x416a,0x416b,0x416c,0x416d,0x416e,0x416f,
+ 0x4170,0x4171,0x4172,0x4173,0x4174,0x4175,0x4176,0x4177,
+ 0x4178,0x4179,0x417a,0x417b,0x417c,0x417d,0x417e,0x417f,
+ 0x4180,0x4181,0x4182,0x4183,0x4184,0x4185,0x4186,0x4187,
+ 0x4188,0x4189,0x418a,0x418b,0x418c,0x418d,0x418e,0x418f,
+ 0x4190,0x4191,0x4192,0x4193,0x4194,0x4195,0x4196,0x4197,
+ 0x4198,0x4199,0x419a,0x419b,0x419c,0x419d,0x419e,0x419f,
+ 0x41a0,0x41a1,0x41a2,0x41a3,0x41a4,0x41a5,0x41a6,0x41a7,
+ 0x41a8,0x41a9,0x41aa,0x41ab,0x41ac,0x41ad,0x41ae,0x41af,
+ 0x41b0,0x41b1,0x41b2,0x41b3,0x41b4,0x41b5,0x41b6,0x41b7,
+ 0x41b8,0x41b9,0x41ba,0x41bb,0x41bc,0x41bd,0x41be,0x41bf,
+ 0x41c0,0x41c1,0x41c2,0x41c3,0x41c4,0x41c5,0x41c6,0x41c7,
+ 0x41c8,0x41c9,0x41ca,0x41cb,0x41cc,0x41cd,0x41ce,0x41cf,
+ 0x41d0,0x41d1,0x41d2,0x41d3,0x41d4,0x41d5,0x41d6,0x41d7,
+ 0x41d8,0x41d9,0x41da,0x41db,0x41dc,0x41dd,0x41de,0x41df,
+ 0x41e0,0x41e1,0x41e2,0x41e3,0x41e4,0x41e5,0x41e6,0x41e7,
+ 0x41e8,0x41e9,0x41ea,0x41eb,0x41ec,0x41ed,0x41ee,0x41ef,
+ 0x41f0,0x41f1,0x41f2,0x41f3,0x41f4,0x41f5,0x41f6,0x41f7,
+ 0x41f8,0x41f9,0x41fa,0x41fb,0x41fc,0x41fd,0x41fe,0x41ff,
+ 0x4200,0x4201,0x4202,0x4203,0x4204,0x4205,0x4206,0x4207,
+ 0x4208,0x4209,0x420a,0x420b,0x420c,0x420d,0x420e,0x420f,
+ 0x4210,0x4211,0x4212,0x4213,0x4214,0x4215,0x4216,0x4217,
+ 0x4218,0x4219,0x421a,0x421b,0x421c,0x421d,0x421e,0x421f,
+ 0x4220,0x4221,0x4222,0x4223,0x4224,0x4225,0x4226,0x4227,
+ 0x4228,0x4229,0x422a,0x422b,0x422c,0x422d,0x422e,0x422f,
+ 0x4230,0x4231,0x4232,0x4233,0x4234,0x4235,0x4236,0x4237,
+ 0x4238,0x4239,0x423a,0x423b,0x423c,0x423d,0x423e,0x423f,
+ 0x4240,0x4241,0x4242,0x4243,0x4244,0x4245,0x4246,0x4247,
+ 0x4248,0x4249,0x424a,0x424b,0x424c,0x424d,0x424e,0x424f,
+ 0x4250,0x4251,0x4252,0x4253,0x4254,0x4255,0x4256,0x4257,
+ 0x4258,0x4259,0x425a,0x425b,0x425c,0x425d,0x425e,0x425f,
+ 0x4260,0x4261,0x4262,0x4263,0x4264,0x4265,0x4266,0x4267,
+ 0x4268,0x4269,0x426a,0x426b,0x426c,0x426d,0x426e,0x426f,
+ 0x4270,0x4271,0x4272,0x4273,0x4274,0x4275,0x4276,0x4277,
+ 0x4278,0x4279,0x427a,0x427b,0x427c,0x427d,0x427e,0x427f,
+ 0x4280,0x4281,0x4282,0x4283,0x4284,0x4285,0x4286,0x4287,
+ 0x4288,0x4289,0x428a,0x428b,0x428c,0x428d,0x428e,0x428f,
+ 0x4290,0x4291,0x4292,0x4293,0x4294,0x4295,0x4296,0x4297,
+ 0x4298,0x4299,0x429a,0x429b,0x429c,0x429d,0x429e,0x429f,
+ 0x42a0,0x42a1,0x42a2,0x42a3,0x42a4,0x42a5,0x42a6,0x42a7,
+ 0x42a8,0x42a9,0x42aa,0x42ab,0x42ac,0x42ad,0x42ae,0x42af,
+ 0x42b0,0x42b1,0x42b2,0x42b3,0x42b4,0x42b5,0x42b6,0x42b7,
+ 0x42b8,0x42b9,0x42ba,0x42bb,0x42bc,0x42bd,0x42be,0x42bf,
+ 0x42c0,0x42c1,0x42c2,0x42c3,0x42c4,0x42c5,0x42c6,0x42c7,
+ 0x42c8,0x42c9,0x42ca,0x42cb,0x42cc,0x42cd,0x42ce,0x42cf,
+ 0x42d0,0x42d1,0x42d2,0x42d3,0x42d4,0x42d5,0x42d6,0x42d7,
+ 0x42d8,0x42d9,0x42da,0x42db,0x42dc,0x42dd,0x42de,0x42df,
+ 0x42e0,0x42e1,0x42e2,0x42e3,0x42e4,0x42e5,0x42e6,0x42e7,
+ 0x42e8,0x42e9,0x42ea,0x42eb,0x42ec,0x42ed,0x42ee,0x42ef,
+ 0x42f0,0x42f1,0x42f2,0x42f3,0x42f4,0x42f5,0x42f6,0x42f7,
+ 0x42f8,0x42f9,0x42fa,0x42fb,0x42fc,0x42fd,0x42fe,0x42ff,
+ 0x4300,0x4301,0x4302,0x4303,0x4304,0x4305,0x4306,0x4307,
+ 0x4308,0x4309,0x430a,0x430b,0x430c,0x430d,0x430e,0x430f,
+ 0x4310,0x4311,0x4312,0x4313,0x4314,0x4315,0x4316,0x4317,
+ 0x4318,0x4319,0x431a,0x431b,0x431c,0x431d,0x431e,0x431f,
+ 0x4320,0x4321,0x4322,0x4323,0x4324,0x4325,0x4326,0x4327,
+ 0x4328,0x4329,0x432a,0x432b,0x432c,0x432d,0x432e,0x432f,
+ 0x4330,0x4331,0x4332,0x4333,0x4334,0x4335,0x4336,0x4337,
+ 0x4338,0x4339,0x433a,0x433b,0x433c,0x433d,0x433e,0x433f,
+ 0x4340,0x4341,0x4342,0x4343,0x4344,0x4345,0x4346,0x4347,
+ 0x4348,0x4349,0x434a,0x434b,0x434c,0x434d,0x434e,0x434f,
+ 0x4350,0x4351,0x4352,0x4353,0x4354,0x4355,0x4356,0x4357,
+ 0x4358,0x4359,0x435a,0x435b,0x435c,0x435d,0x435e,0x435f,
+ 0x4360,0x4361,0x4362,0x4363,0x4364,0x4365,0x4366,0x4367,
+ 0x4368,0x4369,0x436a,0x436b,0x436c,0x436d,0x436e,0x436f,
+ 0x4370,0x4371,0x4372,0x4373,0x4374,0x4375,0x4376,0x4377,
+ 0x4378,0x4379,0x437a,0x437b,0x437c,0x437d,0x437e,0x437f,
+ 0x4380,0x4381,0x4382,0x4383,0x4384,0x4385,0x4386,0x4387,
+ 0x4388,0x4389,0x438a,0x438b,0x438c,0x438d,0x438e,0x438f,
+ 0x4390,0x4391,0x4392,0x4393,0x4394,0x4395,0x4396,0x4397,
+ 0x4398,0x4399,0x439a,0x439b,0x439c,0x439d,0x439e,0x439f,
+ 0x43a0,0x43a1,0x43a2,0x43a3,0x43a4,0x43a5,0x43a6,0x43a7,
+ 0x43a8,0x43a9,0x43aa,0x43ab,0x43ac,0x43ad,0x43ae,0x43af,
+ 0x43b0,0x43b1,0x43b2,0x43b3,0x43b4,0x43b5,0x43b6,0x43b7,
+ 0x43b8,0x43b9,0x43ba,0x43bb,0x43bc,0x43bd,0x43be,0x43bf,
+ 0x43c0,0x43c1,0x43c2,0x43c3,0x43c4,0x43c5,0x43c6,0x43c7,
+ 0x43c8,0x43c9,0x43ca,0x43cb,0x43cc,0x43cd,0x43ce,0x43cf,
+ 0x43d0,0x43d1,0x43d2,0x43d3,0x43d4,0x43d5,0x43d6,0x43d7,
+ 0x43d8,0x43d9,0x43da,0x43db,0x43dc,0x43dd,0x43de,0x43df,
+ 0x43e0,0x43e1,0x43e2,0x43e3,0x43e4,0x43e5,0x43e6,0x43e7,
+ 0x43e8,0x43e9,0x43ea,0x43eb,0x43ec,0x43ed,0x43ee,0x43ef,
+ 0x43f0,0x43f1,0x43f2,0x43f3,0x43f4,0x43f5,0x43f6,0x43f7,
+ 0x43f8,0x43f9,0x43fa,0x43fb,0x43fc,0x43fd,0x43fe,0x43ff,
+ 0x4400,0x4401,0x4402,0x4403,0x4404,0x4405,0x4406,0x4407,
+ 0x4408,0x4409,0x440a,0x440b,0x440c,0x440d,0x440e,0x440f,
+ 0x4410,0x4411,0x4412,0x4413,0x4414,0x4415,0x4416,0x4417,
+ 0x4418,0x4419,0x441a,0x441b,0x441c,0x441d,0x441e,0x441f,
+ 0x4420,0x4421,0x4422,0x4423,0x4424,0x4425,0x4426,0x4427,
+ 0x4428,0x4429,0x442a,0x442b,0x442c,0x442d,0x442e,0x442f,
+ 0x4430,0x4431,0x4432,0x4433,0x4434,0x4435,0x4436,0x4437,
+ 0x4438,0x4439,0x443a,0x443b,0x443c,0x443d,0x443e,0x443f,
+ 0x4440,0x4441,0x4442,0x4443,0x4444,0x4445,0x4446,0x4447,
+ 0x4448,0x4449,0x444a,0x444b,0x444c,0x444d,0x444e,0x444f,
+ 0x4450,0x4451,0x4452,0x4453,0x4454,0x4455,0x4456,0x4457,
+ 0x4458,0x4459,0x445a,0x445b,0x445c,0x445d,0x445e,0x445f,
+ 0x4460,0x4461,0x4462,0x4463,0x4464,0x4465,0x4466,0x4467,
+ 0x4468,0x4469,0x446a,0x446b,0x446c,0x446d,0x446e,0x446f,
+ 0x4470,0x4471,0x4472,0x4473,0x4474,0x4475,0x4476,0x4477,
+ 0x4478,0x4479,0x447a,0x447b,0x447c,0x447d,0x447e,0x447f,
+ 0x4480,0x4481,0x4482,0x4483,0x4484,0x4485,0x4486,0x4487,
+ 0x4488,0x4489,0x448a,0x448b,0x448c,0x448d,0x448e,0x448f,
+ 0x4490,0x4491,0x4492,0x4493,0x4494,0x4495,0x4496,0x4497,
+ 0x4498,0x4499,0x449a,0x449b,0x449c,0x449d,0x449e,0x449f,
+ 0x44a0,0x44a1,0x44a2,0x44a3,0x44a4,0x44a5,0x44a6,0x44a7,
+ 0x44a8,0x44a9,0x44aa,0x44ab,0x44ac,0x44ad,0x44ae,0x44af,
+ 0x44b0,0x44b1,0x44b2,0x44b3,0x44b4,0x44b5,0x44b6,0x44b7,
+ 0x44b8,0x44b9,0x44ba,0x44bb,0x44bc,0x44bd,0x44be,0x44bf,
+ 0x44c0,0x44c1,0x44c2,0x44c3,0x44c4,0x44c5,0x44c6,0x44c7,
+ 0x44c8,0x44c9,0x44ca,0x44cb,0x44cc,0x44cd,0x44ce,0x44cf,
+ 0x44d0,0x44d1,0x44d2,0x44d3,0x44d4,0x44d5,0x44d6,0x44d7,
+ 0x44d8,0x44d9,0x44da,0x44db,0x44dc,0x44dd,0x44de,0x44df,
+ 0x44e0,0x44e1,0x44e2,0x44e3,0x44e4,0x44e5,0x44e6,0x44e7,
+ 0x44e8,0x44e9,0x44ea,0x44eb,0x44ec,0x44ed,0x44ee,0x44ef,
+ 0x44f0,0x44f1,0x44f2,0x44f3,0x44f4,0x44f5,0x44f6,0x44f7,
+ 0x44f8,0x44f9,0x44fa,0x44fb,0x44fc,0x44fd,0x44fe,0x44ff,
+ 0x4500,0x4501,0x4502,0x4503,0x4504,0x4505,0x4506,0x4507,
+ 0x4508,0x4509,0x450a,0x450b,0x450c,0x450d,0x450e,0x450f,
+ 0x4510,0x4511,0x4512,0x4513,0x4514,0x4515,0x4516,0x4517,
+ 0x4518,0x4519,0x451a,0x451b,0x451c,0x451d,0x451e,0x451f,
+ 0x4520,0x4521,0x4522,0x4523,0x4524,0x4525,0x4526,0x4527,
+ 0x4528,0x4529,0x452a,0x452b,0x452c,0x452d,0x452e,0x452f,
+ 0x4530,0x4531,0x4532,0x4533,0x4534,0x4535,0x4536,0x4537,
+ 0x4538,0x4539,0x453a,0x453b,0x453c,0x453d,0x453e,0x453f,
+ 0x4540,0x4541,0x4542,0x4543,0x4544,0x4545,0x4546,0x4547,
+ 0x4548,0x4549,0x454a,0x454b,0x454c,0x454d,0x454e,0x454f,
+ 0x4550,0x4551,0x4552,0x4553,0x4554,0x4555,0x4556,0x4557,
+ 0x4558,0x4559,0x455a,0x455b,0x455c,0x455d,0x455e,0x455f,
+ 0x4560,0x4561,0x4562,0x4563,0x4564,0x4565,0x4566,0x4567,
+ 0x4568,0x4569,0x456a,0x456b,0x456c,0x456d,0x456e,0x456f,
+ 0x4570,0x4571,0x4572,0x4573,0x4574,0x4575,0x4576,0x4577,
+ 0x4578,0x4579,0x457a,0x457b,0x457c,0x457d,0x457e,0x457f,
+ 0x4580,0x4581,0x4582,0x4583,0x4584,0x4585,0x4586,0x4587,
+ 0x4588,0x4589,0x458a,0x458b,0x458c,0x458d,0x458e,0x458f,
+ 0x4590,0x4591,0x4592,0x4593,0x4594,0x4595,0x4596,0x4597,
+ 0x4598,0x4599,0x459a,0x459b,0x459c,0x459d,0x459e,0x459f,
+ 0x45a0,0x45a1,0x45a2,0x45a3,0x45a4,0x45a5,0x45a6,0x45a7,
+ 0x45a8,0x45a9,0x45aa,0x45ab,0x45ac,0x45ad,0x45ae,0x45af,
+ 0x45b0,0x45b1,0x45b2,0x45b3,0x45b4,0x45b5,0x45b6,0x45b7,
+ 0x45b8,0x45b9,0x45ba,0x45bb,0x45bc,0x45bd,0x45be,0x45bf,
+ 0x45c0,0x45c1,0x45c2,0x45c3,0x45c4,0x45c5,0x45c6,0x45c7,
+ 0x45c8,0x45c9,0x45ca,0x45cb,0x45cc,0x45cd,0x45ce,0x45cf,
+ 0x45d0,0x45d1,0x45d2,0x45d3,0x45d4,0x45d5,0x45d6,0x45d7,
+ 0x45d8,0x45d9,0x45da,0x45db,0x45dc,0x45dd,0x45de,0x45df,
+ 0x45e0,0x45e1,0x45e2,0x45e3,0x45e4,0x45e5,0x45e6,0x45e7,
+ 0x45e8,0x45e9,0x45ea,0x45eb,0x45ec,0x45ed,0x45ee,0x45ef,
+ 0x45f0,0x45f1,0x45f2,0x45f3,0x45f4,0x45f5,0x45f6,0x45f7,
+ 0x45f8,0x45f9,0x45fa,0x45fb,0x45fc,0x45fd,0x45fe,0x45ff,
+ 0x4600,0x4601,0x4602,0x4603,0x4604,0x4605,0x4606,0x4607,
+ 0x4608,0x4609,0x460a,0x460b,0x460c,0x460d,0x460e,0x460f,
+ 0x4610,0x4611,0x4612,0x4613,0x4614,0x4615,0x4616,0x4617,
+ 0x4618,0x4619,0x461a,0x461b,0x461c,0x461d,0x461e,0x461f,
+ 0x4620,0x4621,0x4622,0x4623,0x4624,0x4625,0x4626,0x4627,
+ 0x4628,0x4629,0x462a,0x462b,0x462c,0x462d,0x462e,0x462f,
+ 0x4630,0x4631,0x4632,0x4633,0x4634,0x4635,0x4636,0x4637,
+ 0x4638,0x4639,0x463a,0x463b,0x463c,0x463d,0x463e,0x463f,
+ 0x4640,0x4641,0x4642,0x4643,0x4644,0x4645,0x4646,0x4647,
+ 0x4648,0x4649,0x464a,0x464b,0x464c,0x464d,0x464e,0x464f,
+ 0x4650,0x4651,0x4652,0x4653,0x4654,0x4655,0x4656,0x4657,
+ 0x4658,0x4659,0x465a,0x465b,0x465c,0x465d,0x465e,0x465f,
+ 0x4660,0x4661,0x4662,0x4663,0x4664,0x4665,0x4666,0x4667,
+ 0x4668,0x4669,0x466a,0x466b,0x466c,0x466d,0x466e,0x466f,
+ 0x4670,0x4671,0x4672,0x4673,0x4674,0x4675,0x4676,0x4677,
+ 0x4678,0x4679,0x467a,0x467b,0x467c,0x467d,0x467e,0x467f,
+ 0x4680,0x4681,0x4682,0x4683,0x4684,0x4685,0x4686,0x4687,
+ 0x4688,0x4689,0x468a,0x468b,0x468c,0x468d,0x468e,0x468f,
+ 0x4690,0x4691,0x4692,0x4693,0x4694,0x4695,0x4696,0x4697,
+ 0x4698,0x4699,0x469a,0x469b,0x469c,0x469d,0x469e,0x469f,
+ 0x46a0,0x46a1,0x46a2,0x46a3,0x46a4,0x46a5,0x46a6,0x46a7,
+ 0x46a8,0x46a9,0x46aa,0x46ab,0x46ac,0x46ad,0x46ae,0x46af,
+ 0x46b0,0x46b1,0x46b2,0x46b3,0x46b4,0x46b5,0x46b6,0x46b7,
+ 0x46b8,0x46b9,0x46ba,0x46bb,0x46bc,0x46bd,0x46be,0x46bf,
+ 0x46c0,0x46c1,0x46c2,0x46c3,0x46c4,0x46c5,0x46c6,0x46c7,
+ 0x46c8,0x46c9,0x46ca,0x46cb,0x46cc,0x46cd,0x46ce,0x46cf,
+ 0x46d0,0x46d1,0x46d2,0x46d3,0x46d4,0x46d5,0x46d6,0x46d7,
+ 0x46d8,0x46d9,0x46da,0x46db,0x46dc,0x46dd,0x46de,0x46df,
+ 0x46e0,0x46e1,0x46e2,0x46e3,0x46e4,0x46e5,0x46e6,0x46e7,
+ 0x46e8,0x46e9,0x46ea,0x46eb,0x46ec,0x46ed,0x46ee,0x46ef,
+ 0x46f0,0x46f1,0x46f2,0x46f3,0x46f4,0x46f5,0x46f6,0x46f7,
+ 0x46f8,0x46f9,0x46fa,0x46fb,0x46fc,0x46fd,0x46fe,0x46ff,
+ 0x4700,0x4701,0x4702,0x4703,0x4704,0x4705,0x4706,0x4707,
+ 0x4708,0x4709,0x470a,0x470b,0x470c,0x470d,0x470e,0x470f,
+ 0x4710,0x4711,0x4712,0x4713,0x4714,0x4715,0x4716,0x4717,
+ 0x4718,0x4719,0x471a,0x471b,0x471c,0x471d,0x471e,0x471f,
+ 0x4720,0x4721,0x4722,0x4723,0x4724,0x4725,0x4726,0x4727,
+ 0x4728,0x4729,0x472a,0x472b,0x472c,0x472d,0x472e,0x472f,
+ 0x4730,0x4731,0x4732,0x4733,0x4734,0x4735,0x4736,0x4737,
+ 0x4738,0x4739,0x473a,0x473b,0x473c,0x473d,0x473e,0x473f,
+ 0x4740,0x4741,0x4742,0x4743,0x4744,0x4745,0x4746,0x4747,
+ 0x4748,0x4749,0x474a,0x474b,0x474c,0x474d,0x474e,0x474f,
+ 0x4750,0x4751,0x4752,0x4753,0x4754,0x4755,0x4756,0x4757,
+ 0x4758,0x4759,0x475a,0x475b,0x475c,0x475d,0x475e,0x475f,
+ 0x4760,0x4761,0x4762,0x4763,0x4764,0x4765,0x4766,0x4767,
+ 0x4768,0x4769,0x476a,0x476b,0x476c,0x476d,0x476e,0x476f,
+ 0x4770,0x4771,0x4772,0x4773,0x4774,0x4775,0x4776,0x4777,
+ 0x4778,0x4779,0x477a,0x477b,0x477c,0x477d,0x477e,0x477f,
+ 0x4780,0x4781,0x4782,0x4783,0x4784,0x4785,0x4786,0x4787,
+ 0x4788,0x4789,0x478a,0x478b,0x478c,0x478d,0x478e,0x478f,
+ 0x4790,0x4791,0x4792,0x4793,0x4794,0x4795,0x4796,0x4797,
+ 0x4798,0x4799,0x479a,0x479b,0x479c,0x479d,0x479e,0x479f,
+ 0x47a0,0x47a1,0x47a2,0x47a3,0x47a4,0x47a5,0x47a6,0x47a7,
+ 0x47a8,0x47a9,0x47aa,0x47ab,0x47ac,0x47ad,0x47ae,0x47af,
+ 0x47b0,0x47b1,0x47b2,0x47b3,0x47b4,0x47b5,0x47b6,0x47b7,
+ 0x47b8,0x47b9,0x47ba,0x47bb,0x47bc,0x47bd,0x47be,0x47bf,
+ 0x47c0,0x47c1,0x47c2,0x47c3,0x47c4,0x47c5,0x47c6,0x47c7,
+ 0x47c8,0x47c9,0x47ca,0x47cb,0x47cc,0x47cd,0x47ce,0x47cf,
+ 0x47d0,0x47d1,0x47d2,0x47d3,0x47d4,0x47d5,0x47d6,0x47d7,
+ 0x47d8,0x47d9,0x47da,0x47db,0x47dc,0x47dd,0x47de,0x47df,
+ 0x47e0,0x47e1,0x47e2,0x47e3,0x47e4,0x47e5,0x47e6,0x47e7,
+ 0x47e8,0x47e9,0x47ea,0x47eb,0x47ec,0x47ed,0x47ee,0x47ef,
+ 0x47f0,0x47f1,0x47f2,0x47f3,0x47f4,0x47f5,0x47f6,0x47f7,
+ 0x47f8,0x47f9,0x47fa,0x47fb,0x47fc,0x47fd,0x47fe,0x47ff,
+ 0x4800,0x4801,0x4802,0x4803,0x4804,0x4805,0x4806,0x4807,
+ 0x4808,0x4809,0x480a,0x480b,0x480c,0x480d,0x480e,0x480f,
+ 0x4810,0x4811,0x4812,0x4813,0x4814,0x4815,0x4816,0x4817,
+ 0x4818,0x4819,0x481a,0x481b,0x481c,0x481d,0x481e,0x481f,
+ 0x4820,0x4821,0x4822,0x4823,0x4824,0x4825,0x4826,0x4827,
+ 0x4828,0x4829,0x482a,0x482b,0x482c,0x482d,0x482e,0x482f,
+ 0x4830,0x4831,0x4832,0x4833,0x4834,0x4835,0x4836,0x4837,
+ 0x4838,0x4839,0x483a,0x483b,0x483c,0x483d,0x483e,0x483f,
+ 0x4840,0x4841,0x4842,0x4843,0x4844,0x4845,0x4846,0x4847,
+ 0x4848,0x4849,0x484a,0x484b,0x484c,0x484d,0x484e,0x484f,
+ 0x4850,0x4851,0x4852,0x4853,0x4854,0x4855,0x4856,0x4857,
+ 0x4858,0x4859,0x485a,0x485b,0x485c,0x485d,0x485e,0x485f,
+ 0x4860,0x4861,0x4862,0x4863,0x4864,0x4865,0x4866,0x4867,
+ 0x4868,0x4869,0x486a,0x486b,0x486c,0x486d,0x486e,0x486f,
+ 0x4870,0x4871,0x4872,0x4873,0x4874,0x4875,0x4876,0x4877,
+ 0x4878,0x4879,0x487a,0x487b,0x487c,0x487d,0x487e,0x487f,
+ 0x4880,0x4881,0x4882,0x4883,0x4884,0x4885,0x4886,0x4887,
+ 0x4888,0x4889,0x488a,0x488b,0x488c,0x488d,0x488e,0x488f,
+ 0x4890,0x4891,0x4892,0x4893,0x4894,0x4895,0x4896,0x4897,
+ 0x4898,0x4899,0x489a,0x489b,0x489c,0x489d,0x489e,0x489f,
+ 0x48a0,0x48a1,0x48a2,0x48a3,0x48a4,0x48a5,0x48a6,0x48a7,
+ 0x48a8,0x48a9,0x48aa,0x48ab,0x48ac,0x48ad,0x48ae,0x48af,
+ 0x48b0,0x48b1,0x48b2,0x48b3,0x48b4,0x48b5,0x48b6,0x48b7,
+ 0x48b8,0x48b9,0x48ba,0x48bb,0x48bc,0x48bd,0x48be,0x48bf,
+ 0x48c0,0x48c1,0x48c2,0x48c3,0x48c4,0x48c5,0x48c6,0x48c7,
+ 0x48c8,0x48c9,0x48ca,0x48cb,0x48cc,0x48cd,0x48ce,0x48cf,
+ 0x48d0,0x48d1,0x48d2,0x48d3,0x48d4,0x48d5,0x48d6,0x48d7,
+ 0x48d8,0x48d9,0x48da,0x48db,0x48dc,0x48dd,0x48de,0x48df,
+ 0x48e0,0x48e1,0x48e2,0x48e3,0x48e4,0x48e5,0x48e6,0x48e7,
+ 0x48e8,0x48e9,0x48ea,0x48eb,0x48ec,0x48ed,0x48ee,0x48ef,
+ 0x48f0,0x48f1,0x48f2,0x48f3,0x48f4,0x48f5,0x48f6,0x48f7,
+ 0x48f8,0x48f9,0x48fa,0x48fb,0x48fc,0x48fd,0x48fe,0x48ff,
+ 0x4900,0x4901,0x4902,0x4903,0x4904,0x4905,0x4906,0x4907,
+ 0x4908,0x4909,0x490a,0x490b,0x490c,0x490d,0x490e,0x490f,
+ 0x4910,0x4911,0x4912,0x4913,0x4914,0x4915,0x4916,0x4917,
+ 0x4918,0x4919,0x491a,0x491b,0x491c,0x491d,0x491e,0x491f,
+ 0x4920,0x4921,0x4922,0x4923,0x4924,0x4925,0x4926,0x4927,
+ 0x4928,0x4929,0x492a,0x492b,0x492c,0x492d,0x492e,0x492f,
+ 0x4930,0x4931,0x4932,0x4933,0x4934,0x4935,0x4936,0x4937,
+ 0x4938,0x4939,0x493a,0x493b,0x493c,0x493d,0x493e,0x493f,
+ 0x4940,0x4941,0x4942,0x4943,0x4944,0x4945,0x4946,0x4947,
+ 0x4948,0x4949,0x494a,0x494b,0x494c,0x494d,0x494e,0x494f,
+ 0x4950,0x4951,0x4952,0x4953,0x4954,0x4955,0x4956,0x4957,
+ 0x4958,0x4959,0x495a,0x495b,0x495c,0x495d,0x495e,0x495f,
+ 0x4960,0x4961,0x4962,0x4963,0x4964,0x4965,0x4966,0x4967,
+ 0x4968,0x4969,0x496a,0x496b,0x496c,0x496d,0x496e,0x496f,
+ 0x4970,0x4971,0x4972,0x4973,0x4974,0x4975,0x4976,0x4977,
+ 0x4978,0x4979,0x497a,0x497b,0x497c,0x497d,0x497e,0x497f,
+ 0x4980,0x4981,0x4982,0x4983,0x4984,0x4985,0x4986,0x4987,
+ 0x4988,0x4989,0x498a,0x498b,0x498c,0x498d,0x498e,0x498f,
+ 0x4990,0x4991,0x4992,0x4993,0x4994,0x4995,0x4996,0x4997,
+ 0x4998,0x4999,0x499a,0x499b,0x499c,0x499d,0x499e,0x499f,
+ 0x49a0,0x49a1,0x49a2,0x49a3,0x49a4,0x49a5,0x49a6,0x49a7,
+ 0x49a8,0x49a9,0x49aa,0x49ab,0x49ac,0x49ad,0x49ae,0x49af,
+ 0x49b0,0x49b1,0x49b2,0x49b3,0x49b4,0x49b5,0x49b6,0x49b7,
+ 0x49b8,0x49b9,0x49ba,0x49bb,0x49bc,0x49bd,0x49be,0x49bf,
+ 0x49c0,0x49c1,0x49c2,0x49c3,0x49c4,0x49c5,0x49c6,0x49c7,
+ 0x49c8,0x49c9,0x49ca,0x49cb,0x49cc,0x49cd,0x49ce,0x49cf,
+ 0x49d0,0x49d1,0x49d2,0x49d3,0x49d4,0x49d5,0x49d6,0x49d7,
+ 0x49d8,0x49d9,0x49da,0x49db,0x49dc,0x49dd,0x49de,0x49df,
+ 0x49e0,0x49e1,0x49e2,0x49e3,0x49e4,0x49e5,0x49e6,0x49e7,
+ 0x49e8,0x49e9,0x49ea,0x49eb,0x49ec,0x49ed,0x49ee,0x49ef,
+ 0x49f0,0x49f1,0x49f2,0x49f3,0x49f4,0x49f5,0x49f6,0x49f7,
+ 0x49f8,0x49f9,0x49fa,0x49fb,0x49fc,0x49fd,0x49fe,0x49ff,
+ 0x4a00,0x4a01,0x4a02,0x4a03,0x4a04,0x4a05,0x4a06,0x4a07,
+ 0x4a08,0x4a09,0x4a0a,0x4a0b,0x4a0c,0x4a0d,0x4a0e,0x4a0f,
+ 0x4a10,0x4a11,0x4a12,0x4a13,0x4a14,0x4a15,0x4a16,0x4a17,
+ 0x4a18,0x4a19,0x4a1a,0x4a1b,0x4a1c,0x4a1d,0x4a1e,0x4a1f,
+ 0x4a20,0x4a21,0x4a22,0x4a23,0x4a24,0x4a25,0x4a26,0x4a27,
+ 0x4a28,0x4a29,0x4a2a,0x4a2b,0x4a2c,0x4a2d,0x4a2e,0x4a2f,
+ 0x4a30,0x4a31,0x4a32,0x4a33,0x4a34,0x4a35,0x4a36,0x4a37,
+ 0x4a38,0x4a39,0x4a3a,0x4a3b,0x4a3c,0x4a3d,0x4a3e,0x4a3f,
+ 0x4a40,0x4a41,0x4a42,0x4a43,0x4a44,0x4a45,0x4a46,0x4a47,
+ 0x4a48,0x4a49,0x4a4a,0x4a4b,0x4a4c,0x4a4d,0x4a4e,0x4a4f,
+ 0x4a50,0x4a51,0x4a52,0x4a53,0x4a54,0x4a55,0x4a56,0x4a57,
+ 0x4a58,0x4a59,0x4a5a,0x4a5b,0x4a5c,0x4a5d,0x4a5e,0x4a5f,
+ 0x4a60,0x4a61,0x4a62,0x4a63,0x4a64,0x4a65,0x4a66,0x4a67,
+ 0x4a68,0x4a69,0x4a6a,0x4a6b,0x4a6c,0x4a6d,0x4a6e,0x4a6f,
+ 0x4a70,0x4a71,0x4a72,0x4a73,0x4a74,0x4a75,0x4a76,0x4a77,
+ 0x4a78,0x4a79,0x4a7a,0x4a7b,0x4a7c,0x4a7d,0x4a7e,0x4a7f,
+ 0x4a80,0x4a81,0x4a82,0x4a83,0x4a84,0x4a85,0x4a86,0x4a87,
+ 0x4a88,0x4a89,0x4a8a,0x4a8b,0x4a8c,0x4a8d,0x4a8e,0x4a8f,
+ 0x4a90,0x4a91,0x4a92,0x4a93,0x4a94,0x4a95,0x4a96,0x4a97,
+ 0x4a98,0x4a99,0x4a9a,0x4a9b,0x4a9c,0x4a9d,0x4a9e,0x4a9f,
+ 0x4aa0,0x4aa1,0x4aa2,0x4aa3,0x4aa4,0x4aa5,0x4aa6,0x4aa7,
+ 0x4aa8,0x4aa9,0x4aaa,0x4aab,0x4aac,0x4aad,0x4aae,0x4aaf,
+ 0x4ab0,0x4ab1,0x4ab2,0x4ab3,0x4ab4,0x4ab5,0x4ab6,0x4ab7,
+ 0x4ab8,0x4ab9,0x4aba,0x4abb,0x4abc,0x4abd,0x4abe,0x4abf,
+ 0x4ac0,0x4ac1,0x4ac2,0x4ac3,0x4ac4,0x4ac5,0x4ac6,0x4ac7,
+ 0x4ac8,0x4ac9,0x4aca,0x4acb,0x4acc,0x4acd,0x4ace,0x4acf,
+ 0x4ad0,0x4ad1,0x4ad2,0x4ad3,0x4ad4,0x4ad5,0x4ad6,0x4ad7,
+ 0x4ad8,0x4ad9,0x4ada,0x4adb,0x4adc,0x4add,0x4ade,0x4adf,
+ 0x4ae0,0x4ae1,0x4ae2,0x4ae3,0x4ae4,0x4ae5,0x4ae6,0x4ae7,
+ 0x4ae8,0x4ae9,0x4aea,0x4aeb,0x4aec,0x4aed,0x4aee,0x4aef,
+ 0x4af0,0x4af1,0x4af2,0x4af3,0x4af4,0x4af5,0x4af6,0x4af7,
+ 0x4af8,0x4af9,0x4afa,0x4afb,0x4afc,0x4afd,0x4afe,0x4aff,
+ 0x4b00,0x4b01,0x4b02,0x4b03,0x4b04,0x4b05,0x4b06,0x4b07,
+ 0x4b08,0x4b09,0x4b0a,0x4b0b,0x4b0c,0x4b0d,0x4b0e,0x4b0f,
+ 0x4b10,0x4b11,0x4b12,0x4b13,0x4b14,0x4b15,0x4b16,0x4b17,
+ 0x4b18,0x4b19,0x4b1a,0x4b1b,0x4b1c,0x4b1d,0x4b1e,0x4b1f,
+ 0x4b20,0x4b21,0x4b22,0x4b23,0x4b24,0x4b25,0x4b26,0x4b27,
+ 0x4b28,0x4b29,0x4b2a,0x4b2b,0x4b2c,0x4b2d,0x4b2e,0x4b2f,
+ 0x4b30,0x4b31,0x4b32,0x4b33,0x4b34,0x4b35,0x4b36,0x4b37,
+ 0x4b38,0x4b39,0x4b3a,0x4b3b,0x4b3c,0x4b3d,0x4b3e,0x4b3f,
+ 0x4b40,0x4b41,0x4b42,0x4b43,0x4b44,0x4b45,0x4b46,0x4b47,
+ 0x4b48,0x4b49,0x4b4a,0x4b4b,0x4b4c,0x4b4d,0x4b4e,0x4b4f,
+ 0x4b50,0x4b51,0x4b52,0x4b53,0x4b54,0x4b55,0x4b56,0x4b57,
+ 0x4b58,0x4b59,0x4b5a,0x4b5b,0x4b5c,0x4b5d,0x4b5e,0x4b5f,
+ 0x4b60,0x4b61,0x4b62,0x4b63,0x4b64,0x4b65,0x4b66,0x4b67,
+ 0x4b68,0x4b69,0x4b6a,0x4b6b,0x4b6c,0x4b6d,0x4b6e,0x4b6f,
+ 0x4b70,0x4b71,0x4b72,0x4b73,0x4b74,0x4b75,0x4b76,0x4b77,
+ 0x4b78,0x4b79,0x4b7a,0x4b7b,0x4b7c,0x4b7d,0x4b7e,0x4b7f,
+ 0x4b80,0x4b81,0x4b82,0x4b83,0x4b84,0x4b85,0x4b86,0x4b87,
+ 0x4b88,0x4b89,0x4b8a,0x4b8b,0x4b8c,0x4b8d,0x4b8e,0x4b8f,
+ 0x4b90,0x4b91,0x4b92,0x4b93,0x4b94,0x4b95,0x4b96,0x4b97,
+ 0x4b98,0x4b99,0x4b9a,0x4b9b,0x4b9c,0x4b9d,0x4b9e,0x4b9f,
+ 0x4ba0,0x4ba1,0x4ba2,0x4ba3,0x4ba4,0x4ba5,0x4ba6,0x4ba7,
+ 0x4ba8,0x4ba9,0x4baa,0x4bab,0x4bac,0x4bad,0x4bae,0x4baf,
+ 0x4bb0,0x4bb1,0x4bb2,0x4bb3,0x4bb4,0x4bb5,0x4bb6,0x4bb7,
+ 0x4bb8,0x4bb9,0x4bba,0x4bbb,0x4bbc,0x4bbd,0x4bbe,0x4bbf,
+ 0x4bc0,0x4bc1,0x4bc2,0x4bc3,0x4bc4,0x4bc5,0x4bc6,0x4bc7,
+ 0x4bc8,0x4bc9,0x4bca,0x4bcb,0x4bcc,0x4bcd,0x4bce,0x4bcf,
+ 0x4bd0,0x4bd1,0x4bd2,0x4bd3,0x4bd4,0x4bd5,0x4bd6,0x4bd7,
+ 0x4bd8,0x4bd9,0x4bda,0x4bdb,0x4bdc,0x4bdd,0x4bde,0x4bdf,
+ 0x4be0,0x4be1,0x4be2,0x4be3,0x4be4,0x4be5,0x4be6,0x4be7,
+ 0x4be8,0x4be9,0x4bea,0x4beb,0x4bec,0x4bed,0x4bee,0x4bef,
+ 0x4bf0,0x4bf1,0x4bf2,0x4bf3,0x4bf4,0x4bf5,0x4bf6,0x4bf7,
+ 0x4bf8,0x4bf9,0x4bfa,0x4bfb,0x4bfc,0x4bfd,0x4bfe,0x4bff,
+ 0x4c00,0x4c01,0x4c02,0x4c03,0x4c04,0x4c05,0x4c06,0x4c07,
+ 0x4c08,0x4c09,0x4c0a,0x4c0b,0x4c0c,0x4c0d,0x4c0e,0x4c0f,
+ 0x4c10,0x4c11,0x4c12,0x4c13,0x4c14,0x4c15,0x4c16,0x4c17,
+ 0x4c18,0x4c19,0x4c1a,0x4c1b,0x4c1c,0x4c1d,0x4c1e,0x4c1f,
+ 0x4c20,0x4c21,0x4c22,0x4c23,0x4c24,0x4c25,0x4c26,0x4c27,
+ 0x4c28,0x4c29,0x4c2a,0x4c2b,0x4c2c,0x4c2d,0x4c2e,0x4c2f,
+ 0x4c30,0x4c31,0x4c32,0x4c33,0x4c34,0x4c35,0x4c36,0x4c37,
+ 0x4c38,0x4c39,0x4c3a,0x4c3b,0x4c3c,0x4c3d,0x4c3e,0x4c3f,
+ 0x4c40,0x4c41,0x4c42,0x4c43,0x4c44,0x4c45,0x4c46,0x4c47,
+ 0x4c48,0x4c49,0x4c4a,0x4c4b,0x4c4c,0x4c4d,0x4c4e,0x4c4f,
+ 0x4c50,0x4c51,0x4c52,0x4c53,0x4c54,0x4c55,0x4c56,0x4c57,
+ 0x4c58,0x4c59,0x4c5a,0x4c5b,0x4c5c,0x4c5d,0x4c5e,0x4c5f,
+ 0x4c60,0x4c61,0x4c62,0x4c63,0x4c64,0x4c65,0x4c66,0x4c67,
+ 0x4c68,0x4c69,0x4c6a,0x4c6b,0x4c6c,0x4c6d,0x4c6e,0x4c6f,
+ 0x4c70,0x4c71,0x4c72,0x4c73,0x4c74,0x4c75,0x4c76,0x4c77,
+ 0x4c78,0x4c79,0x4c7a,0x4c7b,0x4c7c,0x4c7d,0x4c7e,0x4c7f,
+ 0x4c80,0x4c81,0x4c82,0x4c83,0x4c84,0x4c85,0x4c86,0x4c87,
+ 0x4c88,0x4c89,0x4c8a,0x4c8b,0x4c8c,0x4c8d,0x4c8e,0x4c8f,
+ 0x4c90,0x4c91,0x4c92,0x4c93,0x4c94,0x4c95,0x4c96,0x4c97,
+ 0x4c98,0x4c99,0x4c9a,0x4c9b,0x4c9c,0x4c9d,0x4c9e,0x4c9f,
+ 0x4ca0,0x4ca1,0x4ca2,0x4ca3,0x4ca4,0x4ca5,0x4ca6,0x4ca7,
+ 0x4ca8,0x4ca9,0x4caa,0x4cab,0x4cac,0x4cad,0x4cae,0x4caf,
+ 0x4cb0,0x4cb1,0x4cb2,0x4cb3,0x4cb4,0x4cb5,0x4cb6,0x4cb7,
+ 0x4cb8,0x4cb9,0x4cba,0x4cbb,0x4cbc,0x4cbd,0x4cbe,0x4cbf,
+ 0x4cc0,0x4cc1,0x4cc2,0x4cc3,0x4cc4,0x4cc5,0x4cc6,0x4cc7,
+ 0x4cc8,0x4cc9,0x4cca,0x4ccb,0x4ccc,0x4ccd,0x4cce,0x4ccf,
+ 0x4cd0,0x4cd1,0x4cd2,0x4cd3,0x4cd4,0x4cd5,0x4cd6,0x4cd7,
+ 0x4cd8,0x4cd9,0x4cda,0x4cdb,0x4cdc,0x4cdd,0x4cde,0x4cdf,
+ 0x4ce0,0x4ce1,0x4ce2,0x4ce3,0x4ce4,0x4ce5,0x4ce6,0x4ce7,
+ 0x4ce8,0x4ce9,0x4cea,0x4ceb,0x4cec,0x4ced,0x4cee,0x4cef,
+ 0x4cf0,0x4cf1,0x4cf2,0x4cf3,0x4cf4,0x4cf5,0x4cf6,0x4cf7,
+ 0x4cf8,0x4cf9,0x4cfa,0x4cfb,0x4cfc,0x4cfd,0x4cfe,0x4cff,
+ 0x4d00,0x4d01,0x4d02,0x4d03,0x4d04,0x4d05,0x4d06,0x4d07,
+ 0x4d08,0x4d09,0x4d0a,0x4d0b,0x4d0c,0x4d0d,0x4d0e,0x4d0f,
+ 0x4d10,0x4d11,0x4d12,0x4d13,0x4d14,0x4d15,0x4d16,0x4d17,
+ 0x4d18,0x4d19,0x4d1a,0x4d1b,0x4d1c,0x4d1d,0x4d1e,0x4d1f,
+ 0x4d20,0x4d21,0x4d22,0x4d23,0x4d24,0x4d25,0x4d26,0x4d27,
+ 0x4d28,0x4d29,0x4d2a,0x4d2b,0x4d2c,0x4d2d,0x4d2e,0x4d2f,
+ 0x4d30,0x4d31,0x4d32,0x4d33,0x4d34,0x4d35,0x4d36,0x4d37,
+ 0x4d38,0x4d39,0x4d3a,0x4d3b,0x4d3c,0x4d3d,0x4d3e,0x4d3f,
+ 0x4d40,0x4d41,0x4d42,0x4d43,0x4d44,0x4d45,0x4d46,0x4d47,
+ 0x4d48,0x4d49,0x4d4a,0x4d4b,0x4d4c,0x4d4d,0x4d4e,0x4d4f,
+ 0x4d50,0x4d51,0x4d52,0x4d53,0x4d54,0x4d55,0x4d56,0x4d57,
+ 0x4d58,0x4d59,0x4d5a,0x4d5b,0x4d5c,0x4d5d,0x4d5e,0x4d5f,
+ 0x4d60,0x4d61,0x4d62,0x4d63,0x4d64,0x4d65,0x4d66,0x4d67,
+ 0x4d68,0x4d69,0x4d6a,0x4d6b,0x4d6c,0x4d6d,0x4d6e,0x4d6f,
+ 0x4d70,0x4d71,0x4d72,0x4d73,0x4d74,0x4d75,0x4d76,0x4d77,
+ 0x4d78,0x4d79,0x4d7a,0x4d7b,0x4d7c,0x4d7d,0x4d7e,0x4d7f,
+ 0x4d80,0x4d81,0x4d82,0x4d83,0x4d84,0x4d85,0x4d86,0x4d87,
+ 0x4d88,0x4d89,0x4d8a,0x4d8b,0x4d8c,0x4d8d,0x4d8e,0x4d8f,
+ 0x4d90,0x4d91,0x4d92,0x4d93,0x4d94,0x4d95,0x4d96,0x4d97,
+ 0x4d98,0x4d99,0x4d9a,0x4d9b,0x4d9c,0x4d9d,0x4d9e,0x4d9f,
+ 0x4da0,0x4da1,0x4da2,0x4da3,0x4da4,0x4da5,0x4da6,0x4da7,
+ 0x4da8,0x4da9,0x4daa,0x4dab,0x4dac,0x4dad,0x4dae,0x4daf,
+ 0x4db0,0x4db1,0x4db2,0x4db3,0x4db4,0x4db5,0x4db6,0x4db7,
+ 0x4db8,0x4db9,0x4dba,0x4dbb,0x4dbc,0x4dbd,0x4dbe,0x4dbf,
+ 0x4dc0,0x4dc1,0x4dc2,0x4dc3,0x4dc4,0x4dc5,0x4dc6,0x4dc7,
+ 0x4dc8,0x4dc9,0x4dca,0x4dcb,0x4dcc,0x4dcd,0x4dce,0x4dcf,
+ 0x4dd0,0x4dd1,0x4dd2,0x4dd3,0x4dd4,0x4dd5,0x4dd6,0x4dd7,
+ 0x4dd8,0x4dd9,0x4dda,0x4ddb,0x4ddc,0x4ddd,0x4dde,0x4ddf,
+ 0x4de0,0x4de1,0x4de2,0x4de3,0x4de4,0x4de5,0x4de6,0x4de7,
+ 0x4de8,0x4de9,0x4dea,0x4deb,0x4dec,0x4ded,0x4dee,0x4def,
+ 0x4df0,0x4df1,0x4df2,0x4df3,0x4df4,0x4df5,0x4df6,0x4df7,
+ 0x4df8,0x4df9,0x4dfa,0x4dfb,0x4dfc,0x4dfd,0x4dfe,0x4dff,
+ 0x4e00,0x4e01,0x4e02,0x4e03,0x4e04,0x4e05,0x4e06,0x4e07,
+ 0x4e08,0x4e09,0x4e0a,0x4e0b,0x4e0c,0x4e0d,0x4e0e,0x4e0f,
+ 0x4e10,0x4e11,0x4e12,0x4e13,0x4e14,0x4e15,0x4e16,0x4e17,
+ 0x4e18,0x4e19,0x4e1a,0x4e1b,0x4e1c,0x4e1d,0x4e1e,0x4e1f,
+ 0x4e20,0x4e21,0x4e22,0x4e23,0x4e24,0x4e25,0x4e26,0x4e27,
+ 0x4e28,0x4e29,0x4e2a,0x4e2b,0x4e2c,0x4e2d,0x4e2e,0x4e2f,
+ 0x4e30,0x4e31,0x4e32,0x4e33,0x4e34,0x4e35,0x4e36,0x4e37,
+ 0x4e38,0x4e39,0x4e3a,0x4e3b,0x4e3c,0x4e3d,0x4e3e,0x4e3f,
+ 0x4e40,0x4e41,0x4e42,0x4e43,0x4e44,0x4e45,0x4e46,0x4e47,
+ 0x4e48,0x4e49,0x4e4a,0x4e4b,0x4e4c,0x4e4d,0x4e4e,0x4e4f,
+ 0x4e50,0x4e51,0x4e52,0x4e53,0x4e54,0x4e55,0x4e56,0x4e57,
+ 0x4e58,0x4e59,0x4e5a,0x4e5b,0x4e5c,0x4e5d,0x4e5e,0x4e5f,
+ 0x4e60,0x4e61,0x4e62,0x4e63,0x4e64,0x4e65,0x4e66,0x4e67,
+ 0x4e68,0x4e69,0x4e6a,0x4e6b,0x4e6c,0x4e6d,0x4e6e,0x4e6f,
+ 0x4e70,0x4e71,0x4e72,0x4e73,0x4e74,0x4e75,0x4e76,0x4e77,
+ 0x4e78,0x4e79,0x4e7a,0x4e7b,0x4e7c,0x4e7d,0x4e7e,0x4e7f,
+ 0x4e80,0x4e81,0x4e82,0x4e83,0x4e84,0x4e85,0x4e86,0x4e87,
+ 0x4e88,0x4e89,0x4e8a,0x4e8b,0x4e8c,0x4e8d,0x4e8e,0x4e8f,
+ 0x4e90,0x4e91,0x4e92,0x4e93,0x4e94,0x4e95,0x4e96,0x4e97,
+ 0x4e98,0x4e99,0x4e9a,0x4e9b,0x4e9c,0x4e9d,0x4e9e,0x4e9f,
+ 0x4ea0,0x4ea1,0x4ea2,0x4ea3,0x4ea4,0x4ea5,0x4ea6,0x4ea7,
+ 0x4ea8,0x4ea9,0x4eaa,0x4eab,0x4eac,0x4ead,0x4eae,0x4eaf,
+ 0x4eb0,0x4eb1,0x4eb2,0x4eb3,0x4eb4,0x4eb5,0x4eb6,0x4eb7,
+ 0x4eb8,0x4eb9,0x4eba,0x4ebb,0x4ebc,0x4ebd,0x4ebe,0x4ebf,
+ 0x4ec0,0x4ec1,0x4ec2,0x4ec3,0x4ec4,0x4ec5,0x4ec6,0x4ec7,
+ 0x4ec8,0x4ec9,0x4eca,0x4ecb,0x4ecc,0x4ecd,0x4ece,0x4ecf,
+ 0x4ed0,0x4ed1,0x4ed2,0x4ed3,0x4ed4,0x4ed5,0x4ed6,0x4ed7,
+ 0x4ed8,0x4ed9,0x4eda,0x4edb,0x4edc,0x4edd,0x4ede,0x4edf,
+ 0x4ee0,0x4ee1,0x4ee2,0x4ee3,0x4ee4,0x4ee5,0x4ee6,0x4ee7,
+ 0x4ee8,0x4ee9,0x4eea,0x4eeb,0x4eec,0x4eed,0x4eee,0x4eef,
+ 0x4ef0,0x4ef1,0x4ef2,0x4ef3,0x4ef4,0x4ef5,0x4ef6,0x4ef7,
+ 0x4ef8,0x4ef9,0x4efa,0x4efb,0x4efc,0x4efd,0x4efe,0x4eff,
+ 0x4f00,0x4f01,0x4f02,0x4f03,0x4f04,0x4f05,0x4f06,0x4f07,
+ 0x4f08,0x4f09,0x4f0a,0x4f0b,0x4f0c,0x4f0d,0x4f0e,0x4f0f,
+ 0x4f10,0x4f11,0x4f12,0x4f13,0x4f14,0x4f15,0x4f16,0x4f17,
+ 0x4f18,0x4f19,0x4f1a,0x4f1b,0x4f1c,0x4f1d,0x4f1e,0x4f1f,
+ 0x4f20,0x4f21,0x4f22,0x4f23,0x4f24,0x4f25,0x4f26,0x4f27,
+ 0x4f28,0x4f29,0x4f2a,0x4f2b,0x4f2c,0x4f2d,0x4f2e,0x4f2f,
+ 0x4f30,0x4f31,0x4f32,0x4f33,0x4f34,0x4f35,0x4f36,0x4f37,
+ 0x4f38,0x4f39,0x4f3a,0x4f3b,0x4f3c,0x4f3d,0x4f3e,0x4f3f,
+ 0x4f40,0x4f41,0x4f42,0x4f43,0x4f44,0x4f45,0x4f46,0x4f47,
+ 0x4f48,0x4f49,0x4f4a,0x4f4b,0x4f4c,0x4f4d,0x4f4e,0x4f4f,
+ 0x4f50,0x4f51,0x4f52,0x4f53,0x4f54,0x4f55,0x4f56,0x4f57,
+ 0x4f58,0x4f59,0x4f5a,0x4f5b,0x4f5c,0x4f5d,0x4f5e,0x4f5f,
+ 0x4f60,0x4f61,0x4f62,0x4f63,0x4f64,0x4f65,0x4f66,0x4f67,
+ 0x4f68,0x4f69,0x4f6a,0x4f6b,0x4f6c,0x4f6d,0x4f6e,0x4f6f,
+ 0x4f70,0x4f71,0x4f72,0x4f73,0x4f74,0x4f75,0x4f76,0x4f77,
+ 0x4f78,0x4f79,0x4f7a,0x4f7b,0x4f7c,0x4f7d,0x4f7e,0x4f7f,
+ 0x4f80,0x4f81,0x4f82,0x4f83,0x4f84,0x4f85,0x4f86,0x4f87,
+ 0x4f88,0x4f89,0x4f8a,0x4f8b,0x4f8c,0x4f8d,0x4f8e,0x4f8f,
+ 0x4f90,0x4f91,0x4f92,0x4f93,0x4f94,0x4f95,0x4f96,0x4f97,
+ 0x4f98,0x4f99,0x4f9a,0x4f9b,0x4f9c,0x4f9d,0x4f9e,0x4f9f,
+ 0x4fa0,0x4fa1,0x4fa2,0x4fa3,0x4fa4,0x4fa5,0x4fa6,0x4fa7,
+ 0x4fa8,0x4fa9,0x4faa,0x4fab,0x4fac,0x4fad,0x4fae,0x4faf,
+ 0x4fb0,0x4fb1,0x4fb2,0x4fb3,0x4fb4,0x4fb5,0x4fb6,0x4fb7,
+ 0x4fb8,0x4fb9,0x4fba,0x4fbb,0x4fbc,0x4fbd,0x4fbe,0x4fbf,
+ 0x4fc0,0x4fc1,0x4fc2,0x4fc3,0x4fc4,0x4fc5,0x4fc6,0x4fc7,
+ 0x4fc8,0x4fc9,0x4fca,0x4fcb,0x4fcc,0x4fcd,0x4fce,0x4fcf,
+ 0x4fd0,0x4fd1,0x4fd2,0x4fd3,0x4fd4,0x4fd5,0x4fd6,0x4fd7,
+ 0x4fd8,0x4fd9,0x4fda,0x4fdb,0x4fdc,0x4fdd,0x4fde,0x4fdf,
+ 0x4fe0,0x4fe1,0x4fe2,0x4fe3,0x4fe4,0x4fe5,0x4fe6,0x4fe7,
+ 0x4fe8,0x4fe9,0x4fea,0x4feb,0x4fec,0x4fed,0x4fee,0x4fef,
+ 0x4ff0,0x4ff1,0x4ff2,0x4ff3,0x4ff4,0x4ff5,0x4ff6,0x4ff7,
+ 0x4ff8,0x4ff9,0x4ffa,0x4ffb,0x4ffc,0x4ffd,0x4ffe,0x4fff,
+ 0x5000,0x5001,0x5002,0x5003,0x5004,0x5005,0x5006,0x5007,
+ 0x5008,0x5009,0x500a,0x500b,0x500c,0x500d,0x500e,0x500f,
+ 0x5010,0x5011,0x5012,0x5013,0x5014,0x5015,0x5016,0x5017,
+ 0x5018,0x5019,0x501a,0x501b,0x501c,0x501d,0x501e,0x501f,
+ 0x5020,0x5021,0x5022,0x5023,0x5024,0x5025,0x5026,0x5027,
+ 0x5028,0x5029,0x502a,0x502b,0x502c,0x502d,0x502e,0x502f,
+ 0x5030,0x5031,0x5032,0x5033,0x5034,0x5035,0x5036,0x5037,
+ 0x5038,0x5039,0x503a,0x503b,0x503c,0x503d,0x503e,0x503f,
+ 0x5040,0x5041,0x5042,0x5043,0x5044,0x5045,0x5046,0x5047,
+ 0x5048,0x5049,0x504a,0x504b,0x504c,0x504d,0x504e,0x504f,
+ 0x5050,0x5051,0x5052,0x5053,0x5054,0x5055,0x5056,0x5057,
+ 0x5058,0x5059,0x505a,0x505b,0x505c,0x505d,0x505e,0x505f,
+ 0x5060,0x5061,0x5062,0x5063,0x5064,0x5065,0x5066,0x5067,
+ 0x5068,0x5069,0x506a,0x506b,0x506c,0x506d,0x506e,0x506f,
+ 0x5070,0x5071,0x5072,0x5073,0x5074,0x5075,0x5076,0x5077,
+ 0x5078,0x5079,0x507a,0x507b,0x507c,0x507d,0x507e,0x507f,
+ 0x5080,0x5081,0x5082,0x5083,0x5084,0x5085,0x5086,0x5087,
+ 0x5088,0x5089,0x508a,0x508b,0x508c,0x508d,0x508e,0x508f,
+ 0x5090,0x5091,0x5092,0x5093,0x5094,0x5095,0x5096,0x5097,
+ 0x5098,0x5099,0x509a,0x509b,0x509c,0x509d,0x509e,0x509f,
+ 0x50a0,0x50a1,0x50a2,0x50a3,0x50a4,0x50a5,0x50a6,0x50a7,
+ 0x50a8,0x50a9,0x50aa,0x50ab,0x50ac,0x50ad,0x50ae,0x50af,
+ 0x50b0,0x50b1,0x50b2,0x50b3,0x50b4,0x50b5,0x50b6,0x50b7,
+ 0x50b8,0x50b9,0x50ba,0x50bb,0x50bc,0x50bd,0x50be,0x50bf,
+ 0x50c0,0x50c1,0x50c2,0x50c3,0x50c4,0x50c5,0x50c6,0x50c7,
+ 0x50c8,0x50c9,0x50ca,0x50cb,0x50cc,0x50cd,0x50ce,0x50cf,
+ 0x50d0,0x50d1,0x50d2,0x50d3,0x50d4,0x50d5,0x50d6,0x50d7,
+ 0x50d8,0x50d9,0x50da,0x50db,0x50dc,0x50dd,0x50de,0x50df,
+ 0x50e0,0x50e1,0x50e2,0x50e3,0x50e4,0x50e5,0x50e6,0x50e7,
+ 0x50e8,0x50e9,0x50ea,0x50eb,0x50ec,0x50ed,0x50ee,0x50ef,
+ 0x50f0,0x50f1,0x50f2,0x50f3,0x50f4,0x50f5,0x50f6,0x50f7,
+ 0x50f8,0x50f9,0x50fa,0x50fb,0x50fc,0x50fd,0x50fe,0x50ff,
+ 0x5100,0x5101,0x5102,0x5103,0x5104,0x5105,0x5106,0x5107,
+ 0x5108,0x5109,0x510a,0x510b,0x510c,0x510d,0x510e,0x510f,
+ 0x5110,0x5111,0x5112,0x5113,0x5114,0x5115,0x5116,0x5117,
+ 0x5118,0x5119,0x511a,0x511b,0x511c,0x511d,0x511e,0x511f,
+ 0x5120,0x5121,0x5122,0x5123,0x5124,0x5125,0x5126,0x5127,
+ 0x5128,0x5129,0x512a,0x512b,0x512c,0x512d,0x512e,0x512f,
+ 0x5130,0x5131,0x5132,0x5133,0x5134,0x5135,0x5136,0x5137,
+ 0x5138,0x5139,0x513a,0x513b,0x513c,0x513d,0x513e,0x513f,
+ 0x5140,0x5141,0x5142,0x5143,0x5144,0x5145,0x5146,0x5147,
+ 0x5148,0x5149,0x514a,0x514b,0x514c,0x514d,0x514e,0x514f,
+ 0x5150,0x5151,0x5152,0x5153,0x5154,0x5155,0x5156,0x5157,
+ 0x5158,0x5159,0x515a,0x515b,0x515c,0x515d,0x515e,0x515f,
+ 0x5160,0x5161,0x5162,0x5163,0x5164,0x5165,0x5166,0x5167,
+ 0x5168,0x5169,0x516a,0x516b,0x516c,0x516d,0x516e,0x516f,
+ 0x5170,0x5171,0x5172,0x5173,0x5174,0x5175,0x5176,0x5177,
+ 0x5178,0x5179,0x517a,0x517b,0x517c,0x517d,0x517e,0x517f,
+ 0x5180,0x5181,0x5182,0x5183,0x5184,0x5185,0x5186,0x5187,
+ 0x5188,0x5189,0x518a,0x518b,0x518c,0x518d,0x518e,0x518f,
+ 0x5190,0x5191,0x5192,0x5193,0x5194,0x5195,0x5196,0x5197,
+ 0x5198,0x5199,0x519a,0x519b,0x519c,0x519d,0x519e,0x519f,
+ 0x51a0,0x51a1,0x51a2,0x51a3,0x51a4,0x51a5,0x51a6,0x51a7,
+ 0x51a8,0x51a9,0x51aa,0x51ab,0x51ac,0x51ad,0x51ae,0x51af,
+ 0x51b0,0x51b1,0x51b2,0x51b3,0x51b4,0x51b5,0x51b6,0x51b7,
+ 0x51b8,0x51b9,0x51ba,0x51bb,0x51bc,0x51bd,0x51be,0x51bf,
+ 0x51c0,0x51c1,0x51c2,0x51c3,0x51c4,0x51c5,0x51c6,0x51c7,
+ 0x51c8,0x51c9,0x51ca,0x51cb,0x51cc,0x51cd,0x51ce,0x51cf,
+ 0x51d0,0x51d1,0x51d2,0x51d3,0x51d4,0x51d5,0x51d6,0x51d7,
+ 0x51d8,0x51d9,0x51da,0x51db,0x51dc,0x51dd,0x51de,0x51df,
+ 0x51e0,0x51e1,0x51e2,0x51e3,0x51e4,0x51e5,0x51e6,0x51e7,
+ 0x51e8,0x51e9,0x51ea,0x51eb,0x51ec,0x51ed,0x51ee,0x51ef,
+ 0x51f0,0x51f1,0x51f2,0x51f3,0x51f4,0x51f5,0x51f6,0x51f7,
+ 0x51f8,0x51f9,0x51fa,0x51fb,0x51fc,0x51fd,0x51fe,0x51ff,
+ 0x5200,0x5201,0x5202,0x5203,0x5204,0x5205,0x5206,0x5207,
+ 0x5208,0x5209,0x520a,0x520b,0x520c,0x520d,0x520e,0x520f,
+ 0x5210,0x5211,0x5212,0x5213,0x5214,0x5215,0x5216,0x5217,
+ 0x5218,0x5219,0x521a,0x521b,0x521c,0x521d,0x521e,0x521f,
+ 0x5220,0x5221,0x5222,0x5223,0x5224,0x5225,0x5226,0x5227,
+ 0x5228,0x5229,0x522a,0x522b,0x522c,0x522d,0x522e,0x522f,
+ 0x5230,0x5231,0x5232,0x5233,0x5234,0x5235,0x5236,0x5237,
+ 0x5238,0x5239,0x523a,0x523b,0x523c,0x523d,0x523e,0x523f,
+ 0x5240,0x5241,0x5242,0x5243,0x5244,0x5245,0x5246,0x5247,
+ 0x5248,0x5249,0x524a,0x524b,0x524c,0x524d,0x524e,0x524f,
+ 0x5250,0x5251,0x5252,0x5253,0x5254,0x5255,0x5256,0x5257,
+ 0x5258,0x5259,0x525a,0x525b,0x525c,0x525d,0x525e,0x525f,
+ 0x5260,0x5261,0x5262,0x5263,0x5264,0x5265,0x5266,0x5267,
+ 0x5268,0x5269,0x526a,0x526b,0x526c,0x526d,0x526e,0x526f,
+ 0x5270,0x5271,0x5272,0x5273,0x5274,0x5275,0x5276,0x5277,
+ 0x5278,0x5279,0x527a,0x527b,0x527c,0x527d,0x527e,0x527f,
+ 0x5280,0x5281,0x5282,0x5283,0x5284,0x5285,0x5286,0x5287,
+ 0x5288,0x5289,0x528a,0x528b,0x528c,0x528d,0x528e,0x528f,
+ 0x5290,0x5291,0x5292,0x5293,0x5294,0x5295,0x5296,0x5297,
+ 0x5298,0x5299,0x529a,0x529b,0x529c,0x529d,0x529e,0x529f,
+ 0x52a0,0x52a1,0x52a2,0x52a3,0x52a4,0x52a5,0x52a6,0x52a7,
+ 0x52a8,0x52a9,0x52aa,0x52ab,0x52ac,0x52ad,0x52ae,0x52af,
+ 0x52b0,0x52b1,0x52b2,0x52b3,0x52b4,0x52b5,0x52b6,0x52b7,
+ 0x52b8,0x52b9,0x52ba,0x52bb,0x52bc,0x52bd,0x52be,0x52bf,
+ 0x52c0,0x52c1,0x52c2,0x52c3,0x52c4,0x52c5,0x52c6,0x52c7,
+ 0x52c8,0x52c9,0x52ca,0x52cb,0x52cc,0x52cd,0x52ce,0x52cf,
+ 0x52d0,0x52d1,0x52d2,0x52d3,0x52d4,0x52d5,0x52d6,0x52d7,
+ 0x52d8,0x52d9,0x52da,0x52db,0x52dc,0x52dd,0x52de,0x52df,
+ 0x52e0,0x52e1,0x52e2,0x52e3,0x52e4,0x52e5,0x52e6,0x52e7,
+ 0x52e8,0x52e9,0x52ea,0x52eb,0x52ec,0x52ed,0x52ee,0x52ef,
+ 0x52f0,0x52f1,0x52f2,0x52f3,0x52f4,0x52f5,0x52f6,0x52f7,
+ 0x52f8,0x52f9,0x52fa,0x52fb,0x52fc,0x52fd,0x52fe,0x52ff,
+ 0x5300,0x5301,0x5302,0x5303,0x5304,0x5305,0x5306,0x5307,
+ 0x5308,0x5309,0x530a,0x530b,0x530c,0x530d,0x530e,0x530f,
+ 0x5310,0x5311,0x5312,0x5313,0x5314,0x5315,0x5316,0x5317,
+ 0x5318,0x5319,0x531a,0x531b,0x531c,0x531d,0x531e,0x531f,
+ 0x5320,0x5321,0x5322,0x5323,0x5324,0x5325,0x5326,0x5327,
+ 0x5328,0x5329,0x532a,0x532b,0x532c,0x532d,0x532e,0x532f,
+ 0x5330,0x5331,0x5332,0x5333,0x5334,0x5335,0x5336,0x5337,
+ 0x5338,0x5339,0x533a,0x533b,0x533c,0x533d,0x533e,0x533f,
+ 0x5340,0x5341,0x5342,0x5343,0x5344,0x5345,0x5346,0x5347,
+ 0x5348,0x5349,0x534a,0x534b,0x534c,0x534d,0x534e,0x534f,
+ 0x5350,0x5351,0x5352,0x5353,0x5354,0x5355,0x5356,0x5357,
+ 0x5358,0x5359,0x535a,0x535b,0x535c,0x535d,0x535e,0x535f,
+ 0x5360,0x5361,0x5362,0x5363,0x5364,0x5365,0x5366,0x5367,
+ 0x5368,0x5369,0x536a,0x536b,0x536c,0x536d,0x536e,0x536f,
+ 0x5370,0x5371,0x5372,0x5373,0x5374,0x5375,0x5376,0x5377,
+ 0x5378,0x5379,0x537a,0x537b,0x537c,0x537d,0x537e,0x537f,
+ 0x5380,0x5381,0x5382,0x5383,0x5384,0x5385,0x5386,0x5387,
+ 0x5388,0x5389,0x538a,0x538b,0x538c,0x538d,0x538e,0x538f,
+ 0x5390,0x5391,0x5392,0x5393,0x5394,0x5395,0x5396,0x5397,
+ 0x5398,0x5399,0x539a,0x539b,0x539c,0x539d,0x539e,0x539f,
+ 0x53a0,0x53a1,0x53a2,0x53a3,0x53a4,0x53a5,0x53a6,0x53a7,
+ 0x53a8,0x53a9,0x53aa,0x53ab,0x53ac,0x53ad,0x53ae,0x53af,
+ 0x53b0,0x53b1,0x53b2,0x53b3,0x53b4,0x53b5,0x53b6,0x53b7,
+ 0x53b8,0x53b9,0x53ba,0x53bb,0x53bc,0x53bd,0x53be,0x53bf,
+ 0x53c0,0x53c1,0x53c2,0x53c3,0x53c4,0x53c5,0x53c6,0x53c7,
+ 0x53c8,0x53c9,0x53ca,0x53cb,0x53cc,0x53cd,0x53ce,0x53cf,
+ 0x53d0,0x53d1,0x53d2,0x53d3,0x53d4,0x53d5,0x53d6,0x53d7,
+ 0x53d8,0x53d9,0x53da,0x53db,0x53dc,0x53dd,0x53de,0x53df,
+ 0x53e0,0x53e1,0x53e2,0x53e3,0x53e4,0x53e5,0x53e6,0x53e7,
+ 0x53e8,0x53e9,0x53ea,0x53eb,0x53ec,0x53ed,0x53ee,0x53ef,
+ 0x53f0,0x53f1,0x53f2,0x53f3,0x53f4,0x53f5,0x53f6,0x53f7,
+ 0x53f8,0x53f9,0x53fa,0x53fb,0x53fc,0x53fd,0x53fe,0x53ff,
+ 0x5400,0x5401,0x5402,0x5403,0x5404,0x5405,0x5406,0x5407,
+ 0x5408,0x5409,0x540a,0x540b,0x540c,0x540d,0x540e,0x540f,
+ 0x5410,0x5411,0x5412,0x5413,0x5414,0x5415,0x5416,0x5417,
+ 0x5418,0x5419,0x541a,0x541b,0x541c,0x541d,0x541e,0x541f,
+ 0x5420,0x5421,0x5422,0x5423,0x5424,0x5425,0x5426,0x5427,
+ 0x5428,0x5429,0x542a,0x542b,0x542c,0x542d,0x542e,0x542f,
+ 0x5430,0x5431,0x5432,0x5433,0x5434,0x5435,0x5436,0x5437,
+ 0x5438,0x5439,0x543a,0x543b,0x543c,0x543d,0x543e,0x543f,
+ 0x5440,0x5441,0x5442,0x5443,0x5444,0x5445,0x5446,0x5447,
+ 0x5448,0x5449,0x544a,0x544b,0x544c,0x544d,0x544e,0x544f,
+ 0x5450,0x5451,0x5452,0x5453,0x5454,0x5455,0x5456,0x5457,
+ 0x5458,0x5459,0x545a,0x545b,0x545c,0x545d,0x545e,0x545f,
+ 0x5460,0x5461,0x5462,0x5463,0x5464,0x5465,0x5466,0x5467,
+ 0x5468,0x5469,0x546a,0x546b,0x546c,0x546d,0x546e,0x546f,
+ 0x5470,0x5471,0x5472,0x5473,0x5474,0x5475,0x5476,0x5477,
+ 0x5478,0x5479,0x547a,0x547b,0x547c,0x547d,0x547e,0x547f,
+ 0x5480,0x5481,0x5482,0x5483,0x5484,0x5485,0x5486,0x5487,
+ 0x5488,0x5489,0x548a,0x548b,0x548c,0x548d,0x548e,0x548f,
+ 0x5490,0x5491,0x5492,0x5493,0x5494,0x5495,0x5496,0x5497,
+ 0x5498,0x5499,0x549a,0x549b,0x549c,0x549d,0x549e,0x549f,
+ 0x54a0,0x54a1,0x54a2,0x54a3,0x54a4,0x54a5,0x54a6,0x54a7,
+ 0x54a8,0x54a9,0x54aa,0x54ab,0x54ac,0x54ad,0x54ae,0x54af,
+ 0x54b0,0x54b1,0x54b2,0x54b3,0x54b4,0x54b5,0x54b6,0x54b7,
+ 0x54b8,0x54b9,0x54ba,0x54bb,0x54bc,0x54bd,0x54be,0x54bf,
+ 0x54c0,0x54c1,0x54c2,0x54c3,0x54c4,0x54c5,0x54c6,0x54c7,
+ 0x54c8,0x54c9,0x54ca,0x54cb,0x54cc,0x54cd,0x54ce,0x54cf,
+ 0x54d0,0x54d1,0x54d2,0x54d3,0x54d4,0x54d5,0x54d6,0x54d7,
+ 0x54d8,0x54d9,0x54da,0x54db,0x54dc,0x54dd,0x54de,0x54df,
+ 0x54e0,0x54e1,0x54e2,0x54e3,0x54e4,0x54e5,0x54e6,0x54e7,
+ 0x54e8,0x54e9,0x54ea,0x54eb,0x54ec,0x54ed,0x54ee,0x54ef,
+ 0x54f0,0x54f1,0x54f2,0x54f3,0x54f4,0x54f5,0x54f6,0x54f7,
+ 0x54f8,0x54f9,0x54fa,0x54fb,0x54fc,0x54fd,0x54fe,0x54ff,
+ 0x5500,0x5501,0x5502,0x5503,0x5504,0x5505,0x5506,0x5507,
+ 0x5508,0x5509,0x550a,0x550b,0x550c,0x550d,0x550e,0x550f,
+ 0x5510,0x5511,0x5512,0x5513,0x5514,0x5515,0x5516,0x5517,
+ 0x5518,0x5519,0x551a,0x551b,0x551c,0x551d,0x551e,0x551f,
+ 0x5520,0x5521,0x5522,0x5523,0x5524,0x5525,0x5526,0x5527,
+ 0x5528,0x5529,0x552a,0x552b,0x552c,0x552d,0x552e,0x552f,
+ 0x5530,0x5531,0x5532,0x5533,0x5534,0x5535,0x5536,0x5537,
+ 0x5538,0x5539,0x553a,0x553b,0x553c,0x553d,0x553e,0x553f,
+ 0x5540,0x5541,0x5542,0x5543,0x5544,0x5545,0x5546,0x5547,
+ 0x5548,0x5549,0x554a,0x554b,0x554c,0x554d,0x554e,0x554f,
+ 0x5550,0x5551,0x5552,0x5553,0x5554,0x5555,0x5556,0x5557,
+ 0x5558,0x5559,0x555a,0x555b,0x555c,0x555d,0x555e,0x555f,
+ 0x5560,0x5561,0x5562,0x5563,0x5564,0x5565,0x5566,0x5567,
+ 0x5568,0x5569,0x556a,0x556b,0x556c,0x556d,0x556e,0x556f,
+ 0x5570,0x5571,0x5572,0x5573,0x5574,0x5575,0x5576,0x5577,
+ 0x5578,0x5579,0x557a,0x557b,0x557c,0x557d,0x557e,0x557f,
+ 0x5580,0x5581,0x5582,0x5583,0x5584,0x5585,0x5586,0x5587,
+ 0x5588,0x5589,0x558a,0x558b,0x558c,0x558d,0x558e,0x558f,
+ 0x5590,0x5591,0x5592,0x5593,0x5594,0x5595,0x5596,0x5597,
+ 0x5598,0x5599,0x559a,0x559b,0x559c,0x559d,0x559e,0x559f,
+ 0x55a0,0x55a1,0x55a2,0x55a3,0x55a4,0x55a5,0x55a6,0x55a7,
+ 0x55a8,0x55a9,0x55aa,0x55ab,0x55ac,0x55ad,0x55ae,0x55af,
+ 0x55b0,0x55b1,0x55b2,0x55b3,0x55b4,0x55b5,0x55b6,0x55b7,
+ 0x55b8,0x55b9,0x55ba,0x55bb,0x55bc,0x55bd,0x55be,0x55bf,
+ 0x55c0,0x55c1,0x55c2,0x55c3,0x55c4,0x55c5,0x55c6,0x55c7,
+ 0x55c8,0x55c9,0x55ca,0x55cb,0x55cc,0x55cd,0x55ce,0x55cf,
+ 0x55d0,0x55d1,0x55d2,0x55d3,0x55d4,0x55d5,0x55d6,0x55d7,
+ 0x55d8,0x55d9,0x55da,0x55db,0x55dc,0x55dd,0x55de,0x55df,
+ 0x55e0,0x55e1,0x55e2,0x55e3,0x55e4,0x55e5,0x55e6,0x55e7,
+ 0x55e8,0x55e9,0x55ea,0x55eb,0x55ec,0x55ed,0x55ee,0x55ef,
+ 0x55f0,0x55f1,0x55f2,0x55f3,0x55f4,0x55f5,0x55f6,0x55f7,
+ 0x55f8,0x55f9,0x55fa,0x55fb,0x55fc,0x55fd,0x55fe,0x55ff,
+ 0x5600,0x5601,0x5602,0x5603,0x5604,0x5605,0x5606,0x5607,
+ 0x5608,0x5609,0x560a,0x560b,0x560c,0x560d,0x560e,0x560f,
+ 0x5610,0x5611,0x5612,0x5613,0x5614,0x5615,0x5616,0x5617,
+ 0x5618,0x5619,0x561a,0x561b,0x561c,0x561d,0x561e,0x561f,
+ 0x5620,0x5621,0x5622,0x5623,0x5624,0x5625,0x5626,0x5627,
+ 0x5628,0x5629,0x562a,0x562b,0x562c,0x562d,0x562e,0x562f,
+ 0x5630,0x5631,0x5632,0x5633,0x5634,0x5635,0x5636,0x5637,
+ 0x5638,0x5639,0x563a,0x563b,0x563c,0x563d,0x563e,0x563f,
+ 0x5640,0x5641,0x5642,0x5643,0x5644,0x5645,0x5646,0x5647,
+ 0x5648,0x5649,0x564a,0x564b,0x564c,0x564d,0x564e,0x564f,
+ 0x5650,0x5651,0x5652,0x5653,0x5654,0x5655,0x5656,0x5657,
+ 0x5658,0x5659,0x565a,0x565b,0x565c,0x565d,0x565e,0x565f,
+ 0x5660,0x5661,0x5662,0x5663,0x5664,0x5665,0x5666,0x5667,
+ 0x5668,0x5669,0x566a,0x566b,0x566c,0x566d,0x566e,0x566f,
+ 0x5670,0x5671,0x5672,0x5673,0x5674,0x5675,0x5676,0x5677,
+ 0x5678,0x5679,0x567a,0x567b,0x567c,0x567d,0x567e,0x567f,
+ 0x5680,0x5681,0x5682,0x5683,0x5684,0x5685,0x5686,0x5687,
+ 0x5688,0x5689,0x568a,0x568b,0x568c,0x568d,0x568e,0x568f,
+ 0x5690,0x5691,0x5692,0x5693,0x5694,0x5695,0x5696,0x5697,
+ 0x5698,0x5699,0x569a,0x569b,0x569c,0x569d,0x569e,0x569f,
+ 0x56a0,0x56a1,0x56a2,0x56a3,0x56a4,0x56a5,0x56a6,0x56a7,
+ 0x56a8,0x56a9,0x56aa,0x56ab,0x56ac,0x56ad,0x56ae,0x56af,
+ 0x56b0,0x56b1,0x56b2,0x56b3,0x56b4,0x56b5,0x56b6,0x56b7,
+ 0x56b8,0x56b9,0x56ba,0x56bb,0x56bc,0x56bd,0x56be,0x56bf,
+ 0x56c0,0x56c1,0x56c2,0x56c3,0x56c4,0x56c5,0x56c6,0x56c7,
+ 0x56c8,0x56c9,0x56ca,0x56cb,0x56cc,0x56cd,0x56ce,0x56cf,
+ 0x56d0,0x56d1,0x56d2,0x56d3,0x56d4,0x56d5,0x56d6,0x56d7,
+ 0x56d8,0x56d9,0x56da,0x56db,0x56dc,0x56dd,0x56de,0x56df,
+ 0x56e0,0x56e1,0x56e2,0x56e3,0x56e4,0x56e5,0x56e6,0x56e7,
+ 0x56e8,0x56e9,0x56ea,0x56eb,0x56ec,0x56ed,0x56ee,0x56ef,
+ 0x56f0,0x56f1,0x56f2,0x56f3,0x56f4,0x56f5,0x56f6,0x56f7,
+ 0x56f8,0x56f9,0x56fa,0x56fb,0x56fc,0x56fd,0x56fe,0x56ff,
+ 0x5700,0x5701,0x5702,0x5703,0x5704,0x5705,0x5706,0x5707,
+ 0x5708,0x5709,0x570a,0x570b,0x570c,0x570d,0x570e,0x570f,
+ 0x5710,0x5711,0x5712,0x5713,0x5714,0x5715,0x5716,0x5717,
+ 0x5718,0x5719,0x571a,0x571b,0x571c,0x571d,0x571e,0x571f,
+ 0x5720,0x5721,0x5722,0x5723,0x5724,0x5725,0x5726,0x5727,
+ 0x5728,0x5729,0x572a,0x572b,0x572c,0x572d,0x572e,0x572f,
+ 0x5730,0x5731,0x5732,0x5733,0x5734,0x5735,0x5736,0x5737,
+ 0x5738,0x5739,0x573a,0x573b,0x573c,0x573d,0x573e,0x573f,
+ 0x5740,0x5741,0x5742,0x5743,0x5744,0x5745,0x5746,0x5747,
+ 0x5748,0x5749,0x574a,0x574b,0x574c,0x574d,0x574e,0x574f,
+ 0x5750,0x5751,0x5752,0x5753,0x5754,0x5755,0x5756,0x5757,
+ 0x5758,0x5759,0x575a,0x575b,0x575c,0x575d,0x575e,0x575f,
+ 0x5760,0x5761,0x5762,0x5763,0x5764,0x5765,0x5766,0x5767,
+ 0x5768,0x5769,0x576a,0x576b,0x576c,0x576d,0x576e,0x576f,
+ 0x5770,0x5771,0x5772,0x5773,0x5774,0x5775,0x5776,0x5777,
+ 0x5778,0x5779,0x577a,0x577b,0x577c,0x577d,0x577e,0x577f,
+ 0x5780,0x5781,0x5782,0x5783,0x5784,0x5785,0x5786,0x5787,
+ 0x5788,0x5789,0x578a,0x578b,0x578c,0x578d,0x578e,0x578f,
+ 0x5790,0x5791,0x5792,0x5793,0x5794,0x5795,0x5796,0x5797,
+ 0x5798,0x5799,0x579a,0x579b,0x579c,0x579d,0x579e,0x579f,
+ 0x57a0,0x57a1,0x57a2,0x57a3,0x57a4,0x57a5,0x57a6,0x57a7,
+ 0x57a8,0x57a9,0x57aa,0x57ab,0x57ac,0x57ad,0x57ae,0x57af,
+ 0x57b0,0x57b1,0x57b2,0x57b3,0x57b4,0x57b5,0x57b6,0x57b7,
+ 0x57b8,0x57b9,0x57ba,0x57bb,0x57bc,0x57bd,0x57be,0x57bf,
+ 0x57c0,0x57c1,0x57c2,0x57c3,0x57c4,0x57c5,0x57c6,0x57c7,
+ 0x57c8,0x57c9,0x57ca,0x57cb,0x57cc,0x57cd,0x57ce,0x57cf,
+ 0x57d0,0x57d1,0x57d2,0x57d3,0x57d4,0x57d5,0x57d6,0x57d7,
+ 0x57d8,0x57d9,0x57da,0x57db,0x57dc,0x57dd,0x57de,0x57df,
+ 0x57e0,0x57e1,0x57e2,0x57e3,0x57e4,0x57e5,0x57e6,0x57e7,
+ 0x57e8,0x57e9,0x57ea,0x57eb,0x57ec,0x57ed,0x57ee,0x57ef,
+ 0x57f0,0x57f1,0x57f2,0x57f3,0x57f4,0x57f5,0x57f6,0x57f7,
+ 0x57f8,0x57f9,0x57fa,0x57fb,0x57fc,0x57fd,0x57fe,0x57ff,
+ 0x5800,0x5801,0x5802,0x5803,0x5804,0x5805,0x5806,0x5807,
+ 0x5808,0x5809,0x580a,0x580b,0x580c,0x580d,0x580e,0x580f,
+ 0x5810,0x5811,0x5812,0x5813,0x5814,0x5815,0x5816,0x5817,
+ 0x5818,0x5819,0x581a,0x581b,0x581c,0x581d,0x581e,0x581f,
+ 0x5820,0x5821,0x5822,0x5823,0x5824,0x5825,0x5826,0x5827,
+ 0x5828,0x5829,0x582a,0x582b,0x582c,0x582d,0x582e,0x582f,
+ 0x5830,0x5831,0x5832,0x5833,0x5834,0x5835,0x5836,0x5837,
+ 0x5838,0x5839,0x583a,0x583b,0x583c,0x583d,0x583e,0x583f,
+ 0x5840,0x5841,0x5842,0x5843,0x5844,0x5845,0x5846,0x5847,
+ 0x5848,0x5849,0x584a,0x584b,0x584c,0x584d,0x584e,0x584f,
+ 0x5850,0x5851,0x5852,0x5853,0x5854,0x5855,0x5856,0x5857,
+ 0x5858,0x5859,0x585a,0x585b,0x585c,0x585d,0x585e,0x585f,
+ 0x5860,0x5861,0x5862,0x5863,0x5864,0x5865,0x5866,0x5867,
+ 0x5868,0x5869,0x586a,0x586b,0x586c,0x586d,0x586e,0x586f,
+ 0x5870,0x5871,0x5872,0x5873,0x5874,0x5875,0x5876,0x5877,
+ 0x5878,0x5879,0x587a,0x587b,0x587c,0x587d,0x587e,0x587f,
+ 0x5880,0x5881,0x5882,0x5883,0x5884,0x5885,0x5886,0x5887,
+ 0x5888,0x5889,0x588a,0x588b,0x588c,0x588d,0x588e,0x588f,
+ 0x5890,0x5891,0x5892,0x5893,0x5894,0x5895,0x5896,0x5897,
+ 0x5898,0x5899,0x589a,0x589b,0x589c,0x589d,0x589e,0x589f,
+ 0x58a0,0x58a1,0x58a2,0x58a3,0x58a4,0x58a5,0x58a6,0x58a7,
+ 0x58a8,0x58a9,0x58aa,0x58ab,0x58ac,0x58ad,0x58ae,0x58af,
+ 0x58b0,0x58b1,0x58b2,0x58b3,0x58b4,0x58b5,0x58b6,0x58b7,
+ 0x58b8,0x58b9,0x58ba,0x58bb,0x58bc,0x58bd,0x58be,0x58bf,
+ 0x58c0,0x58c1,0x58c2,0x58c3,0x58c4,0x58c5,0x58c6,0x58c7,
+ 0x58c8,0x58c9,0x58ca,0x58cb,0x58cc,0x58cd,0x58ce,0x58cf,
+ 0x58d0,0x58d1,0x58d2,0x58d3,0x58d4,0x58d5,0x58d6,0x58d7,
+ 0x58d8,0x58d9,0x58da,0x58db,0x58dc,0x58dd,0x58de,0x58df,
+ 0x58e0,0x58e1,0x58e2,0x58e3,0x58e4,0x58e5,0x58e6,0x58e7,
+ 0x58e8,0x58e9,0x58ea,0x58eb,0x58ec,0x58ed,0x58ee,0x58ef,
+ 0x58f0,0x58f1,0x58f2,0x58f3,0x58f4,0x58f5,0x58f6,0x58f7,
+ 0x58f8,0x58f9,0x58fa,0x58fb,0x58fc,0x58fd,0x58fe,0x58ff,
+ 0x5900,0x5901,0x5902,0x5903,0x5904,0x5905,0x5906,0x5907,
+ 0x5908,0x5909,0x590a,0x590b,0x590c,0x590d,0x590e,0x590f,
+ 0x5910,0x5911,0x5912,0x5913,0x5914,0x5915,0x5916,0x5917,
+ 0x5918,0x5919,0x591a,0x591b,0x591c,0x591d,0x591e,0x591f,
+ 0x5920,0x5921,0x5922,0x5923,0x5924,0x5925,0x5926,0x5927,
+ 0x5928,0x5929,0x592a,0x592b,0x592c,0x592d,0x592e,0x592f,
+ 0x5930,0x5931,0x5932,0x5933,0x5934,0x5935,0x5936,0x5937,
+ 0x5938,0x5939,0x593a,0x593b,0x593c,0x593d,0x593e,0x593f,
+ 0x5940,0x5941,0x5942,0x5943,0x5944,0x5945,0x5946,0x5947,
+ 0x5948,0x5949,0x594a,0x594b,0x594c,0x594d,0x594e,0x594f,
+ 0x5950,0x5951,0x5952,0x5953,0x5954,0x5955,0x5956,0x5957,
+ 0x5958,0x5959,0x595a,0x595b,0x595c,0x595d,0x595e,0x595f,
+ 0x5960,0x5961,0x5962,0x5963,0x5964,0x5965,0x5966,0x5967,
+ 0x5968,0x5969,0x596a,0x596b,0x596c,0x596d,0x596e,0x596f,
+ 0x5970,0x5971,0x5972,0x5973,0x5974,0x5975,0x5976,0x5977,
+ 0x5978,0x5979,0x597a,0x597b,0x597c,0x597d,0x597e,0x597f,
+ 0x5980,0x5981,0x5982,0x5983,0x5984,0x5985,0x5986,0x5987,
+ 0x5988,0x5989,0x598a,0x598b,0x598c,0x598d,0x598e,0x598f,
+ 0x5990,0x5991,0x5992,0x5993,0x5994,0x5995,0x5996,0x5997,
+ 0x5998,0x5999,0x599a,0x599b,0x599c,0x599d,0x599e,0x599f,
+ 0x59a0,0x59a1,0x59a2,0x59a3,0x59a4,0x59a5,0x59a6,0x59a7,
+ 0x59a8,0x59a9,0x59aa,0x59ab,0x59ac,0x59ad,0x59ae,0x59af,
+ 0x59b0,0x59b1,0x59b2,0x59b3,0x59b4,0x59b5,0x59b6,0x59b7,
+ 0x59b8,0x59b9,0x59ba,0x59bb,0x59bc,0x59bd,0x59be,0x59bf,
+ 0x59c0,0x59c1,0x59c2,0x59c3,0x59c4,0x59c5,0x59c6,0x59c7,
+ 0x59c8,0x59c9,0x59ca,0x59cb,0x59cc,0x59cd,0x59ce,0x59cf,
+ 0x59d0,0x59d1,0x59d2,0x59d3,0x59d4,0x59d5,0x59d6,0x59d7,
+ 0x59d8,0x59d9,0x59da,0x59db,0x59dc,0x59dd,0x59de,0x59df,
+ 0x59e0,0x59e1,0x59e2,0x59e3,0x59e4,0x59e5,0x59e6,0x59e7,
+ 0x59e8,0x59e9,0x59ea,0x59eb,0x59ec,0x59ed,0x59ee,0x59ef,
+ 0x59f0,0x59f1,0x59f2,0x59f3,0x59f4,0x59f5,0x59f6,0x59f7,
+ 0x59f8,0x59f9,0x59fa,0x59fb,0x59fc,0x59fd,0x59fe,0x59ff,
+ 0x5a00,0x5a01,0x5a02,0x5a03,0x5a04,0x5a05,0x5a06,0x5a07,
+ 0x5a08,0x5a09,0x5a0a,0x5a0b,0x5a0c,0x5a0d,0x5a0e,0x5a0f,
+ 0x5a10,0x5a11,0x5a12,0x5a13,0x5a14,0x5a15,0x5a16,0x5a17,
+ 0x5a18,0x5a19,0x5a1a,0x5a1b,0x5a1c,0x5a1d,0x5a1e,0x5a1f,
+ 0x5a20,0x5a21,0x5a22,0x5a23,0x5a24,0x5a25,0x5a26,0x5a27,
+ 0x5a28,0x5a29,0x5a2a,0x5a2b,0x5a2c,0x5a2d,0x5a2e,0x5a2f,
+ 0x5a30,0x5a31,0x5a32,0x5a33,0x5a34,0x5a35,0x5a36,0x5a37,
+ 0x5a38,0x5a39,0x5a3a,0x5a3b,0x5a3c,0x5a3d,0x5a3e,0x5a3f,
+ 0x5a40,0x5a41,0x5a42,0x5a43,0x5a44,0x5a45,0x5a46,0x5a47,
+ 0x5a48,0x5a49,0x5a4a,0x5a4b,0x5a4c,0x5a4d,0x5a4e,0x5a4f,
+ 0x5a50,0x5a51,0x5a52,0x5a53,0x5a54,0x5a55,0x5a56,0x5a57,
+ 0x5a58,0x5a59,0x5a5a,0x5a5b,0x5a5c,0x5a5d,0x5a5e,0x5a5f,
+ 0x5a60,0x5a61,0x5a62,0x5a63,0x5a64,0x5a65,0x5a66,0x5a67,
+ 0x5a68,0x5a69,0x5a6a,0x5a6b,0x5a6c,0x5a6d,0x5a6e,0x5a6f,
+ 0x5a70,0x5a71,0x5a72,0x5a73,0x5a74,0x5a75,0x5a76,0x5a77,
+ 0x5a78,0x5a79,0x5a7a,0x5a7b,0x5a7c,0x5a7d,0x5a7e,0x5a7f,
+ 0x5a80,0x5a81,0x5a82,0x5a83,0x5a84,0x5a85,0x5a86,0x5a87,
+ 0x5a88,0x5a89,0x5a8a,0x5a8b,0x5a8c,0x5a8d,0x5a8e,0x5a8f,
+ 0x5a90,0x5a91,0x5a92,0x5a93,0x5a94,0x5a95,0x5a96,0x5a97,
+ 0x5a98,0x5a99,0x5a9a,0x5a9b,0x5a9c,0x5a9d,0x5a9e,0x5a9f,
+ 0x5aa0,0x5aa1,0x5aa2,0x5aa3,0x5aa4,0x5aa5,0x5aa6,0x5aa7,
+ 0x5aa8,0x5aa9,0x5aaa,0x5aab,0x5aac,0x5aad,0x5aae,0x5aaf,
+ 0x5ab0,0x5ab1,0x5ab2,0x5ab3,0x5ab4,0x5ab5,0x5ab6,0x5ab7,
+ 0x5ab8,0x5ab9,0x5aba,0x5abb,0x5abc,0x5abd,0x5abe,0x5abf,
+ 0x5ac0,0x5ac1,0x5ac2,0x5ac3,0x5ac4,0x5ac5,0x5ac6,0x5ac7,
+ 0x5ac8,0x5ac9,0x5aca,0x5acb,0x5acc,0x5acd,0x5ace,0x5acf,
+ 0x5ad0,0x5ad1,0x5ad2,0x5ad3,0x5ad4,0x5ad5,0x5ad6,0x5ad7,
+ 0x5ad8,0x5ad9,0x5ada,0x5adb,0x5adc,0x5add,0x5ade,0x5adf,
+ 0x5ae0,0x5ae1,0x5ae2,0x5ae3,0x5ae4,0x5ae5,0x5ae6,0x5ae7,
+ 0x5ae8,0x5ae9,0x5aea,0x5aeb,0x5aec,0x5aed,0x5aee,0x5aef,
+ 0x5af0,0x5af1,0x5af2,0x5af3,0x5af4,0x5af5,0x5af6,0x5af7,
+ 0x5af8,0x5af9,0x5afa,0x5afb,0x5afc,0x5afd,0x5afe,0x5aff,
+ 0x5b00,0x5b01,0x5b02,0x5b03,0x5b04,0x5b05,0x5b06,0x5b07,
+ 0x5b08,0x5b09,0x5b0a,0x5b0b,0x5b0c,0x5b0d,0x5b0e,0x5b0f,
+ 0x5b10,0x5b11,0x5b12,0x5b13,0x5b14,0x5b15,0x5b16,0x5b17,
+ 0x5b18,0x5b19,0x5b1a,0x5b1b,0x5b1c,0x5b1d,0x5b1e,0x5b1f,
+ 0x5b20,0x5b21,0x5b22,0x5b23,0x5b24,0x5b25,0x5b26,0x5b27,
+ 0x5b28,0x5b29,0x5b2a,0x5b2b,0x5b2c,0x5b2d,0x5b2e,0x5b2f,
+ 0x5b30,0x5b31,0x5b32,0x5b33,0x5b34,0x5b35,0x5b36,0x5b37,
+ 0x5b38,0x5b39,0x5b3a,0x5b3b,0x5b3c,0x5b3d,0x5b3e,0x5b3f,
+ 0x5b40,0x5b41,0x5b42,0x5b43,0x5b44,0x5b45,0x5b46,0x5b47,
+ 0x5b48,0x5b49,0x5b4a,0x5b4b,0x5b4c,0x5b4d,0x5b4e,0x5b4f,
+ 0x5b50,0x5b51,0x5b52,0x5b53,0x5b54,0x5b55,0x5b56,0x5b57,
+ 0x5b58,0x5b59,0x5b5a,0x5b5b,0x5b5c,0x5b5d,0x5b5e,0x5b5f,
+ 0x5b60,0x5b61,0x5b62,0x5b63,0x5b64,0x5b65,0x5b66,0x5b67,
+ 0x5b68,0x5b69,0x5b6a,0x5b6b,0x5b6c,0x5b6d,0x5b6e,0x5b6f,
+ 0x5b70,0x5b71,0x5b72,0x5b73,0x5b74,0x5b75,0x5b76,0x5b77,
+ 0x5b78,0x5b79,0x5b7a,0x5b7b,0x5b7c,0x5b7d,0x5b7e,0x5b7f,
+ 0x5b80,0x5b81,0x5b82,0x5b83,0x5b84,0x5b85,0x5b86,0x5b87,
+ 0x5b88,0x5b89,0x5b8a,0x5b8b,0x5b8c,0x5b8d,0x5b8e,0x5b8f,
+ 0x5b90,0x5b91,0x5b92,0x5b93,0x5b94,0x5b95,0x5b96,0x5b97,
+ 0x5b98,0x5b99,0x5b9a,0x5b9b,0x5b9c,0x5b9d,0x5b9e,0x5b9f,
+ 0x5ba0,0x5ba1,0x5ba2,0x5ba3,0x5ba4,0x5ba5,0x5ba6,0x5ba7,
+ 0x5ba8,0x5ba9,0x5baa,0x5bab,0x5bac,0x5bad,0x5bae,0x5baf,
+ 0x5bb0,0x5bb1,0x5bb2,0x5bb3,0x5bb4,0x5bb5,0x5bb6,0x5bb7,
+ 0x5bb8,0x5bb9,0x5bba,0x5bbb,0x5bbc,0x5bbd,0x5bbe,0x5bbf,
+ 0x5bc0,0x5bc1,0x5bc2,0x5bc3,0x5bc4,0x5bc5,0x5bc6,0x5bc7,
+ 0x5bc8,0x5bc9,0x5bca,0x5bcb,0x5bcc,0x5bcd,0x5bce,0x5bcf,
+ 0x5bd0,0x5bd1,0x5bd2,0x5bd3,0x5bd4,0x5bd5,0x5bd6,0x5bd7,
+ 0x5bd8,0x5bd9,0x5bda,0x5bdb,0x5bdc,0x5bdd,0x5bde,0x5bdf,
+ 0x5be0,0x5be1,0x5be2,0x5be3,0x5be4,0x5be5,0x5be6,0x5be7,
+ 0x5be8,0x5be9,0x5bea,0x5beb,0x5bec,0x5bed,0x5bee,0x5bef,
+ 0x5bf0,0x5bf1,0x5bf2,0x5bf3,0x5bf4,0x5bf5,0x5bf6,0x5bf7,
+ 0x5bf8,0x5bf9,0x5bfa,0x5bfb,0x5bfc,0x5bfd,0x5bfe,0x5bff,
+ 0x5c00,0x5c01,0x5c02,0x5c03,0x5c04,0x5c05,0x5c06,0x5c07,
+ 0x5c08,0x5c09,0x5c0a,0x5c0b,0x5c0c,0x5c0d,0x5c0e,0x5c0f,
+ 0x5c10,0x5c11,0x5c12,0x5c13,0x5c14,0x5c15,0x5c16,0x5c17,
+ 0x5c18,0x5c19,0x5c1a,0x5c1b,0x5c1c,0x5c1d,0x5c1e,0x5c1f,
+ 0x5c20,0x5c21,0x5c22,0x5c23,0x5c24,0x5c25,0x5c26,0x5c27,
+ 0x5c28,0x5c29,0x5c2a,0x5c2b,0x5c2c,0x5c2d,0x5c2e,0x5c2f,
+ 0x5c30,0x5c31,0x5c32,0x5c33,0x5c34,0x5c35,0x5c36,0x5c37,
+ 0x5c38,0x5c39,0x5c3a,0x5c3b,0x5c3c,0x5c3d,0x5c3e,0x5c3f,
+ 0x5c40,0x5c41,0x5c42,0x5c43,0x5c44,0x5c45,0x5c46,0x5c47,
+ 0x5c48,0x5c49,0x5c4a,0x5c4b,0x5c4c,0x5c4d,0x5c4e,0x5c4f,
+ 0x5c50,0x5c51,0x5c52,0x5c53,0x5c54,0x5c55,0x5c56,0x5c57,
+ 0x5c58,0x5c59,0x5c5a,0x5c5b,0x5c5c,0x5c5d,0x5c5e,0x5c5f,
+ 0x5c60,0x5c61,0x5c62,0x5c63,0x5c64,0x5c65,0x5c66,0x5c67,
+ 0x5c68,0x5c69,0x5c6a,0x5c6b,0x5c6c,0x5c6d,0x5c6e,0x5c6f,
+ 0x5c70,0x5c71,0x5c72,0x5c73,0x5c74,0x5c75,0x5c76,0x5c77,
+ 0x5c78,0x5c79,0x5c7a,0x5c7b,0x5c7c,0x5c7d,0x5c7e,0x5c7f,
+ 0x5c80,0x5c81,0x5c82,0x5c83,0x5c84,0x5c85,0x5c86,0x5c87,
+ 0x5c88,0x5c89,0x5c8a,0x5c8b,0x5c8c,0x5c8d,0x5c8e,0x5c8f,
+ 0x5c90,0x5c91,0x5c92,0x5c93,0x5c94,0x5c95,0x5c96,0x5c97,
+ 0x5c98,0x5c99,0x5c9a,0x5c9b,0x5c9c,0x5c9d,0x5c9e,0x5c9f,
+ 0x5ca0,0x5ca1,0x5ca2,0x5ca3,0x5ca4,0x5ca5,0x5ca6,0x5ca7,
+ 0x5ca8,0x5ca9,0x5caa,0x5cab,0x5cac,0x5cad,0x5cae,0x5caf,
+ 0x5cb0,0x5cb1,0x5cb2,0x5cb3,0x5cb4,0x5cb5,0x5cb6,0x5cb7,
+ 0x5cb8,0x5cb9,0x5cba,0x5cbb,0x5cbc,0x5cbd,0x5cbe,0x5cbf,
+ 0x5cc0,0x5cc1,0x5cc2,0x5cc3,0x5cc4,0x5cc5,0x5cc6,0x5cc7,
+ 0x5cc8,0x5cc9,0x5cca,0x5ccb,0x5ccc,0x5ccd,0x5cce,0x5ccf,
+ 0x5cd0,0x5cd1,0x5cd2,0x5cd3,0x5cd4,0x5cd5,0x5cd6,0x5cd7,
+ 0x5cd8,0x5cd9,0x5cda,0x5cdb,0x5cdc,0x5cdd,0x5cde,0x5cdf,
+ 0x5ce0,0x5ce1,0x5ce2,0x5ce3,0x5ce4,0x5ce5,0x5ce6,0x5ce7,
+ 0x5ce8,0x5ce9,0x5cea,0x5ceb,0x5cec,0x5ced,0x5cee,0x5cef,
+ 0x5cf0,0x5cf1,0x5cf2,0x5cf3,0x5cf4,0x5cf5,0x5cf6,0x5cf7,
+ 0x5cf8,0x5cf9,0x5cfa,0x5cfb,0x5cfc,0x5cfd,0x5cfe,0x5cff,
+ 0x5d00,0x5d01,0x5d02,0x5d03,0x5d04,0x5d05,0x5d06,0x5d07,
+ 0x5d08,0x5d09,0x5d0a,0x5d0b,0x5d0c,0x5d0d,0x5d0e,0x5d0f,
+ 0x5d10,0x5d11,0x5d12,0x5d13,0x5d14,0x5d15,0x5d16,0x5d17,
+ 0x5d18,0x5d19,0x5d1a,0x5d1b,0x5d1c,0x5d1d,0x5d1e,0x5d1f,
+ 0x5d20,0x5d21,0x5d22,0x5d23,0x5d24,0x5d25,0x5d26,0x5d27,
+ 0x5d28,0x5d29,0x5d2a,0x5d2b,0x5d2c,0x5d2d,0x5d2e,0x5d2f,
+ 0x5d30,0x5d31,0x5d32,0x5d33,0x5d34,0x5d35,0x5d36,0x5d37,
+ 0x5d38,0x5d39,0x5d3a,0x5d3b,0x5d3c,0x5d3d,0x5d3e,0x5d3f,
+ 0x5d40,0x5d41,0x5d42,0x5d43,0x5d44,0x5d45,0x5d46,0x5d47,
+ 0x5d48,0x5d49,0x5d4a,0x5d4b,0x5d4c,0x5d4d,0x5d4e,0x5d4f,
+ 0x5d50,0x5d51,0x5d52,0x5d53,0x5d54,0x5d55,0x5d56,0x5d57,
+ 0x5d58,0x5d59,0x5d5a,0x5d5b,0x5d5c,0x5d5d,0x5d5e,0x5d5f,
+ 0x5d60,0x5d61,0x5d62,0x5d63,0x5d64,0x5d65,0x5d66,0x5d67,
+ 0x5d68,0x5d69,0x5d6a,0x5d6b,0x5d6c,0x5d6d,0x5d6e,0x5d6f,
+ 0x5d70,0x5d71,0x5d72,0x5d73,0x5d74,0x5d75,0x5d76,0x5d77,
+ 0x5d78,0x5d79,0x5d7a,0x5d7b,0x5d7c,0x5d7d,0x5d7e,0x5d7f,
+ 0x5d80,0x5d81,0x5d82,0x5d83,0x5d84,0x5d85,0x5d86,0x5d87,
+ 0x5d88,0x5d89,0x5d8a,0x5d8b,0x5d8c,0x5d8d,0x5d8e,0x5d8f,
+ 0x5d90,0x5d91,0x5d92,0x5d93,0x5d94,0x5d95,0x5d96,0x5d97,
+ 0x5d98,0x5d99,0x5d9a,0x5d9b,0x5d9c,0x5d9d,0x5d9e,0x5d9f,
+ 0x5da0,0x5da1,0x5da2,0x5da3,0x5da4,0x5da5,0x5da6,0x5da7,
+ 0x5da8,0x5da9,0x5daa,0x5dab,0x5dac,0x5dad,0x5dae,0x5daf,
+ 0x5db0,0x5db1,0x5db2,0x5db3,0x5db4,0x5db5,0x5db6,0x5db7,
+ 0x5db8,0x5db9,0x5dba,0x5dbb,0x5dbc,0x5dbd,0x5dbe,0x5dbf,
+ 0x5dc0,0x5dc1,0x5dc2,0x5dc3,0x5dc4,0x5dc5,0x5dc6,0x5dc7,
+ 0x5dc8,0x5dc9,0x5dca,0x5dcb,0x5dcc,0x5dcd,0x5dce,0x5dcf,
+ 0x5dd0,0x5dd1,0x5dd2,0x5dd3,0x5dd4,0x5dd5,0x5dd6,0x5dd7,
+ 0x5dd8,0x5dd9,0x5dda,0x5ddb,0x5ddc,0x5ddd,0x5dde,0x5ddf,
+ 0x5de0,0x5de1,0x5de2,0x5de3,0x5de4,0x5de5,0x5de6,0x5de7,
+ 0x5de8,0x5de9,0x5dea,0x5deb,0x5dec,0x5ded,0x5dee,0x5def,
+ 0x5df0,0x5df1,0x5df2,0x5df3,0x5df4,0x5df5,0x5df6,0x5df7,
+ 0x5df8,0x5df9,0x5dfa,0x5dfb,0x5dfc,0x5dfd,0x5dfe,0x5dff,
+ 0x5e00,0x5e01,0x5e02,0x5e03,0x5e04,0x5e05,0x5e06,0x5e07,
+ 0x5e08,0x5e09,0x5e0a,0x5e0b,0x5e0c,0x5e0d,0x5e0e,0x5e0f,
+ 0x5e10,0x5e11,0x5e12,0x5e13,0x5e14,0x5e15,0x5e16,0x5e17,
+ 0x5e18,0x5e19,0x5e1a,0x5e1b,0x5e1c,0x5e1d,0x5e1e,0x5e1f,
+ 0x5e20,0x5e21,0x5e22,0x5e23,0x5e24,0x5e25,0x5e26,0x5e27,
+ 0x5e28,0x5e29,0x5e2a,0x5e2b,0x5e2c,0x5e2d,0x5e2e,0x5e2f,
+ 0x5e30,0x5e31,0x5e32,0x5e33,0x5e34,0x5e35,0x5e36,0x5e37,
+ 0x5e38,0x5e39,0x5e3a,0x5e3b,0x5e3c,0x5e3d,0x5e3e,0x5e3f,
+ 0x5e40,0x5e41,0x5e42,0x5e43,0x5e44,0x5e45,0x5e46,0x5e47,
+ 0x5e48,0x5e49,0x5e4a,0x5e4b,0x5e4c,0x5e4d,0x5e4e,0x5e4f,
+ 0x5e50,0x5e51,0x5e52,0x5e53,0x5e54,0x5e55,0x5e56,0x5e57,
+ 0x5e58,0x5e59,0x5e5a,0x5e5b,0x5e5c,0x5e5d,0x5e5e,0x5e5f,
+ 0x5e60,0x5e61,0x5e62,0x5e63,0x5e64,0x5e65,0x5e66,0x5e67,
+ 0x5e68,0x5e69,0x5e6a,0x5e6b,0x5e6c,0x5e6d,0x5e6e,0x5e6f,
+ 0x5e70,0x5e71,0x5e72,0x5e73,0x5e74,0x5e75,0x5e76,0x5e77,
+ 0x5e78,0x5e79,0x5e7a,0x5e7b,0x5e7c,0x5e7d,0x5e7e,0x5e7f,
+ 0x5e80,0x5e81,0x5e82,0x5e83,0x5e84,0x5e85,0x5e86,0x5e87,
+ 0x5e88,0x5e89,0x5e8a,0x5e8b,0x5e8c,0x5e8d,0x5e8e,0x5e8f,
+ 0x5e90,0x5e91,0x5e92,0x5e93,0x5e94,0x5e95,0x5e96,0x5e97,
+ 0x5e98,0x5e99,0x5e9a,0x5e9b,0x5e9c,0x5e9d,0x5e9e,0x5e9f,
+ 0x5ea0,0x5ea1,0x5ea2,0x5ea3,0x5ea4,0x5ea5,0x5ea6,0x5ea7,
+ 0x5ea8,0x5ea9,0x5eaa,0x5eab,0x5eac,0x5ead,0x5eae,0x5eaf,
+ 0x5eb0,0x5eb1,0x5eb2,0x5eb3,0x5eb4,0x5eb5,0x5eb6,0x5eb7,
+ 0x5eb8,0x5eb9,0x5eba,0x5ebb,0x5ebc,0x5ebd,0x5ebe,0x5ebf,
+ 0x5ec0,0x5ec1,0x5ec2,0x5ec3,0x5ec4,0x5ec5,0x5ec6,0x5ec7,
+ 0x5ec8,0x5ec9,0x5eca,0x5ecb,0x5ecc,0x5ecd,0x5ece,0x5ecf,
+ 0x5ed0,0x5ed1,0x5ed2,0x5ed3,0x5ed4,0x5ed5,0x5ed6,0x5ed7,
+ 0x5ed8,0x5ed9,0x5eda,0x5edb,0x5edc,0x5edd,0x5ede,0x5edf,
+ 0x5ee0,0x5ee1,0x5ee2,0x5ee3,0x5ee4,0x5ee5,0x5ee6,0x5ee7,
+ 0x5ee8,0x5ee9,0x5eea,0x5eeb,0x5eec,0x5eed,0x5eee,0x5eef,
+ 0x5ef0,0x5ef1,0x5ef2,0x5ef3,0x5ef4,0x5ef5,0x5ef6,0x5ef7,
+ 0x5ef8,0x5ef9,0x5efa,0x5efb,0x5efc,0x5efd,0x5efe,0x5eff,
+ 0x5f00,0x5f01,0x5f02,0x5f03,0x5f04,0x5f05,0x5f06,0x5f07,
+ 0x5f08,0x5f09,0x5f0a,0x5f0b,0x5f0c,0x5f0d,0x5f0e,0x5f0f,
+ 0x5f10,0x5f11,0x5f12,0x5f13,0x5f14,0x5f15,0x5f16,0x5f17,
+ 0x5f18,0x5f19,0x5f1a,0x5f1b,0x5f1c,0x5f1d,0x5f1e,0x5f1f,
+ 0x5f20,0x5f21,0x5f22,0x5f23,0x5f24,0x5f25,0x5f26,0x5f27,
+ 0x5f28,0x5f29,0x5f2a,0x5f2b,0x5f2c,0x5f2d,0x5f2e,0x5f2f,
+ 0x5f30,0x5f31,0x5f32,0x5f33,0x5f34,0x5f35,0x5f36,0x5f37,
+ 0x5f38,0x5f39,0x5f3a,0x5f3b,0x5f3c,0x5f3d,0x5f3e,0x5f3f,
+ 0x5f40,0x5f41,0x5f42,0x5f43,0x5f44,0x5f45,0x5f46,0x5f47,
+ 0x5f48,0x5f49,0x5f4a,0x5f4b,0x5f4c,0x5f4d,0x5f4e,0x5f4f,
+ 0x5f50,0x5f51,0x5f52,0x5f53,0x5f54,0x5f55,0x5f56,0x5f57,
+ 0x5f58,0x5f59,0x5f5a,0x5f5b,0x5f5c,0x5f5d,0x5f5e,0x5f5f,
+ 0x5f60,0x5f61,0x5f62,0x5f63,0x5f64,0x5f65,0x5f66,0x5f67,
+ 0x5f68,0x5f69,0x5f6a,0x5f6b,0x5f6c,0x5f6d,0x5f6e,0x5f6f,
+ 0x5f70,0x5f71,0x5f72,0x5f73,0x5f74,0x5f75,0x5f76,0x5f77,
+ 0x5f78,0x5f79,0x5f7a,0x5f7b,0x5f7c,0x5f7d,0x5f7e,0x5f7f,
+ 0x5f80,0x5f81,0x5f82,0x5f83,0x5f84,0x5f85,0x5f86,0x5f87,
+ 0x5f88,0x5f89,0x5f8a,0x5f8b,0x5f8c,0x5f8d,0x5f8e,0x5f8f,
+ 0x5f90,0x5f91,0x5f92,0x5f93,0x5f94,0x5f95,0x5f96,0x5f97,
+ 0x5f98,0x5f99,0x5f9a,0x5f9b,0x5f9c,0x5f9d,0x5f9e,0x5f9f,
+ 0x5fa0,0x5fa1,0x5fa2,0x5fa3,0x5fa4,0x5fa5,0x5fa6,0x5fa7,
+ 0x5fa8,0x5fa9,0x5faa,0x5fab,0x5fac,0x5fad,0x5fae,0x5faf,
+ 0x5fb0,0x5fb1,0x5fb2,0x5fb3,0x5fb4,0x5fb5,0x5fb6,0x5fb7,
+ 0x5fb8,0x5fb9,0x5fba,0x5fbb,0x5fbc,0x5fbd,0x5fbe,0x5fbf,
+ 0x5fc0,0x5fc1,0x5fc2,0x5fc3,0x5fc4,0x5fc5,0x5fc6,0x5fc7,
+ 0x5fc8,0x5fc9,0x5fca,0x5fcb,0x5fcc,0x5fcd,0x5fce,0x5fcf,
+ 0x5fd0,0x5fd1,0x5fd2,0x5fd3,0x5fd4,0x5fd5,0x5fd6,0x5fd7,
+ 0x5fd8,0x5fd9,0x5fda,0x5fdb,0x5fdc,0x5fdd,0x5fde,0x5fdf,
+ 0x5fe0,0x5fe1,0x5fe2,0x5fe3,0x5fe4,0x5fe5,0x5fe6,0x5fe7,
+ 0x5fe8,0x5fe9,0x5fea,0x5feb,0x5fec,0x5fed,0x5fee,0x5fef,
+ 0x5ff0,0x5ff1,0x5ff2,0x5ff3,0x5ff4,0x5ff5,0x5ff6,0x5ff7,
+ 0x5ff8,0x5ff9,0x5ffa,0x5ffb,0x5ffc,0x5ffd,0x5ffe,0x5fff,
+ 0x6000,0x6001,0x6002,0x6003,0x6004,0x6005,0x6006,0x6007,
+ 0x6008,0x6009,0x600a,0x600b,0x600c,0x600d,0x600e,0x600f,
+ 0x6010,0x6011,0x6012,0x6013,0x6014,0x6015,0x6016,0x6017,
+ 0x6018,0x6019,0x601a,0x601b,0x601c,0x601d,0x601e,0x601f,
+ 0x6020,0x6021,0x6022,0x6023,0x6024,0x6025,0x6026,0x6027,
+ 0x6028,0x6029,0x602a,0x602b,0x602c,0x602d,0x602e,0x602f,
+ 0x6030,0x6031,0x6032,0x6033,0x6034,0x6035,0x6036,0x6037,
+ 0x6038,0x6039,0x603a,0x603b,0x603c,0x603d,0x603e,0x603f,
+ 0x6040,0x6041,0x6042,0x6043,0x6044,0x6045,0x6046,0x6047,
+ 0x6048,0x6049,0x604a,0x604b,0x604c,0x604d,0x604e,0x604f,
+ 0x6050,0x6051,0x6052,0x6053,0x6054,0x6055,0x6056,0x6057,
+ 0x6058,0x6059,0x605a,0x605b,0x605c,0x605d,0x605e,0x605f,
+ 0x6060,0x6061,0x6062,0x6063,0x6064,0x6065,0x6066,0x6067,
+ 0x6068,0x6069,0x606a,0x606b,0x606c,0x606d,0x606e,0x606f,
+ 0x6070,0x6071,0x6072,0x6073,0x6074,0x6075,0x6076,0x6077,
+ 0x6078,0x6079,0x607a,0x607b,0x607c,0x607d,0x607e,0x607f,
+ 0x6080,0x6081,0x6082,0x6083,0x6084,0x6085,0x6086,0x6087,
+ 0x6088,0x6089,0x608a,0x608b,0x608c,0x608d,0x608e,0x608f,
+ 0x6090,0x6091,0x6092,0x6093,0x6094,0x6095,0x6096,0x6097,
+ 0x6098,0x6099,0x609a,0x609b,0x609c,0x609d,0x609e,0x609f,
+ 0x60a0,0x60a1,0x60a2,0x60a3,0x60a4,0x60a5,0x60a6,0x60a7,
+ 0x60a8,0x60a9,0x60aa,0x60ab,0x60ac,0x60ad,0x60ae,0x60af,
+ 0x60b0,0x60b1,0x60b2,0x60b3,0x60b4,0x60b5,0x60b6,0x60b7,
+ 0x60b8,0x60b9,0x60ba,0x60bb,0x60bc,0x60bd,0x60be,0x60bf,
+ 0x60c0,0x60c1,0x60c2,0x60c3,0x60c4,0x60c5,0x60c6,0x60c7,
+ 0x60c8,0x60c9,0x60ca,0x60cb,0x60cc,0x60cd,0x60ce,0x60cf,
+ 0x60d0,0x60d1,0x60d2,0x60d3,0x60d4,0x60d5,0x60d6,0x60d7,
+ 0x60d8,0x60d9,0x60da,0x60db,0x60dc,0x60dd,0x60de,0x60df,
+ 0x60e0,0x60e1,0x60e2,0x60e3,0x60e4,0x60e5,0x60e6,0x60e7,
+ 0x60e8,0x60e9,0x60ea,0x60eb,0x60ec,0x60ed,0x60ee,0x60ef,
+ 0x60f0,0x60f1,0x60f2,0x60f3,0x60f4,0x60f5,0x60f6,0x60f7,
+ 0x60f8,0x60f9,0x60fa,0x60fb,0x60fc,0x60fd,0x60fe,0x60ff,
+ 0x6100,0x6101,0x6102,0x6103,0x6104,0x6105,0x6106,0x6107,
+ 0x6108,0x6109,0x610a,0x610b,0x610c,0x610d,0x610e,0x610f,
+ 0x6110,0x6111,0x6112,0x6113,0x6114,0x6115,0x6116,0x6117,
+ 0x6118,0x6119,0x611a,0x611b,0x611c,0x611d,0x611e,0x611f,
+ 0x6120,0x6121,0x6122,0x6123,0x6124,0x6125,0x6126,0x6127,
+ 0x6128,0x6129,0x612a,0x612b,0x612c,0x612d,0x612e,0x612f,
+ 0x6130,0x6131,0x6132,0x6133,0x6134,0x6135,0x6136,0x6137,
+ 0x6138,0x6139,0x613a,0x613b,0x613c,0x613d,0x613e,0x613f,
+ 0x6140,0x6141,0x6142,0x6143,0x6144,0x6145,0x6146,0x6147,
+ 0x6148,0x6149,0x614a,0x614b,0x614c,0x614d,0x614e,0x614f,
+ 0x6150,0x6151,0x6152,0x6153,0x6154,0x6155,0x6156,0x6157,
+ 0x6158,0x6159,0x615a,0x615b,0x615c,0x615d,0x615e,0x615f,
+ 0x6160,0x6161,0x6162,0x6163,0x6164,0x6165,0x6166,0x6167,
+ 0x6168,0x6169,0x616a,0x616b,0x616c,0x616d,0x616e,0x616f,
+ 0x6170,0x6171,0x6172,0x6173,0x6174,0x6175,0x6176,0x6177,
+ 0x6178,0x6179,0x617a,0x617b,0x617c,0x617d,0x617e,0x617f,
+ 0x6180,0x6181,0x6182,0x6183,0x6184,0x6185,0x6186,0x6187,
+ 0x6188,0x6189,0x618a,0x618b,0x618c,0x618d,0x618e,0x618f,
+ 0x6190,0x6191,0x6192,0x6193,0x6194,0x6195,0x6196,0x6197,
+ 0x6198,0x6199,0x619a,0x619b,0x619c,0x619d,0x619e,0x619f,
+ 0x61a0,0x61a1,0x61a2,0x61a3,0x61a4,0x61a5,0x61a6,0x61a7,
+ 0x61a8,0x61a9,0x61aa,0x61ab,0x61ac,0x61ad,0x61ae,0x61af,
+ 0x61b0,0x61b1,0x61b2,0x61b3,0x61b4,0x61b5,0x61b6,0x61b7,
+ 0x61b8,0x61b9,0x61ba,0x61bb,0x61bc,0x61bd,0x61be,0x61bf,
+ 0x61c0,0x61c1,0x61c2,0x61c3,0x61c4,0x61c5,0x61c6,0x61c7,
+ 0x61c8,0x61c9,0x61ca,0x61cb,0x61cc,0x61cd,0x61ce,0x61cf,
+ 0x61d0,0x61d1,0x61d2,0x61d3,0x61d4,0x61d5,0x61d6,0x61d7,
+ 0x61d8,0x61d9,0x61da,0x61db,0x61dc,0x61dd,0x61de,0x61df,
+ 0x61e0,0x61e1,0x61e2,0x61e3,0x61e4,0x61e5,0x61e6,0x61e7,
+ 0x61e8,0x61e9,0x61ea,0x61eb,0x61ec,0x61ed,0x61ee,0x61ef,
+ 0x61f0,0x61f1,0x61f2,0x61f3,0x61f4,0x61f5,0x61f6,0x61f7,
+ 0x61f8,0x61f9,0x61fa,0x61fb,0x61fc,0x61fd,0x61fe,0x61ff,
+ 0x6200,0x6201,0x6202,0x6203,0x6204,0x6205,0x6206,0x6207,
+ 0x6208,0x6209,0x620a,0x620b,0x620c,0x620d,0x620e,0x620f,
+ 0x6210,0x6211,0x6212,0x6213,0x6214,0x6215,0x6216,0x6217,
+ 0x6218,0x6219,0x621a,0x621b,0x621c,0x621d,0x621e,0x621f,
+ 0x6220,0x6221,0x6222,0x6223,0x6224,0x6225,0x6226,0x6227,
+ 0x6228,0x6229,0x622a,0x622b,0x622c,0x622d,0x622e,0x622f,
+ 0x6230,0x6231,0x6232,0x6233,0x6234,0x6235,0x6236,0x6237,
+ 0x6238,0x6239,0x623a,0x623b,0x623c,0x623d,0x623e,0x623f,
+ 0x6240,0x6241,0x6242,0x6243,0x6244,0x6245,0x6246,0x6247,
+ 0x6248,0x6249,0x624a,0x624b,0x624c,0x624d,0x624e,0x624f,
+ 0x6250,0x6251,0x6252,0x6253,0x6254,0x6255,0x6256,0x6257,
+ 0x6258,0x6259,0x625a,0x625b,0x625c,0x625d,0x625e,0x625f,
+ 0x6260,0x6261,0x6262,0x6263,0x6264,0x6265,0x6266,0x6267,
+ 0x6268,0x6269,0x626a,0x626b,0x626c,0x626d,0x626e,0x626f,
+ 0x6270,0x6271,0x6272,0x6273,0x6274,0x6275,0x6276,0x6277,
+ 0x6278,0x6279,0x627a,0x627b,0x627c,0x627d,0x627e,0x627f,
+ 0x6280,0x6281,0x6282,0x6283,0x6284,0x6285,0x6286,0x6287,
+ 0x6288,0x6289,0x628a,0x628b,0x628c,0x628d,0x628e,0x628f,
+ 0x6290,0x6291,0x6292,0x6293,0x6294,0x6295,0x6296,0x6297,
+ 0x6298,0x6299,0x629a,0x629b,0x629c,0x629d,0x629e,0x629f,
+ 0x62a0,0x62a1,0x62a2,0x62a3,0x62a4,0x62a5,0x62a6,0x62a7,
+ 0x62a8,0x62a9,0x62aa,0x62ab,0x62ac,0x62ad,0x62ae,0x62af,
+ 0x62b0,0x62b1,0x62b2,0x62b3,0x62b4,0x62b5,0x62b6,0x62b7,
+ 0x62b8,0x62b9,0x62ba,0x62bb,0x62bc,0x62bd,0x62be,0x62bf,
+ 0x62c0,0x62c1,0x62c2,0x62c3,0x62c4,0x62c5,0x62c6,0x62c7,
+ 0x62c8,0x62c9,0x62ca,0x62cb,0x62cc,0x62cd,0x62ce,0x62cf,
+ 0x62d0,0x62d1,0x62d2,0x62d3,0x62d4,0x62d5,0x62d6,0x62d7,
+ 0x62d8,0x62d9,0x62da,0x62db,0x62dc,0x62dd,0x62de,0x62df,
+ 0x62e0,0x62e1,0x62e2,0x62e3,0x62e4,0x62e5,0x62e6,0x62e7,
+ 0x62e8,0x62e9,0x62ea,0x62eb,0x62ec,0x62ed,0x62ee,0x62ef,
+ 0x62f0,0x62f1,0x62f2,0x62f3,0x62f4,0x62f5,0x62f6,0x62f7,
+ 0x62f8,0x62f9,0x62fa,0x62fb,0x62fc,0x62fd,0x62fe,0x62ff,
+ 0x6300,0x6301,0x6302,0x6303,0x6304,0x6305,0x6306,0x6307,
+ 0x6308,0x6309,0x630a,0x630b,0x630c,0x630d,0x630e,0x630f,
+ 0x6310,0x6311,0x6312,0x6313,0x6314,0x6315,0x6316,0x6317,
+ 0x6318,0x6319,0x631a,0x631b,0x631c,0x631d,0x631e,0x631f,
+ 0x6320,0x6321,0x6322,0x6323,0x6324,0x6325,0x6326,0x6327,
+ 0x6328,0x6329,0x632a,0x632b,0x632c,0x632d,0x632e,0x632f,
+ 0x6330,0x6331,0x6332,0x6333,0x6334,0x6335,0x6336,0x6337,
+ 0x6338,0x6339,0x633a,0x633b,0x633c,0x633d,0x633e,0x633f,
+ 0x6340,0x6341,0x6342,0x6343,0x6344,0x6345,0x6346,0x6347,
+ 0x6348,0x6349,0x634a,0x634b,0x634c,0x634d,0x634e,0x634f,
+ 0x6350,0x6351,0x6352,0x6353,0x6354,0x6355,0x6356,0x6357,
+ 0x6358,0x6359,0x635a,0x635b,0x635c,0x635d,0x635e,0x635f,
+ 0x6360,0x6361,0x6362,0x6363,0x6364,0x6365,0x6366,0x6367,
+ 0x6368,0x6369,0x636a,0x636b,0x636c,0x636d,0x636e,0x636f,
+ 0x6370,0x6371,0x6372,0x6373,0x6374,0x6375,0x6376,0x6377,
+ 0x6378,0x6379,0x637a,0x637b,0x637c,0x637d,0x637e,0x637f,
+ 0x6380,0x6381,0x6382,0x6383,0x6384,0x6385,0x6386,0x6387,
+ 0x6388,0x6389,0x638a,0x638b,0x638c,0x638d,0x638e,0x638f,
+ 0x6390,0x6391,0x6392,0x6393,0x6394,0x6395,0x6396,0x6397,
+ 0x6398,0x6399,0x639a,0x639b,0x639c,0x639d,0x639e,0x639f,
+ 0x63a0,0x63a1,0x63a2,0x63a3,0x63a4,0x63a5,0x63a6,0x63a7,
+ 0x63a8,0x63a9,0x63aa,0x63ab,0x63ac,0x63ad,0x63ae,0x63af,
+ 0x63b0,0x63b1,0x63b2,0x63b3,0x63b4,0x63b5,0x63b6,0x63b7,
+ 0x63b8,0x63b9,0x63ba,0x63bb,0x63bc,0x63bd,0x63be,0x63bf,
+ 0x63c0,0x63c1,0x63c2,0x63c3,0x63c4,0x63c5,0x63c6,0x63c7,
+ 0x63c8,0x63c9,0x63ca,0x63cb,0x63cc,0x63cd,0x63ce,0x63cf,
+ 0x63d0,0x63d1,0x63d2,0x63d3,0x63d4,0x63d5,0x63d6,0x63d7,
+ 0x63d8,0x63d9,0x63da,0x63db,0x63dc,0x63dd,0x63de,0x63df,
+ 0x63e0,0x63e1,0x63e2,0x63e3,0x63e4,0x63e5,0x63e6,0x63e7,
+ 0x63e8,0x63e9,0x63ea,0x63eb,0x63ec,0x63ed,0x63ee,0x63ef,
+ 0x63f0,0x63f1,0x63f2,0x63f3,0x63f4,0x63f5,0x63f6,0x63f7,
+ 0x63f8,0x63f9,0x63fa,0x63fb,0x63fc,0x63fd,0x63fe,0x63ff,
+ 0x6400,0x6401,0x6402,0x6403,0x6404,0x6405,0x6406,0x6407,
+ 0x6408,0x6409,0x640a,0x640b,0x640c,0x640d,0x640e,0x640f,
+ 0x6410,0x6411,0x6412,0x6413,0x6414,0x6415,0x6416,0x6417,
+ 0x6418,0x6419,0x641a,0x641b,0x641c,0x641d,0x641e,0x641f,
+ 0x6420,0x6421,0x6422,0x6423,0x6424,0x6425,0x6426,0x6427,
+ 0x6428,0x6429,0x642a,0x642b,0x642c,0x642d,0x642e,0x642f,
+ 0x6430,0x6431,0x6432,0x6433,0x6434,0x6435,0x6436,0x6437,
+ 0x6438,0x6439,0x643a,0x643b,0x643c,0x643d,0x643e,0x643f,
+ 0x6440,0x6441,0x6442,0x6443,0x6444,0x6445,0x6446,0x6447,
+ 0x6448,0x6449,0x644a,0x644b,0x644c,0x644d,0x644e,0x644f,
+ 0x6450,0x6451,0x6452,0x6453,0x6454,0x6455,0x6456,0x6457,
+ 0x6458,0x6459,0x645a,0x645b,0x645c,0x645d,0x645e,0x645f,
+ 0x6460,0x6461,0x6462,0x6463,0x6464,0x6465,0x6466,0x6467,
+ 0x6468,0x6469,0x646a,0x646b,0x646c,0x646d,0x646e,0x646f,
+ 0x6470,0x6471,0x6472,0x6473,0x6474,0x6475,0x6476,0x6477,
+ 0x6478,0x6479,0x647a,0x647b,0x647c,0x647d,0x647e,0x647f,
+ 0x6480,0x6481,0x6482,0x6483,0x6484,0x6485,0x6486,0x6487,
+ 0x6488,0x6489,0x648a,0x648b,0x648c,0x648d,0x648e,0x648f,
+ 0x6490,0x6491,0x6492,0x6493,0x6494,0x6495,0x6496,0x6497,
+ 0x6498,0x6499,0x649a,0x649b,0x649c,0x649d,0x649e,0x649f,
+ 0x64a0,0x64a1,0x64a2,0x64a3,0x64a4,0x64a5,0x64a6,0x64a7,
+ 0x64a8,0x64a9,0x64aa,0x64ab,0x64ac,0x64ad,0x64ae,0x64af,
+ 0x64b0,0x64b1,0x64b2,0x64b3,0x64b4,0x64b5,0x64b6,0x64b7,
+ 0x64b8,0x64b9,0x64ba,0x64bb,0x64bc,0x64bd,0x64be,0x64bf,
+ 0x64c0,0x64c1,0x64c2,0x64c3,0x64c4,0x64c5,0x64c6,0x64c7,
+ 0x64c8,0x64c9,0x64ca,0x64cb,0x64cc,0x64cd,0x64ce,0x64cf,
+ 0x64d0,0x64d1,0x64d2,0x64d3,0x64d4,0x64d5,0x64d6,0x64d7,
+ 0x64d8,0x64d9,0x64da,0x64db,0x64dc,0x64dd,0x64de,0x64df,
+ 0x64e0,0x64e1,0x64e2,0x64e3,0x64e4,0x64e5,0x64e6,0x64e7,
+ 0x64e8,0x64e9,0x64ea,0x64eb,0x64ec,0x64ed,0x64ee,0x64ef,
+ 0x64f0,0x64f1,0x64f2,0x64f3,0x64f4,0x64f5,0x64f6,0x64f7,
+ 0x64f8,0x64f9,0x64fa,0x64fb,0x64fc,0x64fd,0x64fe,0x64ff,
+ 0x6500,0x6501,0x6502,0x6503,0x6504,0x6505,0x6506,0x6507,
+ 0x6508,0x6509,0x650a,0x650b,0x650c,0x650d,0x650e,0x650f,
+ 0x6510,0x6511,0x6512,0x6513,0x6514,0x6515,0x6516,0x6517,
+ 0x6518,0x6519,0x651a,0x651b,0x651c,0x651d,0x651e,0x651f,
+ 0x6520,0x6521,0x6522,0x6523,0x6524,0x6525,0x6526,0x6527,
+ 0x6528,0x6529,0x652a,0x652b,0x652c,0x652d,0x652e,0x652f,
+ 0x6530,0x6531,0x6532,0x6533,0x6534,0x6535,0x6536,0x6537,
+ 0x6538,0x6539,0x653a,0x653b,0x653c,0x653d,0x653e,0x653f,
+ 0x6540,0x6541,0x6542,0x6543,0x6544,0x6545,0x6546,0x6547,
+ 0x6548,0x6549,0x654a,0x654b,0x654c,0x654d,0x654e,0x654f,
+ 0x6550,0x6551,0x6552,0x6553,0x6554,0x6555,0x6556,0x6557,
+ 0x6558,0x6559,0x655a,0x655b,0x655c,0x655d,0x655e,0x655f,
+ 0x6560,0x6561,0x6562,0x6563,0x6564,0x6565,0x6566,0x6567,
+ 0x6568,0x6569,0x656a,0x656b,0x656c,0x656d,0x656e,0x656f,
+ 0x6570,0x6571,0x6572,0x6573,0x6574,0x6575,0x6576,0x6577,
+ 0x6578,0x6579,0x657a,0x657b,0x657c,0x657d,0x657e,0x657f,
+ 0x6580,0x6581,0x6582,0x6583,0x6584,0x6585,0x6586,0x6587,
+ 0x6588,0x6589,0x658a,0x658b,0x658c,0x658d,0x658e,0x658f,
+ 0x6590,0x6591,0x6592,0x6593,0x6594,0x6595,0x6596,0x6597,
+ 0x6598,0x6599,0x659a,0x659b,0x659c,0x659d,0x659e,0x659f,
+ 0x65a0,0x65a1,0x65a2,0x65a3,0x65a4,0x65a5,0x65a6,0x65a7,
+ 0x65a8,0x65a9,0x65aa,0x65ab,0x65ac,0x65ad,0x65ae,0x65af,
+ 0x65b0,0x65b1,0x65b2,0x65b3,0x65b4,0x65b5,0x65b6,0x65b7,
+ 0x65b8,0x65b9,0x65ba,0x65bb,0x65bc,0x65bd,0x65be,0x65bf,
+ 0x65c0,0x65c1,0x65c2,0x65c3,0x65c4,0x65c5,0x65c6,0x65c7,
+ 0x65c8,0x65c9,0x65ca,0x65cb,0x65cc,0x65cd,0x65ce,0x65cf,
+ 0x65d0,0x65d1,0x65d2,0x65d3,0x65d4,0x65d5,0x65d6,0x65d7,
+ 0x65d8,0x65d9,0x65da,0x65db,0x65dc,0x65dd,0x65de,0x65df,
+ 0x65e0,0x65e1,0x65e2,0x65e3,0x65e4,0x65e5,0x65e6,0x65e7,
+ 0x65e8,0x65e9,0x65ea,0x65eb,0x65ec,0x65ed,0x65ee,0x65ef,
+ 0x65f0,0x65f1,0x65f2,0x65f3,0x65f4,0x65f5,0x65f6,0x65f7,
+ 0x65f8,0x65f9,0x65fa,0x65fb,0x65fc,0x65fd,0x65fe,0x65ff,
+ 0x6600,0x6601,0x6602,0x6603,0x6604,0x6605,0x6606,0x6607,
+ 0x6608,0x6609,0x660a,0x660b,0x660c,0x660d,0x660e,0x660f,
+ 0x6610,0x6611,0x6612,0x6613,0x6614,0x6615,0x6616,0x6617,
+ 0x6618,0x6619,0x661a,0x661b,0x661c,0x661d,0x661e,0x661f,
+ 0x6620,0x6621,0x6622,0x6623,0x6624,0x6625,0x6626,0x6627,
+ 0x6628,0x6629,0x662a,0x662b,0x662c,0x662d,0x662e,0x662f,
+ 0x6630,0x6631,0x6632,0x6633,0x6634,0x6635,0x6636,0x6637,
+ 0x6638,0x6639,0x663a,0x663b,0x663c,0x663d,0x663e,0x663f,
+ 0x6640,0x6641,0x6642,0x6643,0x6644,0x6645,0x6646,0x6647,
+ 0x6648,0x6649,0x664a,0x664b,0x664c,0x664d,0x664e,0x664f,
+ 0x6650,0x6651,0x6652,0x6653,0x6654,0x6655,0x6656,0x6657,
+ 0x6658,0x6659,0x665a,0x665b,0x665c,0x665d,0x665e,0x665f,
+ 0x6660,0x6661,0x6662,0x6663,0x6664,0x6665,0x6666,0x6667,
+ 0x6668,0x6669,0x666a,0x666b,0x666c,0x666d,0x666e,0x666f,
+ 0x6670,0x6671,0x6672,0x6673,0x6674,0x6675,0x6676,0x6677,
+ 0x6678,0x6679,0x667a,0x667b,0x667c,0x667d,0x667e,0x667f,
+ 0x6680,0x6681,0x6682,0x6683,0x6684,0x6685,0x6686,0x6687,
+ 0x6688,0x6689,0x668a,0x668b,0x668c,0x668d,0x668e,0x668f,
+ 0x6690,0x6691,0x6692,0x6693,0x6694,0x6695,0x6696,0x6697,
+ 0x6698,0x6699,0x669a,0x669b,0x669c,0x669d,0x669e,0x669f,
+ 0x66a0,0x66a1,0x66a2,0x66a3,0x66a4,0x66a5,0x66a6,0x66a7,
+ 0x66a8,0x66a9,0x66aa,0x66ab,0x66ac,0x66ad,0x66ae,0x66af,
+ 0x66b0,0x66b1,0x66b2,0x66b3,0x66b4,0x66b5,0x66b6,0x66b7,
+ 0x66b8,0x66b9,0x66ba,0x66bb,0x66bc,0x66bd,0x66be,0x66bf,
+ 0x66c0,0x66c1,0x66c2,0x66c3,0x66c4,0x66c5,0x66c6,0x66c7,
+ 0x66c8,0x66c9,0x66ca,0x66cb,0x66cc,0x66cd,0x66ce,0x66cf,
+ 0x66d0,0x66d1,0x66d2,0x66d3,0x66d4,0x66d5,0x66d6,0x66d7,
+ 0x66d8,0x66d9,0x66da,0x66db,0x66dc,0x66dd,0x66de,0x66df,
+ 0x66e0,0x66e1,0x66e2,0x66e3,0x66e4,0x66e5,0x66e6,0x66e7,
+ 0x66e8,0x66e9,0x66ea,0x66eb,0x66ec,0x66ed,0x66ee,0x66ef,
+ 0x66f0,0x66f1,0x66f2,0x66f3,0x66f4,0x66f5,0x66f6,0x66f7,
+ 0x66f8,0x66f9,0x66fa,0x66fb,0x66fc,0x66fd,0x66fe,0x66ff,
+ 0x6700,0x6701,0x6702,0x6703,0x6704,0x6705,0x6706,0x6707,
+ 0x6708,0x6709,0x670a,0x670b,0x670c,0x670d,0x670e,0x670f,
+ 0x6710,0x6711,0x6712,0x6713,0x6714,0x6715,0x6716,0x6717,
+ 0x6718,0x6719,0x671a,0x671b,0x671c,0x671d,0x671e,0x671f,
+ 0x6720,0x6721,0x6722,0x6723,0x6724,0x6725,0x6726,0x6727,
+ 0x6728,0x6729,0x672a,0x672b,0x672c,0x672d,0x672e,0x672f,
+ 0x6730,0x6731,0x6732,0x6733,0x6734,0x6735,0x6736,0x6737,
+ 0x6738,0x6739,0x673a,0x673b,0x673c,0x673d,0x673e,0x673f,
+ 0x6740,0x6741,0x6742,0x6743,0x6744,0x6745,0x6746,0x6747,
+ 0x6748,0x6749,0x674a,0x674b,0x674c,0x674d,0x674e,0x674f,
+ 0x6750,0x6751,0x6752,0x6753,0x6754,0x6755,0x6756,0x6757,
+ 0x6758,0x6759,0x675a,0x675b,0x675c,0x675d,0x675e,0x675f,
+ 0x6760,0x6761,0x6762,0x6763,0x6764,0x6765,0x6766,0x6767,
+ 0x6768,0x6769,0x676a,0x676b,0x676c,0x676d,0x676e,0x676f,
+ 0x6770,0x6771,0x6772,0x6773,0x6774,0x6775,0x6776,0x6777,
+ 0x6778,0x6779,0x677a,0x677b,0x677c,0x677d,0x677e,0x677f,
+ 0x6780,0x6781,0x6782,0x6783,0x6784,0x6785,0x6786,0x6787,
+ 0x6788,0x6789,0x678a,0x678b,0x678c,0x678d,0x678e,0x678f,
+ 0x6790,0x6791,0x6792,0x6793,0x6794,0x6795,0x6796,0x6797,
+ 0x6798,0x6799,0x679a,0x679b,0x679c,0x679d,0x679e,0x679f,
+ 0x67a0,0x67a1,0x67a2,0x67a3,0x67a4,0x67a5,0x67a6,0x67a7,
+ 0x67a8,0x67a9,0x67aa,0x67ab,0x67ac,0x67ad,0x67ae,0x67af,
+ 0x67b0,0x67b1,0x67b2,0x67b3,0x67b4,0x67b5,0x67b6,0x67b7,
+ 0x67b8,0x67b9,0x67ba,0x67bb,0x67bc,0x67bd,0x67be,0x67bf,
+ 0x67c0,0x67c1,0x67c2,0x67c3,0x67c4,0x67c5,0x67c6,0x67c7,
+ 0x67c8,0x67c9,0x67ca,0x67cb,0x67cc,0x67cd,0x67ce,0x67cf,
+ 0x67d0,0x67d1,0x67d2,0x67d3,0x67d4,0x67d5,0x67d6,0x67d7,
+ 0x67d8,0x67d9,0x67da,0x67db,0x67dc,0x67dd,0x67de,0x67df,
+ 0x67e0,0x67e1,0x67e2,0x67e3,0x67e4,0x67e5,0x67e6,0x67e7,
+ 0x67e8,0x67e9,0x67ea,0x67eb,0x67ec,0x67ed,0x67ee,0x67ef,
+ 0x67f0,0x67f1,0x67f2,0x67f3,0x67f4,0x67f5,0x67f6,0x67f7,
+ 0x67f8,0x67f9,0x67fa,0x67fb,0x67fc,0x67fd,0x67fe,0x67ff,
+ 0x6800,0x6801,0x6802,0x6803,0x6804,0x6805,0x6806,0x6807,
+ 0x6808,0x6809,0x680a,0x680b,0x680c,0x680d,0x680e,0x680f,
+ 0x6810,0x6811,0x6812,0x6813,0x6814,0x6815,0x6816,0x6817,
+ 0x6818,0x6819,0x681a,0x681b,0x681c,0x681d,0x681e,0x681f,
+ 0x6820,0x6821,0x6822,0x6823,0x6824,0x6825,0x6826,0x6827,
+ 0x6828,0x6829,0x682a,0x682b,0x682c,0x682d,0x682e,0x682f,
+ 0x6830,0x6831,0x6832,0x6833,0x6834,0x6835,0x6836,0x6837,
+ 0x6838,0x6839,0x683a,0x683b,0x683c,0x683d,0x683e,0x683f,
+ 0x6840,0x6841,0x6842,0x6843,0x6844,0x6845,0x6846,0x6847,
+ 0x6848,0x6849,0x684a,0x684b,0x684c,0x684d,0x684e,0x684f,
+ 0x6850,0x6851,0x6852,0x6853,0x6854,0x6855,0x6856,0x6857,
+ 0x6858,0x6859,0x685a,0x685b,0x685c,0x685d,0x685e,0x685f,
+ 0x6860,0x6861,0x6862,0x6863,0x6864,0x6865,0x6866,0x6867,
+ 0x6868,0x6869,0x686a,0x686b,0x686c,0x686d,0x686e,0x686f,
+ 0x6870,0x6871,0x6872,0x6873,0x6874,0x6875,0x6876,0x6877,
+ 0x6878,0x6879,0x687a,0x687b,0x687c,0x687d,0x687e,0x687f,
+ 0x6880,0x6881,0x6882,0x6883,0x6884,0x6885,0x6886,0x6887,
+ 0x6888,0x6889,0x688a,0x688b,0x688c,0x688d,0x688e,0x688f,
+ 0x6890,0x6891,0x6892,0x6893,0x6894,0x6895,0x6896,0x6897,
+ 0x6898,0x6899,0x689a,0x689b,0x689c,0x689d,0x689e,0x689f,
+ 0x68a0,0x68a1,0x68a2,0x68a3,0x68a4,0x68a5,0x68a6,0x68a7,
+ 0x68a8,0x68a9,0x68aa,0x68ab,0x68ac,0x68ad,0x68ae,0x68af,
+ 0x68b0,0x68b1,0x68b2,0x68b3,0x68b4,0x68b5,0x68b6,0x68b7,
+ 0x68b8,0x68b9,0x68ba,0x68bb,0x68bc,0x68bd,0x68be,0x68bf,
+ 0x68c0,0x68c1,0x68c2,0x68c3,0x68c4,0x68c5,0x68c6,0x68c7,
+ 0x68c8,0x68c9,0x68ca,0x68cb,0x68cc,0x68cd,0x68ce,0x68cf,
+ 0x68d0,0x68d1,0x68d2,0x68d3,0x68d4,0x68d5,0x68d6,0x68d7,
+ 0x68d8,0x68d9,0x68da,0x68db,0x68dc,0x68dd,0x68de,0x68df,
+ 0x68e0,0x68e1,0x68e2,0x68e3,0x68e4,0x68e5,0x68e6,0x68e7,
+ 0x68e8,0x68e9,0x68ea,0x68eb,0x68ec,0x68ed,0x68ee,0x68ef,
+ 0x68f0,0x68f1,0x68f2,0x68f3,0x68f4,0x68f5,0x68f6,0x68f7,
+ 0x68f8,0x68f9,0x68fa,0x68fb,0x68fc,0x68fd,0x68fe,0x68ff,
+ 0x6900,0x6901,0x6902,0x6903,0x6904,0x6905,0x6906,0x6907,
+ 0x6908,0x6909,0x690a,0x690b,0x690c,0x690d,0x690e,0x690f,
+ 0x6910,0x6911,0x6912,0x6913,0x6914,0x6915,0x6916,0x6917,
+ 0x6918,0x6919,0x691a,0x691b,0x691c,0x691d,0x691e,0x691f,
+ 0x6920,0x6921,0x6922,0x6923,0x6924,0x6925,0x6926,0x6927,
+ 0x6928,0x6929,0x692a,0x692b,0x692c,0x692d,0x692e,0x692f,
+ 0x6930,0x6931,0x6932,0x6933,0x6934,0x6935,0x6936,0x6937,
+ 0x6938,0x6939,0x693a,0x693b,0x693c,0x693d,0x693e,0x693f,
+ 0x6940,0x6941,0x6942,0x6943,0x6944,0x6945,0x6946,0x6947,
+ 0x6948,0x6949,0x694a,0x694b,0x694c,0x694d,0x694e,0x694f,
+ 0x6950,0x6951,0x6952,0x6953,0x6954,0x6955,0x6956,0x6957,
+ 0x6958,0x6959,0x695a,0x695b,0x695c,0x695d,0x695e,0x695f,
+ 0x6960,0x6961,0x6962,0x6963,0x6964,0x6965,0x6966,0x6967,
+ 0x6968,0x6969,0x696a,0x696b,0x696c,0x696d,0x696e,0x696f,
+ 0x6970,0x6971,0x6972,0x6973,0x6974,0x6975,0x6976,0x6977,
+ 0x6978,0x6979,0x697a,0x697b,0x697c,0x697d,0x697e,0x697f,
+ 0x6980,0x6981,0x6982,0x6983,0x6984,0x6985,0x6986,0x6987,
+ 0x6988,0x6989,0x698a,0x698b,0x698c,0x698d,0x698e,0x698f,
+ 0x6990,0x6991,0x6992,0x6993,0x6994,0x6995,0x6996,0x6997,
+ 0x6998,0x6999,0x699a,0x699b,0x699c,0x699d,0x699e,0x699f,
+ 0x69a0,0x69a1,0x69a2,0x69a3,0x69a4,0x69a5,0x69a6,0x69a7,
+ 0x69a8,0x69a9,0x69aa,0x69ab,0x69ac,0x69ad,0x69ae,0x69af,
+ 0x69b0,0x69b1,0x69b2,0x69b3,0x69b4,0x69b5,0x69b6,0x69b7,
+ 0x69b8,0x69b9,0x69ba,0x69bb,0x69bc,0x69bd,0x69be,0x69bf,
+ 0x69c0,0x69c1,0x69c2,0x69c3,0x69c4,0x69c5,0x69c6,0x69c7,
+ 0x69c8,0x69c9,0x69ca,0x69cb,0x69cc,0x69cd,0x69ce,0x69cf,
+ 0x69d0,0x69d1,0x69d2,0x69d3,0x69d4,0x69d5,0x69d6,0x69d7,
+ 0x69d8,0x69d9,0x69da,0x69db,0x69dc,0x69dd,0x69de,0x69df,
+ 0x69e0,0x69e1,0x69e2,0x69e3,0x69e4,0x69e5,0x69e6,0x69e7,
+ 0x69e8,0x69e9,0x69ea,0x69eb,0x69ec,0x69ed,0x69ee,0x69ef,
+ 0x69f0,0x69f1,0x69f2,0x69f3,0x69f4,0x69f5,0x69f6,0x69f7,
+ 0x69f8,0x69f9,0x69fa,0x69fb,0x69fc,0x69fd,0x69fe,0x69ff,
+ 0x6a00,0x6a01,0x6a02,0x6a03,0x6a04,0x6a05,0x6a06,0x6a07,
+ 0x6a08,0x6a09,0x6a0a,0x6a0b,0x6a0c,0x6a0d,0x6a0e,0x6a0f,
+ 0x6a10,0x6a11,0x6a12,0x6a13,0x6a14,0x6a15,0x6a16,0x6a17,
+ 0x6a18,0x6a19,0x6a1a,0x6a1b,0x6a1c,0x6a1d,0x6a1e,0x6a1f,
+ 0x6a20,0x6a21,0x6a22,0x6a23,0x6a24,0x6a25,0x6a26,0x6a27,
+ 0x6a28,0x6a29,0x6a2a,0x6a2b,0x6a2c,0x6a2d,0x6a2e,0x6a2f,
+ 0x6a30,0x6a31,0x6a32,0x6a33,0x6a34,0x6a35,0x6a36,0x6a37,
+ 0x6a38,0x6a39,0x6a3a,0x6a3b,0x6a3c,0x6a3d,0x6a3e,0x6a3f,
+ 0x6a40,0x6a41,0x6a42,0x6a43,0x6a44,0x6a45,0x6a46,0x6a47,
+ 0x6a48,0x6a49,0x6a4a,0x6a4b,0x6a4c,0x6a4d,0x6a4e,0x6a4f,
+ 0x6a50,0x6a51,0x6a52,0x6a53,0x6a54,0x6a55,0x6a56,0x6a57,
+ 0x6a58,0x6a59,0x6a5a,0x6a5b,0x6a5c,0x6a5d,0x6a5e,0x6a5f,
+ 0x6a60,0x6a61,0x6a62,0x6a63,0x6a64,0x6a65,0x6a66,0x6a67,
+ 0x6a68,0x6a69,0x6a6a,0x6a6b,0x6a6c,0x6a6d,0x6a6e,0x6a6f,
+ 0x6a70,0x6a71,0x6a72,0x6a73,0x6a74,0x6a75,0x6a76,0x6a77,
+ 0x6a78,0x6a79,0x6a7a,0x6a7b,0x6a7c,0x6a7d,0x6a7e,0x6a7f,
+ 0x6a80,0x6a81,0x6a82,0x6a83,0x6a84,0x6a85,0x6a86,0x6a87,
+ 0x6a88,0x6a89,0x6a8a,0x6a8b,0x6a8c,0x6a8d,0x6a8e,0x6a8f,
+ 0x6a90,0x6a91,0x6a92,0x6a93,0x6a94,0x6a95,0x6a96,0x6a97,
+ 0x6a98,0x6a99,0x6a9a,0x6a9b,0x6a9c,0x6a9d,0x6a9e,0x6a9f,
+ 0x6aa0,0x6aa1,0x6aa2,0x6aa3,0x6aa4,0x6aa5,0x6aa6,0x6aa7,
+ 0x6aa8,0x6aa9,0x6aaa,0x6aab,0x6aac,0x6aad,0x6aae,0x6aaf,
+ 0x6ab0,0x6ab1,0x6ab2,0x6ab3,0x6ab4,0x6ab5,0x6ab6,0x6ab7,
+ 0x6ab8,0x6ab9,0x6aba,0x6abb,0x6abc,0x6abd,0x6abe,0x6abf,
+ 0x6ac0,0x6ac1,0x6ac2,0x6ac3,0x6ac4,0x6ac5,0x6ac6,0x6ac7,
+ 0x6ac8,0x6ac9,0x6aca,0x6acb,0x6acc,0x6acd,0x6ace,0x6acf,
+ 0x6ad0,0x6ad1,0x6ad2,0x6ad3,0x6ad4,0x6ad5,0x6ad6,0x6ad7,
+ 0x6ad8,0x6ad9,0x6ada,0x6adb,0x6adc,0x6add,0x6ade,0x6adf,
+ 0x6ae0,0x6ae1,0x6ae2,0x6ae3,0x6ae4,0x6ae5,0x6ae6,0x6ae7,
+ 0x6ae8,0x6ae9,0x6aea,0x6aeb,0x6aec,0x6aed,0x6aee,0x6aef,
+ 0x6af0,0x6af1,0x6af2,0x6af3,0x6af4,0x6af5,0x6af6,0x6af7,
+ 0x6af8,0x6af9,0x6afa,0x6afb,0x6afc,0x6afd,0x6afe,0x6aff,
+ 0x6b00,0x6b01,0x6b02,0x6b03,0x6b04,0x6b05,0x6b06,0x6b07,
+ 0x6b08,0x6b09,0x6b0a,0x6b0b,0x6b0c,0x6b0d,0x6b0e,0x6b0f,
+ 0x6b10,0x6b11,0x6b12,0x6b13,0x6b14,0x6b15,0x6b16,0x6b17,
+ 0x6b18,0x6b19,0x6b1a,0x6b1b,0x6b1c,0x6b1d,0x6b1e,0x6b1f,
+ 0x6b20,0x6b21,0x6b22,0x6b23,0x6b24,0x6b25,0x6b26,0x6b27,
+ 0x6b28,0x6b29,0x6b2a,0x6b2b,0x6b2c,0x6b2d,0x6b2e,0x6b2f,
+ 0x6b30,0x6b31,0x6b32,0x6b33,0x6b34,0x6b35,0x6b36,0x6b37,
+ 0x6b38,0x6b39,0x6b3a,0x6b3b,0x6b3c,0x6b3d,0x6b3e,0x6b3f,
+ 0x6b40,0x6b41,0x6b42,0x6b43,0x6b44,0x6b45,0x6b46,0x6b47,
+ 0x6b48,0x6b49,0x6b4a,0x6b4b,0x6b4c,0x6b4d,0x6b4e,0x6b4f,
+ 0x6b50,0x6b51,0x6b52,0x6b53,0x6b54,0x6b55,0x6b56,0x6b57,
+ 0x6b58,0x6b59,0x6b5a,0x6b5b,0x6b5c,0x6b5d,0x6b5e,0x6b5f,
+ 0x6b60,0x6b61,0x6b62,0x6b63,0x6b64,0x6b65,0x6b66,0x6b67,
+ 0x6b68,0x6b69,0x6b6a,0x6b6b,0x6b6c,0x6b6d,0x6b6e,0x6b6f,
+ 0x6b70,0x6b71,0x6b72,0x6b73,0x6b74,0x6b75,0x6b76,0x6b77,
+ 0x6b78,0x6b79,0x6b7a,0x6b7b,0x6b7c,0x6b7d,0x6b7e,0x6b7f,
+ 0x6b80,0x6b81,0x6b82,0x6b83,0x6b84,0x6b85,0x6b86,0x6b87,
+ 0x6b88,0x6b89,0x6b8a,0x6b8b,0x6b8c,0x6b8d,0x6b8e,0x6b8f,
+ 0x6b90,0x6b91,0x6b92,0x6b93,0x6b94,0x6b95,0x6b96,0x6b97,
+ 0x6b98,0x6b99,0x6b9a,0x6b9b,0x6b9c,0x6b9d,0x6b9e,0x6b9f,
+ 0x6ba0,0x6ba1,0x6ba2,0x6ba3,0x6ba4,0x6ba5,0x6ba6,0x6ba7,
+ 0x6ba8,0x6ba9,0x6baa,0x6bab,0x6bac,0x6bad,0x6bae,0x6baf,
+ 0x6bb0,0x6bb1,0x6bb2,0x6bb3,0x6bb4,0x6bb5,0x6bb6,0x6bb7,
+ 0x6bb8,0x6bb9,0x6bba,0x6bbb,0x6bbc,0x6bbd,0x6bbe,0x6bbf,
+ 0x6bc0,0x6bc1,0x6bc2,0x6bc3,0x6bc4,0x6bc5,0x6bc6,0x6bc7,
+ 0x6bc8,0x6bc9,0x6bca,0x6bcb,0x6bcc,0x6bcd,0x6bce,0x6bcf,
+ 0x6bd0,0x6bd1,0x6bd2,0x6bd3,0x6bd4,0x6bd5,0x6bd6,0x6bd7,
+ 0x6bd8,0x6bd9,0x6bda,0x6bdb,0x6bdc,0x6bdd,0x6bde,0x6bdf,
+ 0x6be0,0x6be1,0x6be2,0x6be3,0x6be4,0x6be5,0x6be6,0x6be7,
+ 0x6be8,0x6be9,0x6bea,0x6beb,0x6bec,0x6bed,0x6bee,0x6bef,
+ 0x6bf0,0x6bf1,0x6bf2,0x6bf3,0x6bf4,0x6bf5,0x6bf6,0x6bf7,
+ 0x6bf8,0x6bf9,0x6bfa,0x6bfb,0x6bfc,0x6bfd,0x6bfe,0x6bff,
+ 0x6c00,0x6c01,0x6c02,0x6c03,0x6c04,0x6c05,0x6c06,0x6c07,
+ 0x6c08,0x6c09,0x6c0a,0x6c0b,0x6c0c,0x6c0d,0x6c0e,0x6c0f,
+ 0x6c10,0x6c11,0x6c12,0x6c13,0x6c14,0x6c15,0x6c16,0x6c17,
+ 0x6c18,0x6c19,0x6c1a,0x6c1b,0x6c1c,0x6c1d,0x6c1e,0x6c1f,
+ 0x6c20,0x6c21,0x6c22,0x6c23,0x6c24,0x6c25,0x6c26,0x6c27,
+ 0x6c28,0x6c29,0x6c2a,0x6c2b,0x6c2c,0x6c2d,0x6c2e,0x6c2f,
+ 0x6c30,0x6c31,0x6c32,0x6c33,0x6c34,0x6c35,0x6c36,0x6c37,
+ 0x6c38,0x6c39,0x6c3a,0x6c3b,0x6c3c,0x6c3d,0x6c3e,0x6c3f,
+ 0x6c40,0x6c41,0x6c42,0x6c43,0x6c44,0x6c45,0x6c46,0x6c47,
+ 0x6c48,0x6c49,0x6c4a,0x6c4b,0x6c4c,0x6c4d,0x6c4e,0x6c4f,
+ 0x6c50,0x6c51,0x6c52,0x6c53,0x6c54,0x6c55,0x6c56,0x6c57,
+ 0x6c58,0x6c59,0x6c5a,0x6c5b,0x6c5c,0x6c5d,0x6c5e,0x6c5f,
+ 0x6c60,0x6c61,0x6c62,0x6c63,0x6c64,0x6c65,0x6c66,0x6c67,
+ 0x6c68,0x6c69,0x6c6a,0x6c6b,0x6c6c,0x6c6d,0x6c6e,0x6c6f,
+ 0x6c70,0x6c71,0x6c72,0x6c73,0x6c74,0x6c75,0x6c76,0x6c77,
+ 0x6c78,0x6c79,0x6c7a,0x6c7b,0x6c7c,0x6c7d,0x6c7e,0x6c7f,
+ 0x6c80,0x6c81,0x6c82,0x6c83,0x6c84,0x6c85,0x6c86,0x6c87,
+ 0x6c88,0x6c89,0x6c8a,0x6c8b,0x6c8c,0x6c8d,0x6c8e,0x6c8f,
+ 0x6c90,0x6c91,0x6c92,0x6c93,0x6c94,0x6c95,0x6c96,0x6c97,
+ 0x6c98,0x6c99,0x6c9a,0x6c9b,0x6c9c,0x6c9d,0x6c9e,0x6c9f,
+ 0x6ca0,0x6ca1,0x6ca2,0x6ca3,0x6ca4,0x6ca5,0x6ca6,0x6ca7,
+ 0x6ca8,0x6ca9,0x6caa,0x6cab,0x6cac,0x6cad,0x6cae,0x6caf,
+ 0x6cb0,0x6cb1,0x6cb2,0x6cb3,0x6cb4,0x6cb5,0x6cb6,0x6cb7,
+ 0x6cb8,0x6cb9,0x6cba,0x6cbb,0x6cbc,0x6cbd,0x6cbe,0x6cbf,
+ 0x6cc0,0x6cc1,0x6cc2,0x6cc3,0x6cc4,0x6cc5,0x6cc6,0x6cc7,
+ 0x6cc8,0x6cc9,0x6cca,0x6ccb,0x6ccc,0x6ccd,0x6cce,0x6ccf,
+ 0x6cd0,0x6cd1,0x6cd2,0x6cd3,0x6cd4,0x6cd5,0x6cd6,0x6cd7,
+ 0x6cd8,0x6cd9,0x6cda,0x6cdb,0x6cdc,0x6cdd,0x6cde,0x6cdf,
+ 0x6ce0,0x6ce1,0x6ce2,0x6ce3,0x6ce4,0x6ce5,0x6ce6,0x6ce7,
+ 0x6ce8,0x6ce9,0x6cea,0x6ceb,0x6cec,0x6ced,0x6cee,0x6cef,
+ 0x6cf0,0x6cf1,0x6cf2,0x6cf3,0x6cf4,0x6cf5,0x6cf6,0x6cf7,
+ 0x6cf8,0x6cf9,0x6cfa,0x6cfb,0x6cfc,0x6cfd,0x6cfe,0x6cff,
+ 0x6d00,0x6d01,0x6d02,0x6d03,0x6d04,0x6d05,0x6d06,0x6d07,
+ 0x6d08,0x6d09,0x6d0a,0x6d0b,0x6d0c,0x6d0d,0x6d0e,0x6d0f,
+ 0x6d10,0x6d11,0x6d12,0x6d13,0x6d14,0x6d15,0x6d16,0x6d17,
+ 0x6d18,0x6d19,0x6d1a,0x6d1b,0x6d1c,0x6d1d,0x6d1e,0x6d1f,
+ 0x6d20,0x6d21,0x6d22,0x6d23,0x6d24,0x6d25,0x6d26,0x6d27,
+ 0x6d28,0x6d29,0x6d2a,0x6d2b,0x6d2c,0x6d2d,0x6d2e,0x6d2f,
+ 0x6d30,0x6d31,0x6d32,0x6d33,0x6d34,0x6d35,0x6d36,0x6d37,
+ 0x6d38,0x6d39,0x6d3a,0x6d3b,0x6d3c,0x6d3d,0x6d3e,0x6d3f,
+ 0x6d40,0x6d41,0x6d42,0x6d43,0x6d44,0x6d45,0x6d46,0x6d47,
+ 0x6d48,0x6d49,0x6d4a,0x6d4b,0x6d4c,0x6d4d,0x6d4e,0x6d4f,
+ 0x6d50,0x6d51,0x6d52,0x6d53,0x6d54,0x6d55,0x6d56,0x6d57,
+ 0x6d58,0x6d59,0x6d5a,0x6d5b,0x6d5c,0x6d5d,0x6d5e,0x6d5f,
+ 0x6d60,0x6d61,0x6d62,0x6d63,0x6d64,0x6d65,0x6d66,0x6d67,
+ 0x6d68,0x6d69,0x6d6a,0x6d6b,0x6d6c,0x6d6d,0x6d6e,0x6d6f,
+ 0x6d70,0x6d71,0x6d72,0x6d73,0x6d74,0x6d75,0x6d76,0x6d77,
+ 0x6d78,0x6d79,0x6d7a,0x6d7b,0x6d7c,0x6d7d,0x6d7e,0x6d7f,
+ 0x6d80,0x6d81,0x6d82,0x6d83,0x6d84,0x6d85,0x6d86,0x6d87,
+ 0x6d88,0x6d89,0x6d8a,0x6d8b,0x6d8c,0x6d8d,0x6d8e,0x6d8f,
+ 0x6d90,0x6d91,0x6d92,0x6d93,0x6d94,0x6d95,0x6d96,0x6d97,
+ 0x6d98,0x6d99,0x6d9a,0x6d9b,0x6d9c,0x6d9d,0x6d9e,0x6d9f,
+ 0x6da0,0x6da1,0x6da2,0x6da3,0x6da4,0x6da5,0x6da6,0x6da7,
+ 0x6da8,0x6da9,0x6daa,0x6dab,0x6dac,0x6dad,0x6dae,0x6daf,
+ 0x6db0,0x6db1,0x6db2,0x6db3,0x6db4,0x6db5,0x6db6,0x6db7,
+ 0x6db8,0x6db9,0x6dba,0x6dbb,0x6dbc,0x6dbd,0x6dbe,0x6dbf,
+ 0x6dc0,0x6dc1,0x6dc2,0x6dc3,0x6dc4,0x6dc5,0x6dc6,0x6dc7,
+ 0x6dc8,0x6dc9,0x6dca,0x6dcb,0x6dcc,0x6dcd,0x6dce,0x6dcf,
+ 0x6dd0,0x6dd1,0x6dd2,0x6dd3,0x6dd4,0x6dd5,0x6dd6,0x6dd7,
+ 0x6dd8,0x6dd9,0x6dda,0x6ddb,0x6ddc,0x6ddd,0x6dde,0x6ddf,
+ 0x6de0,0x6de1,0x6de2,0x6de3,0x6de4,0x6de5,0x6de6,0x6de7,
+ 0x6de8,0x6de9,0x6dea,0x6deb,0x6dec,0x6ded,0x6dee,0x6def,
+ 0x6df0,0x6df1,0x6df2,0x6df3,0x6df4,0x6df5,0x6df6,0x6df7,
+ 0x6df8,0x6df9,0x6dfa,0x6dfb,0x6dfc,0x6dfd,0x6dfe,0x6dff,
+ 0x6e00,0x6e01,0x6e02,0x6e03,0x6e04,0x6e05,0x6e06,0x6e07,
+ 0x6e08,0x6e09,0x6e0a,0x6e0b,0x6e0c,0x6e0d,0x6e0e,0x6e0f,
+ 0x6e10,0x6e11,0x6e12,0x6e13,0x6e14,0x6e15,0x6e16,0x6e17,
+ 0x6e18,0x6e19,0x6e1a,0x6e1b,0x6e1c,0x6e1d,0x6e1e,0x6e1f,
+ 0x6e20,0x6e21,0x6e22,0x6e23,0x6e24,0x6e25,0x6e26,0x6e27,
+ 0x6e28,0x6e29,0x6e2a,0x6e2b,0x6e2c,0x6e2d,0x6e2e,0x6e2f,
+ 0x6e30,0x6e31,0x6e32,0x6e33,0x6e34,0x6e35,0x6e36,0x6e37,
+ 0x6e38,0x6e39,0x6e3a,0x6e3b,0x6e3c,0x6e3d,0x6e3e,0x6e3f,
+ 0x6e40,0x6e41,0x6e42,0x6e43,0x6e44,0x6e45,0x6e46,0x6e47,
+ 0x6e48,0x6e49,0x6e4a,0x6e4b,0x6e4c,0x6e4d,0x6e4e,0x6e4f,
+ 0x6e50,0x6e51,0x6e52,0x6e53,0x6e54,0x6e55,0x6e56,0x6e57,
+ 0x6e58,0x6e59,0x6e5a,0x6e5b,0x6e5c,0x6e5d,0x6e5e,0x6e5f,
+ 0x6e60,0x6e61,0x6e62,0x6e63,0x6e64,0x6e65,0x6e66,0x6e67,
+ 0x6e68,0x6e69,0x6e6a,0x6e6b,0x6e6c,0x6e6d,0x6e6e,0x6e6f,
+ 0x6e70,0x6e71,0x6e72,0x6e73,0x6e74,0x6e75,0x6e76,0x6e77,
+ 0x6e78,0x6e79,0x6e7a,0x6e7b,0x6e7c,0x6e7d,0x6e7e,0x6e7f,
+ 0x6e80,0x6e81,0x6e82,0x6e83,0x6e84,0x6e85,0x6e86,0x6e87,
+ 0x6e88,0x6e89,0x6e8a,0x6e8b,0x6e8c,0x6e8d,0x6e8e,0x6e8f,
+ 0x6e90,0x6e91,0x6e92,0x6e93,0x6e94,0x6e95,0x6e96,0x6e97,
+ 0x6e98,0x6e99,0x6e9a,0x6e9b,0x6e9c,0x6e9d,0x6e9e,0x6e9f,
+ 0x6ea0,0x6ea1,0x6ea2,0x6ea3,0x6ea4,0x6ea5,0x6ea6,0x6ea7,
+ 0x6ea8,0x6ea9,0x6eaa,0x6eab,0x6eac,0x6ead,0x6eae,0x6eaf,
+ 0x6eb0,0x6eb1,0x6eb2,0x6eb3,0x6eb4,0x6eb5,0x6eb6,0x6eb7,
+ 0x6eb8,0x6eb9,0x6eba,0x6ebb,0x6ebc,0x6ebd,0x6ebe,0x6ebf,
+ 0x6ec0,0x6ec1,0x6ec2,0x6ec3,0x6ec4,0x6ec5,0x6ec6,0x6ec7,
+ 0x6ec8,0x6ec9,0x6eca,0x6ecb,0x6ecc,0x6ecd,0x6ece,0x6ecf,
+ 0x6ed0,0x6ed1,0x6ed2,0x6ed3,0x6ed4,0x6ed5,0x6ed6,0x6ed7,
+ 0x6ed8,0x6ed9,0x6eda,0x6edb,0x6edc,0x6edd,0x6ede,0x6edf,
+ 0x6ee0,0x6ee1,0x6ee2,0x6ee3,0x6ee4,0x6ee5,0x6ee6,0x6ee7,
+ 0x6ee8,0x6ee9,0x6eea,0x6eeb,0x6eec,0x6eed,0x6eee,0x6eef,
+ 0x6ef0,0x6ef1,0x6ef2,0x6ef3,0x6ef4,0x6ef5,0x6ef6,0x6ef7,
+ 0x6ef8,0x6ef9,0x6efa,0x6efb,0x6efc,0x6efd,0x6efe,0x6eff,
+ 0x6f00,0x6f01,0x6f02,0x6f03,0x6f04,0x6f05,0x6f06,0x6f07,
+ 0x6f08,0x6f09,0x6f0a,0x6f0b,0x6f0c,0x6f0d,0x6f0e,0x6f0f,
+ 0x6f10,0x6f11,0x6f12,0x6f13,0x6f14,0x6f15,0x6f16,0x6f17,
+ 0x6f18,0x6f19,0x6f1a,0x6f1b,0x6f1c,0x6f1d,0x6f1e,0x6f1f,
+ 0x6f20,0x6f21,0x6f22,0x6f23,0x6f24,0x6f25,0x6f26,0x6f27,
+ 0x6f28,0x6f29,0x6f2a,0x6f2b,0x6f2c,0x6f2d,0x6f2e,0x6f2f,
+ 0x6f30,0x6f31,0x6f32,0x6f33,0x6f34,0x6f35,0x6f36,0x6f37,
+ 0x6f38,0x6f39,0x6f3a,0x6f3b,0x6f3c,0x6f3d,0x6f3e,0x6f3f,
+ 0x6f40,0x6f41,0x6f42,0x6f43,0x6f44,0x6f45,0x6f46,0x6f47,
+ 0x6f48,0x6f49,0x6f4a,0x6f4b,0x6f4c,0x6f4d,0x6f4e,0x6f4f,
+ 0x6f50,0x6f51,0x6f52,0x6f53,0x6f54,0x6f55,0x6f56,0x6f57,
+ 0x6f58,0x6f59,0x6f5a,0x6f5b,0x6f5c,0x6f5d,0x6f5e,0x6f5f,
+ 0x6f60,0x6f61,0x6f62,0x6f63,0x6f64,0x6f65,0x6f66,0x6f67,
+ 0x6f68,0x6f69,0x6f6a,0x6f6b,0x6f6c,0x6f6d,0x6f6e,0x6f6f,
+ 0x6f70,0x6f71,0x6f72,0x6f73,0x6f74,0x6f75,0x6f76,0x6f77,
+ 0x6f78,0x6f79,0x6f7a,0x6f7b,0x6f7c,0x6f7d,0x6f7e,0x6f7f,
+ 0x6f80,0x6f81,0x6f82,0x6f83,0x6f84,0x6f85,0x6f86,0x6f87,
+ 0x6f88,0x6f89,0x6f8a,0x6f8b,0x6f8c,0x6f8d,0x6f8e,0x6f8f,
+ 0x6f90,0x6f91,0x6f92,0x6f93,0x6f94,0x6f95,0x6f96,0x6f97,
+ 0x6f98,0x6f99,0x6f9a,0x6f9b,0x6f9c,0x6f9d,0x6f9e,0x6f9f,
+ 0x6fa0,0x6fa1,0x6fa2,0x6fa3,0x6fa4,0x6fa5,0x6fa6,0x6fa7,
+ 0x6fa8,0x6fa9,0x6faa,0x6fab,0x6fac,0x6fad,0x6fae,0x6faf,
+ 0x6fb0,0x6fb1,0x6fb2,0x6fb3,0x6fb4,0x6fb5,0x6fb6,0x6fb7,
+ 0x6fb8,0x6fb9,0x6fba,0x6fbb,0x6fbc,0x6fbd,0x6fbe,0x6fbf,
+ 0x6fc0,0x6fc1,0x6fc2,0x6fc3,0x6fc4,0x6fc5,0x6fc6,0x6fc7,
+ 0x6fc8,0x6fc9,0x6fca,0x6fcb,0x6fcc,0x6fcd,0x6fce,0x6fcf,
+ 0x6fd0,0x6fd1,0x6fd2,0x6fd3,0x6fd4,0x6fd5,0x6fd6,0x6fd7,
+ 0x6fd8,0x6fd9,0x6fda,0x6fdb,0x6fdc,0x6fdd,0x6fde,0x6fdf,
+ 0x6fe0,0x6fe1,0x6fe2,0x6fe3,0x6fe4,0x6fe5,0x6fe6,0x6fe7,
+ 0x6fe8,0x6fe9,0x6fea,0x6feb,0x6fec,0x6fed,0x6fee,0x6fef,
+ 0x6ff0,0x6ff1,0x6ff2,0x6ff3,0x6ff4,0x6ff5,0x6ff6,0x6ff7,
+ 0x6ff8,0x6ff9,0x6ffa,0x6ffb,0x6ffc,0x6ffd,0x6ffe,0x6fff,
+ 0x7000,0x7001,0x7002,0x7003,0x7004,0x7005,0x7006,0x7007,
+ 0x7008,0x7009,0x700a,0x700b,0x700c,0x700d,0x700e,0x700f,
+ 0x7010,0x7011,0x7012,0x7013,0x7014,0x7015,0x7016,0x7017,
+ 0x7018,0x7019,0x701a,0x701b,0x701c,0x701d,0x701e,0x701f,
+ 0x7020,0x7021,0x7022,0x7023,0x7024,0x7025,0x7026,0x7027,
+ 0x7028,0x7029,0x702a,0x702b,0x702c,0x702d,0x702e,0x702f,
+ 0x7030,0x7031,0x7032,0x7033,0x7034,0x7035,0x7036,0x7037,
+ 0x7038,0x7039,0x703a,0x703b,0x703c,0x703d,0x703e,0x703f,
+ 0x7040,0x7041,0x7042,0x7043,0x7044,0x7045,0x7046,0x7047,
+ 0x7048,0x7049,0x704a,0x704b,0x704c,0x704d,0x704e,0x704f,
+ 0x7050,0x7051,0x7052,0x7053,0x7054,0x7055,0x7056,0x7057,
+ 0x7058,0x7059,0x705a,0x705b,0x705c,0x705d,0x705e,0x705f,
+ 0x7060,0x7061,0x7062,0x7063,0x7064,0x7065,0x7066,0x7067,
+ 0x7068,0x7069,0x706a,0x706b,0x706c,0x706d,0x706e,0x706f,
+ 0x7070,0x7071,0x7072,0x7073,0x7074,0x7075,0x7076,0x7077,
+ 0x7078,0x7079,0x707a,0x707b,0x707c,0x707d,0x707e,0x707f,
+ 0x7080,0x7081,0x7082,0x7083,0x7084,0x7085,0x7086,0x7087,
+ 0x7088,0x7089,0x708a,0x708b,0x708c,0x708d,0x708e,0x708f,
+ 0x7090,0x7091,0x7092,0x7093,0x7094,0x7095,0x7096,0x7097,
+ 0x7098,0x7099,0x709a,0x709b,0x709c,0x709d,0x709e,0x709f,
+ 0x70a0,0x70a1,0x70a2,0x70a3,0x70a4,0x70a5,0x70a6,0x70a7,
+ 0x70a8,0x70a9,0x70aa,0x70ab,0x70ac,0x70ad,0x70ae,0x70af,
+ 0x70b0,0x70b1,0x70b2,0x70b3,0x70b4,0x70b5,0x70b6,0x70b7,
+ 0x70b8,0x70b9,0x70ba,0x70bb,0x70bc,0x70bd,0x70be,0x70bf,
+ 0x70c0,0x70c1,0x70c2,0x70c3,0x70c4,0x70c5,0x70c6,0x70c7,
+ 0x70c8,0x70c9,0x70ca,0x70cb,0x70cc,0x70cd,0x70ce,0x70cf,
+ 0x70d0,0x70d1,0x70d2,0x70d3,0x70d4,0x70d5,0x70d6,0x70d7,
+ 0x70d8,0x70d9,0x70da,0x70db,0x70dc,0x70dd,0x70de,0x70df,
+ 0x70e0,0x70e1,0x70e2,0x70e3,0x70e4,0x70e5,0x70e6,0x70e7,
+ 0x70e8,0x70e9,0x70ea,0x70eb,0x70ec,0x70ed,0x70ee,0x70ef,
+ 0x70f0,0x70f1,0x70f2,0x70f3,0x70f4,0x70f5,0x70f6,0x70f7,
+ 0x70f8,0x70f9,0x70fa,0x70fb,0x70fc,0x70fd,0x70fe,0x70ff,
+ 0x7100,0x7101,0x7102,0x7103,0x7104,0x7105,0x7106,0x7107,
+ 0x7108,0x7109,0x710a,0x710b,0x710c,0x710d,0x710e,0x710f,
+ 0x7110,0x7111,0x7112,0x7113,0x7114,0x7115,0x7116,0x7117,
+ 0x7118,0x7119,0x711a,0x711b,0x711c,0x711d,0x711e,0x711f,
+ 0x7120,0x7121,0x7122,0x7123,0x7124,0x7125,0x7126,0x7127,
+ 0x7128,0x7129,0x712a,0x712b,0x712c,0x712d,0x712e,0x712f,
+ 0x7130,0x7131,0x7132,0x7133,0x7134,0x7135,0x7136,0x7137,
+ 0x7138,0x7139,0x713a,0x713b,0x713c,0x713d,0x713e,0x713f,
+ 0x7140,0x7141,0x7142,0x7143,0x7144,0x7145,0x7146,0x7147,
+ 0x7148,0x7149,0x714a,0x714b,0x714c,0x714d,0x714e,0x714f,
+ 0x7150,0x7151,0x7152,0x7153,0x7154,0x7155,0x7156,0x7157,
+ 0x7158,0x7159,0x715a,0x715b,0x715c,0x715d,0x715e,0x715f,
+ 0x7160,0x7161,0x7162,0x7163,0x7164,0x7165,0x7166,0x7167,
+ 0x7168,0x7169,0x716a,0x716b,0x716c,0x716d,0x716e,0x716f,
+ 0x7170,0x7171,0x7172,0x7173,0x7174,0x7175,0x7176,0x7177,
+ 0x7178,0x7179,0x717a,0x717b,0x717c,0x717d,0x717e,0x717f,
+ 0x7180,0x7181,0x7182,0x7183,0x7184,0x7185,0x7186,0x7187,
+ 0x7188,0x7189,0x718a,0x718b,0x718c,0x718d,0x718e,0x718f,
+ 0x7190,0x7191,0x7192,0x7193,0x7194,0x7195,0x7196,0x7197,
+ 0x7198,0x7199,0x719a,0x719b,0x719c,0x719d,0x719e,0x719f,
+ 0x71a0,0x71a1,0x71a2,0x71a3,0x71a4,0x71a5,0x71a6,0x71a7,
+ 0x71a8,0x71a9,0x71aa,0x71ab,0x71ac,0x71ad,0x71ae,0x71af,
+ 0x71b0,0x71b1,0x71b2,0x71b3,0x71b4,0x71b5,0x71b6,0x71b7,
+ 0x71b8,0x71b9,0x71ba,0x71bb,0x71bc,0x71bd,0x71be,0x71bf,
+ 0x71c0,0x71c1,0x71c2,0x71c3,0x71c4,0x71c5,0x71c6,0x71c7,
+ 0x71c8,0x71c9,0x71ca,0x71cb,0x71cc,0x71cd,0x71ce,0x71cf,
+ 0x71d0,0x71d1,0x71d2,0x71d3,0x71d4,0x71d5,0x71d6,0x71d7,
+ 0x71d8,0x71d9,0x71da,0x71db,0x71dc,0x71dd,0x71de,0x71df,
+ 0x71e0,0x71e1,0x71e2,0x71e3,0x71e4,0x71e5,0x71e6,0x71e7,
+ 0x71e8,0x71e9,0x71ea,0x71eb,0x71ec,0x71ed,0x71ee,0x71ef,
+ 0x71f0,0x71f1,0x71f2,0x71f3,0x71f4,0x71f5,0x71f6,0x71f7,
+ 0x71f8,0x71f9,0x71fa,0x71fb,0x71fc,0x71fd,0x71fe,0x71ff,
+ 0x7200,0x7201,0x7202,0x7203,0x7204,0x7205,0x7206,0x7207,
+ 0x7208,0x7209,0x720a,0x720b,0x720c,0x720d,0x720e,0x720f,
+ 0x7210,0x7211,0x7212,0x7213,0x7214,0x7215,0x7216,0x7217,
+ 0x7218,0x7219,0x721a,0x721b,0x721c,0x721d,0x721e,0x721f,
+ 0x7220,0x7221,0x7222,0x7223,0x7224,0x7225,0x7226,0x7227,
+ 0x7228,0x7229,0x722a,0x722b,0x722c,0x722d,0x722e,0x722f,
+ 0x7230,0x7231,0x7232,0x7233,0x7234,0x7235,0x7236,0x7237,
+ 0x7238,0x7239,0x723a,0x723b,0x723c,0x723d,0x723e,0x723f,
+ 0x7240,0x7241,0x7242,0x7243,0x7244,0x7245,0x7246,0x7247,
+ 0x7248,0x7249,0x724a,0x724b,0x724c,0x724d,0x724e,0x724f,
+ 0x7250,0x7251,0x7252,0x7253,0x7254,0x7255,0x7256,0x7257,
+ 0x7258,0x7259,0x725a,0x725b,0x725c,0x725d,0x725e,0x725f,
+ 0x7260,0x7261,0x7262,0x7263,0x7264,0x7265,0x7266,0x7267,
+ 0x7268,0x7269,0x726a,0x726b,0x726c,0x726d,0x726e,0x726f,
+ 0x7270,0x7271,0x7272,0x7273,0x7274,0x7275,0x7276,0x7277,
+ 0x7278,0x7279,0x727a,0x727b,0x727c,0x727d,0x727e,0x727f,
+ 0x7280,0x7281,0x7282,0x7283,0x7284,0x7285,0x7286,0x7287,
+ 0x7288,0x7289,0x728a,0x728b,0x728c,0x728d,0x728e,0x728f,
+ 0x7290,0x7291,0x7292,0x7293,0x7294,0x7295,0x7296,0x7297,
+ 0x7298,0x7299,0x729a,0x729b,0x729c,0x729d,0x729e,0x729f,
+ 0x72a0,0x72a1,0x72a2,0x72a3,0x72a4,0x72a5,0x72a6,0x72a7,
+ 0x72a8,0x72a9,0x72aa,0x72ab,0x72ac,0x72ad,0x72ae,0x72af,
+ 0x72b0,0x72b1,0x72b2,0x72b3,0x72b4,0x72b5,0x72b6,0x72b7,
+ 0x72b8,0x72b9,0x72ba,0x72bb,0x72bc,0x72bd,0x72be,0x72bf,
+ 0x72c0,0x72c1,0x72c2,0x72c3,0x72c4,0x72c5,0x72c6,0x72c7,
+ 0x72c8,0x72c9,0x72ca,0x72cb,0x72cc,0x72cd,0x72ce,0x72cf,
+ 0x72d0,0x72d1,0x72d2,0x72d3,0x72d4,0x72d5,0x72d6,0x72d7,
+ 0x72d8,0x72d9,0x72da,0x72db,0x72dc,0x72dd,0x72de,0x72df,
+ 0x72e0,0x72e1,0x72e2,0x72e3,0x72e4,0x72e5,0x72e6,0x72e7,
+ 0x72e8,0x72e9,0x72ea,0x72eb,0x72ec,0x72ed,0x72ee,0x72ef,
+ 0x72f0,0x72f1,0x72f2,0x72f3,0x72f4,0x72f5,0x72f6,0x72f7,
+ 0x72f8,0x72f9,0x72fa,0x72fb,0x72fc,0x72fd,0x72fe,0x72ff,
+ 0x7300,0x7301,0x7302,0x7303,0x7304,0x7305,0x7306,0x7307,
+ 0x7308,0x7309,0x730a,0x730b,0x730c,0x730d,0x730e,0x730f,
+ 0x7310,0x7311,0x7312,0x7313,0x7314,0x7315,0x7316,0x7317,
+ 0x7318,0x7319,0x731a,0x731b,0x731c,0x731d,0x731e,0x731f,
+ 0x7320,0x7321,0x7322,0x7323,0x7324,0x7325,0x7326,0x7327,
+ 0x7328,0x7329,0x732a,0x732b,0x732c,0x732d,0x732e,0x732f,
+ 0x7330,0x7331,0x7332,0x7333,0x7334,0x7335,0x7336,0x7337,
+ 0x7338,0x7339,0x733a,0x733b,0x733c,0x733d,0x733e,0x733f,
+ 0x7340,0x7341,0x7342,0x7343,0x7344,0x7345,0x7346,0x7347,
+ 0x7348,0x7349,0x734a,0x734b,0x734c,0x734d,0x734e,0x734f,
+ 0x7350,0x7351,0x7352,0x7353,0x7354,0x7355,0x7356,0x7357,
+ 0x7358,0x7359,0x735a,0x735b,0x735c,0x735d,0x735e,0x735f,
+ 0x7360,0x7361,0x7362,0x7363,0x7364,0x7365,0x7366,0x7367,
+ 0x7368,0x7369,0x736a,0x736b,0x736c,0x736d,0x736e,0x736f,
+ 0x7370,0x7371,0x7372,0x7373,0x7374,0x7375,0x7376,0x7377,
+ 0x7378,0x7379,0x737a,0x737b,0x737c,0x737d,0x737e,0x737f,
+ 0x7380,0x7381,0x7382,0x7383,0x7384,0x7385,0x7386,0x7387,
+ 0x7388,0x7389,0x738a,0x738b,0x738c,0x738d,0x738e,0x738f,
+ 0x7390,0x7391,0x7392,0x7393,0x7394,0x7395,0x7396,0x7397,
+ 0x7398,0x7399,0x739a,0x739b,0x739c,0x739d,0x739e,0x739f,
+ 0x73a0,0x73a1,0x73a2,0x73a3,0x73a4,0x73a5,0x73a6,0x73a7,
+ 0x73a8,0x73a9,0x73aa,0x73ab,0x73ac,0x73ad,0x73ae,0x73af,
+ 0x73b0,0x73b1,0x73b2,0x73b3,0x73b4,0x73b5,0x73b6,0x73b7,
+ 0x73b8,0x73b9,0x73ba,0x73bb,0x73bc,0x73bd,0x73be,0x73bf,
+ 0x73c0,0x73c1,0x73c2,0x73c3,0x73c4,0x73c5,0x73c6,0x73c7,
+ 0x73c8,0x73c9,0x73ca,0x73cb,0x73cc,0x73cd,0x73ce,0x73cf,
+ 0x73d0,0x73d1,0x73d2,0x73d3,0x73d4,0x73d5,0x73d6,0x73d7,
+ 0x73d8,0x73d9,0x73da,0x73db,0x73dc,0x73dd,0x73de,0x73df,
+ 0x73e0,0x73e1,0x73e2,0x73e3,0x73e4,0x73e5,0x73e6,0x73e7,
+ 0x73e8,0x73e9,0x73ea,0x73eb,0x73ec,0x73ed,0x73ee,0x73ef,
+ 0x73f0,0x73f1,0x73f2,0x73f3,0x73f4,0x73f5,0x73f6,0x73f7,
+ 0x73f8,0x73f9,0x73fa,0x73fb,0x73fc,0x73fd,0x73fe,0x73ff,
+ 0x7400,0x7401,0x7402,0x7403,0x7404,0x7405,0x7406,0x7407,
+ 0x7408,0x7409,0x740a,0x740b,0x740c,0x740d,0x740e,0x740f,
+ 0x7410,0x7411,0x7412,0x7413,0x7414,0x7415,0x7416,0x7417,
+ 0x7418,0x7419,0x741a,0x741b,0x741c,0x741d,0x741e,0x741f,
+ 0x7420,0x7421,0x7422,0x7423,0x7424,0x7425,0x7426,0x7427,
+ 0x7428,0x7429,0x742a,0x742b,0x742c,0x742d,0x742e,0x742f,
+ 0x7430,0x7431,0x7432,0x7433,0x7434,0x7435,0x7436,0x7437,
+ 0x7438,0x7439,0x743a,0x743b,0x743c,0x743d,0x743e,0x743f,
+ 0x7440,0x7441,0x7442,0x7443,0x7444,0x7445,0x7446,0x7447,
+ 0x7448,0x7449,0x744a,0x744b,0x744c,0x744d,0x744e,0x744f,
+ 0x7450,0x7451,0x7452,0x7453,0x7454,0x7455,0x7456,0x7457,
+ 0x7458,0x7459,0x745a,0x745b,0x745c,0x745d,0x745e,0x745f,
+ 0x7460,0x7461,0x7462,0x7463,0x7464,0x7465,0x7466,0x7467,
+ 0x7468,0x7469,0x746a,0x746b,0x746c,0x746d,0x746e,0x746f,
+ 0x7470,0x7471,0x7472,0x7473,0x7474,0x7475,0x7476,0x7477,
+ 0x7478,0x7479,0x747a,0x747b,0x747c,0x747d,0x747e,0x747f,
+ 0x7480,0x7481,0x7482,0x7483,0x7484,0x7485,0x7486,0x7487,
+ 0x7488,0x7489,0x748a,0x748b,0x748c,0x748d,0x748e,0x748f,
+ 0x7490,0x7491,0x7492,0x7493,0x7494,0x7495,0x7496,0x7497,
+ 0x7498,0x7499,0x749a,0x749b,0x749c,0x749d,0x749e,0x749f,
+ 0x74a0,0x74a1,0x74a2,0x74a3,0x74a4,0x74a5,0x74a6,0x74a7,
+ 0x74a8,0x74a9,0x74aa,0x74ab,0x74ac,0x74ad,0x74ae,0x74af,
+ 0x74b0,0x74b1,0x74b2,0x74b3,0x74b4,0x74b5,0x74b6,0x74b7,
+ 0x74b8,0x74b9,0x74ba,0x74bb,0x74bc,0x74bd,0x74be,0x74bf,
+ 0x74c0,0x74c1,0x74c2,0x74c3,0x74c4,0x74c5,0x74c6,0x74c7,
+ 0x74c8,0x74c9,0x74ca,0x74cb,0x74cc,0x74cd,0x74ce,0x74cf,
+ 0x74d0,0x74d1,0x74d2,0x74d3,0x74d4,0x74d5,0x74d6,0x74d7,
+ 0x74d8,0x74d9,0x74da,0x74db,0x74dc,0x74dd,0x74de,0x74df,
+ 0x74e0,0x74e1,0x74e2,0x74e3,0x74e4,0x74e5,0x74e6,0x74e7,
+ 0x74e8,0x74e9,0x74ea,0x74eb,0x74ec,0x74ed,0x74ee,0x74ef,
+ 0x74f0,0x74f1,0x74f2,0x74f3,0x74f4,0x74f5,0x74f6,0x74f7,
+ 0x74f8,0x74f9,0x74fa,0x74fb,0x74fc,0x74fd,0x74fe,0x74ff,
+ 0x7500,0x7501,0x7502,0x7503,0x7504,0x7505,0x7506,0x7507,
+ 0x7508,0x7509,0x750a,0x750b,0x750c,0x750d,0x750e,0x750f,
+ 0x7510,0x7511,0x7512,0x7513,0x7514,0x7515,0x7516,0x7517,
+ 0x7518,0x7519,0x751a,0x751b,0x751c,0x751d,0x751e,0x751f,
+ 0x7520,0x7521,0x7522,0x7523,0x7524,0x7525,0x7526,0x7527,
+ 0x7528,0x7529,0x752a,0x752b,0x752c,0x752d,0x752e,0x752f,
+ 0x7530,0x7531,0x7532,0x7533,0x7534,0x7535,0x7536,0x7537,
+ 0x7538,0x7539,0x753a,0x753b,0x753c,0x753d,0x753e,0x753f,
+ 0x7540,0x7541,0x7542,0x7543,0x7544,0x7545,0x7546,0x7547,
+ 0x7548,0x7549,0x754a,0x754b,0x754c,0x754d,0x754e,0x754f,
+ 0x7550,0x7551,0x7552,0x7553,0x7554,0x7555,0x7556,0x7557,
+ 0x7558,0x7559,0x755a,0x755b,0x755c,0x755d,0x755e,0x755f,
+ 0x7560,0x7561,0x7562,0x7563,0x7564,0x7565,0x7566,0x7567,
+ 0x7568,0x7569,0x756a,0x756b,0x756c,0x756d,0x756e,0x756f,
+ 0x7570,0x7571,0x7572,0x7573,0x7574,0x7575,0x7576,0x7577,
+ 0x7578,0x7579,0x757a,0x757b,0x757c,0x757d,0x757e,0x757f,
+ 0x7580,0x7581,0x7582,0x7583,0x7584,0x7585,0x7586,0x7587,
+ 0x7588,0x7589,0x758a,0x758b,0x758c,0x758d,0x758e,0x758f,
+ 0x7590,0x7591,0x7592,0x7593,0x7594,0x7595,0x7596,0x7597,
+ 0x7598,0x7599,0x759a,0x759b,0x759c,0x759d,0x759e,0x759f,
+ 0x75a0,0x75a1,0x75a2,0x75a3,0x75a4,0x75a5,0x75a6,0x75a7,
+ 0x75a8,0x75a9,0x75aa,0x75ab,0x75ac,0x75ad,0x75ae,0x75af,
+ 0x75b0,0x75b1,0x75b2,0x75b3,0x75b4,0x75b5,0x75b6,0x75b7,
+ 0x75b8,0x75b9,0x75ba,0x75bb,0x75bc,0x75bd,0x75be,0x75bf,
+ 0x75c0,0x75c1,0x75c2,0x75c3,0x75c4,0x75c5,0x75c6,0x75c7,
+ 0x75c8,0x75c9,0x75ca,0x75cb,0x75cc,0x75cd,0x75ce,0x75cf,
+ 0x75d0,0x75d1,0x75d2,0x75d3,0x75d4,0x75d5,0x75d6,0x75d7,
+ 0x75d8,0x75d9,0x75da,0x75db,0x75dc,0x75dd,0x75de,0x75df,
+ 0x75e0,0x75e1,0x75e2,0x75e3,0x75e4,0x75e5,0x75e6,0x75e7,
+ 0x75e8,0x75e9,0x75ea,0x75eb,0x75ec,0x75ed,0x75ee,0x75ef,
+ 0x75f0,0x75f1,0x75f2,0x75f3,0x75f4,0x75f5,0x75f6,0x75f7,
+ 0x75f8,0x75f9,0x75fa,0x75fb,0x75fc,0x75fd,0x75fe,0x75ff,
+ 0x7600,0x7601,0x7602,0x7603,0x7604,0x7605,0x7606,0x7607,
+ 0x7608,0x7609,0x760a,0x760b,0x760c,0x760d,0x760e,0x760f,
+ 0x7610,0x7611,0x7612,0x7613,0x7614,0x7615,0x7616,0x7617,
+ 0x7618,0x7619,0x761a,0x761b,0x761c,0x761d,0x761e,0x761f,
+ 0x7620,0x7621,0x7622,0x7623,0x7624,0x7625,0x7626,0x7627,
+ 0x7628,0x7629,0x762a,0x762b,0x762c,0x762d,0x762e,0x762f,
+ 0x7630,0x7631,0x7632,0x7633,0x7634,0x7635,0x7636,0x7637,
+ 0x7638,0x7639,0x763a,0x763b,0x763c,0x763d,0x763e,0x763f,
+ 0x7640,0x7641,0x7642,0x7643,0x7644,0x7645,0x7646,0x7647,
+ 0x7648,0x7649,0x764a,0x764b,0x764c,0x764d,0x764e,0x764f,
+ 0x7650,0x7651,0x7652,0x7653,0x7654,0x7655,0x7656,0x7657,
+ 0x7658,0x7659,0x765a,0x765b,0x765c,0x765d,0x765e,0x765f,
+ 0x7660,0x7661,0x7662,0x7663,0x7664,0x7665,0x7666,0x7667,
+ 0x7668,0x7669,0x766a,0x766b,0x766c,0x766d,0x766e,0x766f,
+ 0x7670,0x7671,0x7672,0x7673,0x7674,0x7675,0x7676,0x7677,
+ 0x7678,0x7679,0x767a,0x767b,0x767c,0x767d,0x767e,0x767f,
+ 0x7680,0x7681,0x7682,0x7683,0x7684,0x7685,0x7686,0x7687,
+ 0x7688,0x7689,0x768a,0x768b,0x768c,0x768d,0x768e,0x768f,
+ 0x7690,0x7691,0x7692,0x7693,0x7694,0x7695,0x7696,0x7697,
+ 0x7698,0x7699,0x769a,0x769b,0x769c,0x769d,0x769e,0x769f,
+ 0x76a0,0x76a1,0x76a2,0x76a3,0x76a4,0x76a5,0x76a6,0x76a7,
+ 0x76a8,0x76a9,0x76aa,0x76ab,0x76ac,0x76ad,0x76ae,0x76af,
+ 0x76b0,0x76b1,0x76b2,0x76b3,0x76b4,0x76b5,0x76b6,0x76b7,
+ 0x76b8,0x76b9,0x76ba,0x76bb,0x76bc,0x76bd,0x76be,0x76bf,
+ 0x76c0,0x76c1,0x76c2,0x76c3,0x76c4,0x76c5,0x76c6,0x76c7,
+ 0x76c8,0x76c9,0x76ca,0x76cb,0x76cc,0x76cd,0x76ce,0x76cf,
+ 0x76d0,0x76d1,0x76d2,0x76d3,0x76d4,0x76d5,0x76d6,0x76d7,
+ 0x76d8,0x76d9,0x76da,0x76db,0x76dc,0x76dd,0x76de,0x76df,
+ 0x76e0,0x76e1,0x76e2,0x76e3,0x76e4,0x76e5,0x76e6,0x76e7,
+ 0x76e8,0x76e9,0x76ea,0x76eb,0x76ec,0x76ed,0x76ee,0x76ef,
+ 0x76f0,0x76f1,0x76f2,0x76f3,0x76f4,0x76f5,0x76f6,0x76f7,
+ 0x76f8,0x76f9,0x76fa,0x76fb,0x76fc,0x76fd,0x76fe,0x76ff,
+ 0x7700,0x7701,0x7702,0x7703,0x7704,0x7705,0x7706,0x7707,
+ 0x7708,0x7709,0x770a,0x770b,0x770c,0x770d,0x770e,0x770f,
+ 0x7710,0x7711,0x7712,0x7713,0x7714,0x7715,0x7716,0x7717,
+ 0x7718,0x7719,0x771a,0x771b,0x771c,0x771d,0x771e,0x771f,
+ 0x7720,0x7721,0x7722,0x7723,0x7724,0x7725,0x7726,0x7727,
+ 0x7728,0x7729,0x772a,0x772b,0x772c,0x772d,0x772e,0x772f,
+ 0x7730,0x7731,0x7732,0x7733,0x7734,0x7735,0x7736,0x7737,
+ 0x7738,0x7739,0x773a,0x773b,0x773c,0x773d,0x773e,0x773f,
+ 0x7740,0x7741,0x7742,0x7743,0x7744,0x7745,0x7746,0x7747,
+ 0x7748,0x7749,0x774a,0x774b,0x774c,0x774d,0x774e,0x774f,
+ 0x7750,0x7751,0x7752,0x7753,0x7754,0x7755,0x7756,0x7757,
+ 0x7758,0x7759,0x775a,0x775b,0x775c,0x775d,0x775e,0x775f,
+ 0x7760,0x7761,0x7762,0x7763,0x7764,0x7765,0x7766,0x7767,
+ 0x7768,0x7769,0x776a,0x776b,0x776c,0x776d,0x776e,0x776f,
+ 0x7770,0x7771,0x7772,0x7773,0x7774,0x7775,0x7776,0x7777,
+ 0x7778,0x7779,0x777a,0x777b,0x777c,0x777d,0x777e,0x777f,
+ 0x7780,0x7781,0x7782,0x7783,0x7784,0x7785,0x7786,0x7787,
+ 0x7788,0x7789,0x778a,0x778b,0x778c,0x778d,0x778e,0x778f,
+ 0x7790,0x7791,0x7792,0x7793,0x7794,0x7795,0x7796,0x7797,
+ 0x7798,0x7799,0x779a,0x779b,0x779c,0x779d,0x779e,0x779f,
+ 0x77a0,0x77a1,0x77a2,0x77a3,0x77a4,0x77a5,0x77a6,0x77a7,
+ 0x77a8,0x77a9,0x77aa,0x77ab,0x77ac,0x77ad,0x77ae,0x77af,
+ 0x77b0,0x77b1,0x77b2,0x77b3,0x77b4,0x77b5,0x77b6,0x77b7,
+ 0x77b8,0x77b9,0x77ba,0x77bb,0x77bc,0x77bd,0x77be,0x77bf,
+ 0x77c0,0x77c1,0x77c2,0x77c3,0x77c4,0x77c5,0x77c6,0x77c7,
+ 0x77c8,0x77c9,0x77ca,0x77cb,0x77cc,0x77cd,0x77ce,0x77cf,
+ 0x77d0,0x77d1,0x77d2,0x77d3,0x77d4,0x77d5,0x77d6,0x77d7,
+ 0x77d8,0x77d9,0x77da,0x77db,0x77dc,0x77dd,0x77de,0x77df,
+ 0x77e0,0x77e1,0x77e2,0x77e3,0x77e4,0x77e5,0x77e6,0x77e7,
+ 0x77e8,0x77e9,0x77ea,0x77eb,0x77ec,0x77ed,0x77ee,0x77ef,
+ 0x77f0,0x77f1,0x77f2,0x77f3,0x77f4,0x77f5,0x77f6,0x77f7,
+ 0x77f8,0x77f9,0x77fa,0x77fb,0x77fc,0x77fd,0x77fe,0x77ff,
+ 0x7800,0x7801,0x7802,0x7803,0x7804,0x7805,0x7806,0x7807,
+ 0x7808,0x7809,0x780a,0x780b,0x780c,0x780d,0x780e,0x780f,
+ 0x7810,0x7811,0x7812,0x7813,0x7814,0x7815,0x7816,0x7817,
+ 0x7818,0x7819,0x781a,0x781b,0x781c,0x781d,0x781e,0x781f,
+ 0x7820,0x7821,0x7822,0x7823,0x7824,0x7825,0x7826,0x7827,
+ 0x7828,0x7829,0x782a,0x782b,0x782c,0x782d,0x782e,0x782f,
+ 0x7830,0x7831,0x7832,0x7833,0x7834,0x7835,0x7836,0x7837,
+ 0x7838,0x7839,0x783a,0x783b,0x783c,0x783d,0x783e,0x783f,
+ 0x7840,0x7841,0x7842,0x7843,0x7844,0x7845,0x7846,0x7847,
+ 0x7848,0x7849,0x784a,0x784b,0x784c,0x784d,0x784e,0x784f,
+ 0x7850,0x7851,0x7852,0x7853,0x7854,0x7855,0x7856,0x7857,
+ 0x7858,0x7859,0x785a,0x785b,0x785c,0x785d,0x785e,0x785f,
+ 0x7860,0x7861,0x7862,0x7863,0x7864,0x7865,0x7866,0x7867,
+ 0x7868,0x7869,0x786a,0x786b,0x786c,0x786d,0x786e,0x786f,
+ 0x7870,0x7871,0x7872,0x7873,0x7874,0x7875,0x7876,0x7877,
+ 0x7878,0x7879,0x787a,0x787b,0x787c,0x787d,0x787e,0x787f,
+ 0x7880,0x7881,0x7882,0x7883,0x7884,0x7885,0x7886,0x7887,
+ 0x7888,0x7889,0x788a,0x788b,0x788c,0x788d,0x788e,0x788f,
+ 0x7890,0x7891,0x7892,0x7893,0x7894,0x7895,0x7896,0x7897,
+ 0x7898,0x7899,0x789a,0x789b,0x789c,0x789d,0x789e,0x789f,
+ 0x78a0,0x78a1,0x78a2,0x78a3,0x78a4,0x78a5,0x78a6,0x78a7,
+ 0x78a8,0x78a9,0x78aa,0x78ab,0x78ac,0x78ad,0x78ae,0x78af,
+ 0x78b0,0x78b1,0x78b2,0x78b3,0x78b4,0x78b5,0x78b6,0x78b7,
+ 0x78b8,0x78b9,0x78ba,0x78bb,0x78bc,0x78bd,0x78be,0x78bf,
+ 0x78c0,0x78c1,0x78c2,0x78c3,0x78c4,0x78c5,0x78c6,0x78c7,
+ 0x78c8,0x78c9,0x78ca,0x78cb,0x78cc,0x78cd,0x78ce,0x78cf,
+ 0x78d0,0x78d1,0x78d2,0x78d3,0x78d4,0x78d5,0x78d6,0x78d7,
+ 0x78d8,0x78d9,0x78da,0x78db,0x78dc,0x78dd,0x78de,0x78df,
+ 0x78e0,0x78e1,0x78e2,0x78e3,0x78e4,0x78e5,0x78e6,0x78e7,
+ 0x78e8,0x78e9,0x78ea,0x78eb,0x78ec,0x78ed,0x78ee,0x78ef,
+ 0x78f0,0x78f1,0x78f2,0x78f3,0x78f4,0x78f5,0x78f6,0x78f7,
+ 0x78f8,0x78f9,0x78fa,0x78fb,0x78fc,0x78fd,0x78fe,0x78ff,
+ 0x7900,0x7901,0x7902,0x7903,0x7904,0x7905,0x7906,0x7907,
+ 0x7908,0x7909,0x790a,0x790b,0x790c,0x790d,0x790e,0x790f,
+ 0x7910,0x7911,0x7912,0x7913,0x7914,0x7915,0x7916,0x7917,
+ 0x7918,0x7919,0x791a,0x791b,0x791c,0x791d,0x791e,0x791f,
+ 0x7920,0x7921,0x7922,0x7923,0x7924,0x7925,0x7926,0x7927,
+ 0x7928,0x7929,0x792a,0x792b,0x792c,0x792d,0x792e,0x792f,
+ 0x7930,0x7931,0x7932,0x7933,0x7934,0x7935,0x7936,0x7937,
+ 0x7938,0x7939,0x793a,0x793b,0x793c,0x793d,0x793e,0x793f,
+ 0x7940,0x7941,0x7942,0x7943,0x7944,0x7945,0x7946,0x7947,
+ 0x7948,0x7949,0x794a,0x794b,0x794c,0x794d,0x794e,0x794f,
+ 0x7950,0x7951,0x7952,0x7953,0x7954,0x7955,0x7956,0x7957,
+ 0x7958,0x7959,0x795a,0x795b,0x795c,0x795d,0x795e,0x795f,
+ 0x7960,0x7961,0x7962,0x7963,0x7964,0x7965,0x7966,0x7967,
+ 0x7968,0x7969,0x796a,0x796b,0x796c,0x796d,0x796e,0x796f,
+ 0x7970,0x7971,0x7972,0x7973,0x7974,0x7975,0x7976,0x7977,
+ 0x7978,0x7979,0x797a,0x797b,0x797c,0x797d,0x797e,0x797f,
+ 0x7980,0x7981,0x7982,0x7983,0x7984,0x7985,0x7986,0x7987,
+ 0x7988,0x7989,0x798a,0x798b,0x798c,0x798d,0x798e,0x798f,
+ 0x7990,0x7991,0x7992,0x7993,0x7994,0x7995,0x7996,0x7997,
+ 0x7998,0x7999,0x799a,0x799b,0x799c,0x799d,0x799e,0x799f,
+ 0x79a0,0x79a1,0x79a2,0x79a3,0x79a4,0x79a5,0x79a6,0x79a7,
+ 0x79a8,0x79a9,0x79aa,0x79ab,0x79ac,0x79ad,0x79ae,0x79af,
+ 0x79b0,0x79b1,0x79b2,0x79b3,0x79b4,0x79b5,0x79b6,0x79b7,
+ 0x79b8,0x79b9,0x79ba,0x79bb,0x79bc,0x79bd,0x79be,0x79bf,
+ 0x79c0,0x79c1,0x79c2,0x79c3,0x79c4,0x79c5,0x79c6,0x79c7,
+ 0x79c8,0x79c9,0x79ca,0x79cb,0x79cc,0x79cd,0x79ce,0x79cf,
+ 0x79d0,0x79d1,0x79d2,0x79d3,0x79d4,0x79d5,0x79d6,0x79d7,
+ 0x79d8,0x79d9,0x79da,0x79db,0x79dc,0x79dd,0x79de,0x79df,
+ 0x79e0,0x79e1,0x79e2,0x79e3,0x79e4,0x79e5,0x79e6,0x79e7,
+ 0x79e8,0x79e9,0x79ea,0x79eb,0x79ec,0x79ed,0x79ee,0x79ef,
+ 0x79f0,0x79f1,0x79f2,0x79f3,0x79f4,0x79f5,0x79f6,0x79f7,
+ 0x79f8,0x79f9,0x79fa,0x79fb,0x79fc,0x79fd,0x79fe,0x79ff,
+ 0x7a00,0x7a01,0x7a02,0x7a03,0x7a04,0x7a05,0x7a06,0x7a07,
+ 0x7a08,0x7a09,0x7a0a,0x7a0b,0x7a0c,0x7a0d,0x7a0e,0x7a0f,
+ 0x7a10,0x7a11,0x7a12,0x7a13,0x7a14,0x7a15,0x7a16,0x7a17,
+ 0x7a18,0x7a19,0x7a1a,0x7a1b,0x7a1c,0x7a1d,0x7a1e,0x7a1f,
+ 0x7a20,0x7a21,0x7a22,0x7a23,0x7a24,0x7a25,0x7a26,0x7a27,
+ 0x7a28,0x7a29,0x7a2a,0x7a2b,0x7a2c,0x7a2d,0x7a2e,0x7a2f,
+ 0x7a30,0x7a31,0x7a32,0x7a33,0x7a34,0x7a35,0x7a36,0x7a37,
+ 0x7a38,0x7a39,0x7a3a,0x7a3b,0x7a3c,0x7a3d,0x7a3e,0x7a3f,
+ 0x7a40,0x7a41,0x7a42,0x7a43,0x7a44,0x7a45,0x7a46,0x7a47,
+ 0x7a48,0x7a49,0x7a4a,0x7a4b,0x7a4c,0x7a4d,0x7a4e,0x7a4f,
+ 0x7a50,0x7a51,0x7a52,0x7a53,0x7a54,0x7a55,0x7a56,0x7a57,
+ 0x7a58,0x7a59,0x7a5a,0x7a5b,0x7a5c,0x7a5d,0x7a5e,0x7a5f,
+ 0x7a60,0x7a61,0x7a62,0x7a63,0x7a64,0x7a65,0x7a66,0x7a67,
+ 0x7a68,0x7a69,0x7a6a,0x7a6b,0x7a6c,0x7a6d,0x7a6e,0x7a6f,
+ 0x7a70,0x7a71,0x7a72,0x7a73,0x7a74,0x7a75,0x7a76,0x7a77,
+ 0x7a78,0x7a79,0x7a7a,0x7a7b,0x7a7c,0x7a7d,0x7a7e,0x7a7f,
+ 0x7a80,0x7a81,0x7a82,0x7a83,0x7a84,0x7a85,0x7a86,0x7a87,
+ 0x7a88,0x7a89,0x7a8a,0x7a8b,0x7a8c,0x7a8d,0x7a8e,0x7a8f,
+ 0x7a90,0x7a91,0x7a92,0x7a93,0x7a94,0x7a95,0x7a96,0x7a97,
+ 0x7a98,0x7a99,0x7a9a,0x7a9b,0x7a9c,0x7a9d,0x7a9e,0x7a9f,
+ 0x7aa0,0x7aa1,0x7aa2,0x7aa3,0x7aa4,0x7aa5,0x7aa6,0x7aa7,
+ 0x7aa8,0x7aa9,0x7aaa,0x7aab,0x7aac,0x7aad,0x7aae,0x7aaf,
+ 0x7ab0,0x7ab1,0x7ab2,0x7ab3,0x7ab4,0x7ab5,0x7ab6,0x7ab7,
+ 0x7ab8,0x7ab9,0x7aba,0x7abb,0x7abc,0x7abd,0x7abe,0x7abf,
+ 0x7ac0,0x7ac1,0x7ac2,0x7ac3,0x7ac4,0x7ac5,0x7ac6,0x7ac7,
+ 0x7ac8,0x7ac9,0x7aca,0x7acb,0x7acc,0x7acd,0x7ace,0x7acf,
+ 0x7ad0,0x7ad1,0x7ad2,0x7ad3,0x7ad4,0x7ad5,0x7ad6,0x7ad7,
+ 0x7ad8,0x7ad9,0x7ada,0x7adb,0x7adc,0x7add,0x7ade,0x7adf,
+ 0x7ae0,0x7ae1,0x7ae2,0x7ae3,0x7ae4,0x7ae5,0x7ae6,0x7ae7,
+ 0x7ae8,0x7ae9,0x7aea,0x7aeb,0x7aec,0x7aed,0x7aee,0x7aef,
+ 0x7af0,0x7af1,0x7af2,0x7af3,0x7af4,0x7af5,0x7af6,0x7af7,
+ 0x7af8,0x7af9,0x7afa,0x7afb,0x7afc,0x7afd,0x7afe,0x7aff,
+ 0x7b00,0x7b01,0x7b02,0x7b03,0x7b04,0x7b05,0x7b06,0x7b07,
+ 0x7b08,0x7b09,0x7b0a,0x7b0b,0x7b0c,0x7b0d,0x7b0e,0x7b0f,
+ 0x7b10,0x7b11,0x7b12,0x7b13,0x7b14,0x7b15,0x7b16,0x7b17,
+ 0x7b18,0x7b19,0x7b1a,0x7b1b,0x7b1c,0x7b1d,0x7b1e,0x7b1f,
+ 0x7b20,0x7b21,0x7b22,0x7b23,0x7b24,0x7b25,0x7b26,0x7b27,
+ 0x7b28,0x7b29,0x7b2a,0x7b2b,0x7b2c,0x7b2d,0x7b2e,0x7b2f,
+ 0x7b30,0x7b31,0x7b32,0x7b33,0x7b34,0x7b35,0x7b36,0x7b37,
+ 0x7b38,0x7b39,0x7b3a,0x7b3b,0x7b3c,0x7b3d,0x7b3e,0x7b3f,
+ 0x7b40,0x7b41,0x7b42,0x7b43,0x7b44,0x7b45,0x7b46,0x7b47,
+ 0x7b48,0x7b49,0x7b4a,0x7b4b,0x7b4c,0x7b4d,0x7b4e,0x7b4f,
+ 0x7b50,0x7b51,0x7b52,0x7b53,0x7b54,0x7b55,0x7b56,0x7b57,
+ 0x7b58,0x7b59,0x7b5a,0x7b5b,0x7b5c,0x7b5d,0x7b5e,0x7b5f,
+ 0x7b60,0x7b61,0x7b62,0x7b63,0x7b64,0x7b65,0x7b66,0x7b67,
+ 0x7b68,0x7b69,0x7b6a,0x7b6b,0x7b6c,0x7b6d,0x7b6e,0x7b6f,
+ 0x7b70,0x7b71,0x7b72,0x7b73,0x7b74,0x7b75,0x7b76,0x7b77,
+ 0x7b78,0x7b79,0x7b7a,0x7b7b,0x7b7c,0x7b7d,0x7b7e,0x7b7f,
+ 0x7b80,0x7b81,0x7b82,0x7b83,0x7b84,0x7b85,0x7b86,0x7b87,
+ 0x7b88,0x7b89,0x7b8a,0x7b8b,0x7b8c,0x7b8d,0x7b8e,0x7b8f,
+ 0x7b90,0x7b91,0x7b92,0x7b93,0x7b94,0x7b95,0x7b96,0x7b97,
+ 0x7b98,0x7b99,0x7b9a,0x7b9b,0x7b9c,0x7b9d,0x7b9e,0x7b9f,
+ 0x7ba0,0x7ba1,0x7ba2,0x7ba3,0x7ba4,0x7ba5,0x7ba6,0x7ba7,
+ 0x7ba8,0x7ba9,0x7baa,0x7bab,0x7bac,0x7bad,0x7bae,0x7baf,
+ 0x7bb0,0x7bb1,0x7bb2,0x7bb3,0x7bb4,0x7bb5,0x7bb6,0x7bb7,
+ 0x7bb8,0x7bb9,0x7bba,0x7bbb,0x7bbc,0x7bbd,0x7bbe,0x7bbf,
+ 0x7bc0,0x7bc1,0x7bc2,0x7bc3,0x7bc4,0x7bc5,0x7bc6,0x7bc7,
+ 0x7bc8,0x7bc9,0x7bca,0x7bcb,0x7bcc,0x7bcd,0x7bce,0x7bcf,
+ 0x7bd0,0x7bd1,0x7bd2,0x7bd3,0x7bd4,0x7bd5,0x7bd6,0x7bd7,
+ 0x7bd8,0x7bd9,0x7bda,0x7bdb,0x7bdc,0x7bdd,0x7bde,0x7bdf,
+ 0x7be0,0x7be1,0x7be2,0x7be3,0x7be4,0x7be5,0x7be6,0x7be7,
+ 0x7be8,0x7be9,0x7bea,0x7beb,0x7bec,0x7bed,0x7bee,0x7bef,
+ 0x7bf0,0x7bf1,0x7bf2,0x7bf3,0x7bf4,0x7bf5,0x7bf6,0x7bf7,
+ 0x7bf8,0x7bf9,0x7bfa,0x7bfb,0x7bfc,0x7bfd,0x7bfe,0x7bff,
+ 0x7c00,0x7c01,0x7c02,0x7c03,0x7c04,0x7c05,0x7c06,0x7c07,
+ 0x7c08,0x7c09,0x7c0a,0x7c0b,0x7c0c,0x7c0d,0x7c0e,0x7c0f,
+ 0x7c10,0x7c11,0x7c12,0x7c13,0x7c14,0x7c15,0x7c16,0x7c17,
+ 0x7c18,0x7c19,0x7c1a,0x7c1b,0x7c1c,0x7c1d,0x7c1e,0x7c1f,
+ 0x7c20,0x7c21,0x7c22,0x7c23,0x7c24,0x7c25,0x7c26,0x7c27,
+ 0x7c28,0x7c29,0x7c2a,0x7c2b,0x7c2c,0x7c2d,0x7c2e,0x7c2f,
+ 0x7c30,0x7c31,0x7c32,0x7c33,0x7c34,0x7c35,0x7c36,0x7c37,
+ 0x7c38,0x7c39,0x7c3a,0x7c3b,0x7c3c,0x7c3d,0x7c3e,0x7c3f,
+ 0x7c40,0x7c41,0x7c42,0x7c43,0x7c44,0x7c45,0x7c46,0x7c47,
+ 0x7c48,0x7c49,0x7c4a,0x7c4b,0x7c4c,0x7c4d,0x7c4e,0x7c4f,
+ 0x7c50,0x7c51,0x7c52,0x7c53,0x7c54,0x7c55,0x7c56,0x7c57,
+ 0x7c58,0x7c59,0x7c5a,0x7c5b,0x7c5c,0x7c5d,0x7c5e,0x7c5f,
+ 0x7c60,0x7c61,0x7c62,0x7c63,0x7c64,0x7c65,0x7c66,0x7c67,
+ 0x7c68,0x7c69,0x7c6a,0x7c6b,0x7c6c,0x7c6d,0x7c6e,0x7c6f,
+ 0x7c70,0x7c71,0x7c72,0x7c73,0x7c74,0x7c75,0x7c76,0x7c77,
+ 0x7c78,0x7c79,0x7c7a,0x7c7b,0x7c7c,0x7c7d,0x7c7e,0x7c7f,
+ 0x7c80,0x7c81,0x7c82,0x7c83,0x7c84,0x7c85,0x7c86,0x7c87,
+ 0x7c88,0x7c89,0x7c8a,0x7c8b,0x7c8c,0x7c8d,0x7c8e,0x7c8f,
+ 0x7c90,0x7c91,0x7c92,0x7c93,0x7c94,0x7c95,0x7c96,0x7c97,
+ 0x7c98,0x7c99,0x7c9a,0x7c9b,0x7c9c,0x7c9d,0x7c9e,0x7c9f,
+ 0x7ca0,0x7ca1,0x7ca2,0x7ca3,0x7ca4,0x7ca5,0x7ca6,0x7ca7,
+ 0x7ca8,0x7ca9,0x7caa,0x7cab,0x7cac,0x7cad,0x7cae,0x7caf,
+ 0x7cb0,0x7cb1,0x7cb2,0x7cb3,0x7cb4,0x7cb5,0x7cb6,0x7cb7,
+ 0x7cb8,0x7cb9,0x7cba,0x7cbb,0x7cbc,0x7cbd,0x7cbe,0x7cbf,
+ 0x7cc0,0x7cc1,0x7cc2,0x7cc3,0x7cc4,0x7cc5,0x7cc6,0x7cc7,
+ 0x7cc8,0x7cc9,0x7cca,0x7ccb,0x7ccc,0x7ccd,0x7cce,0x7ccf,
+ 0x7cd0,0x7cd1,0x7cd2,0x7cd3,0x7cd4,0x7cd5,0x7cd6,0x7cd7,
+ 0x7cd8,0x7cd9,0x7cda,0x7cdb,0x7cdc,0x7cdd,0x7cde,0x7cdf,
+ 0x7ce0,0x7ce1,0x7ce2,0x7ce3,0x7ce4,0x7ce5,0x7ce6,0x7ce7,
+ 0x7ce8,0x7ce9,0x7cea,0x7ceb,0x7cec,0x7ced,0x7cee,0x7cef,
+ 0x7cf0,0x7cf1,0x7cf2,0x7cf3,0x7cf4,0x7cf5,0x7cf6,0x7cf7,
+ 0x7cf8,0x7cf9,0x7cfa,0x7cfb,0x7cfc,0x7cfd,0x7cfe,0x7cff,
+ 0x7d00,0x7d01,0x7d02,0x7d03,0x7d04,0x7d05,0x7d06,0x7d07,
+ 0x7d08,0x7d09,0x7d0a,0x7d0b,0x7d0c,0x7d0d,0x7d0e,0x7d0f,
+ 0x7d10,0x7d11,0x7d12,0x7d13,0x7d14,0x7d15,0x7d16,0x7d17,
+ 0x7d18,0x7d19,0x7d1a,0x7d1b,0x7d1c,0x7d1d,0x7d1e,0x7d1f,
+ 0x7d20,0x7d21,0x7d22,0x7d23,0x7d24,0x7d25,0x7d26,0x7d27,
+ 0x7d28,0x7d29,0x7d2a,0x7d2b,0x7d2c,0x7d2d,0x7d2e,0x7d2f,
+ 0x7d30,0x7d31,0x7d32,0x7d33,0x7d34,0x7d35,0x7d36,0x7d37,
+ 0x7d38,0x7d39,0x7d3a,0x7d3b,0x7d3c,0x7d3d,0x7d3e,0x7d3f,
+ 0x7d40,0x7d41,0x7d42,0x7d43,0x7d44,0x7d45,0x7d46,0x7d47,
+ 0x7d48,0x7d49,0x7d4a,0x7d4b,0x7d4c,0x7d4d,0x7d4e,0x7d4f,
+ 0x7d50,0x7d51,0x7d52,0x7d53,0x7d54,0x7d55,0x7d56,0x7d57,
+ 0x7d58,0x7d59,0x7d5a,0x7d5b,0x7d5c,0x7d5d,0x7d5e,0x7d5f,
+ 0x7d60,0x7d61,0x7d62,0x7d63,0x7d64,0x7d65,0x7d66,0x7d67,
+ 0x7d68,0x7d69,0x7d6a,0x7d6b,0x7d6c,0x7d6d,0x7d6e,0x7d6f,
+ 0x7d70,0x7d71,0x7d72,0x7d73,0x7d74,0x7d75,0x7d76,0x7d77,
+ 0x7d78,0x7d79,0x7d7a,0x7d7b,0x7d7c,0x7d7d,0x7d7e,0x7d7f,
+ 0x7d80,0x7d81,0x7d82,0x7d83,0x7d84,0x7d85,0x7d86,0x7d87,
+ 0x7d88,0x7d89,0x7d8a,0x7d8b,0x7d8c,0x7d8d,0x7d8e,0x7d8f,
+ 0x7d90,0x7d91,0x7d92,0x7d93,0x7d94,0x7d95,0x7d96,0x7d97,
+ 0x7d98,0x7d99,0x7d9a,0x7d9b,0x7d9c,0x7d9d,0x7d9e,0x7d9f,
+ 0x7da0,0x7da1,0x7da2,0x7da3,0x7da4,0x7da5,0x7da6,0x7da7,
+ 0x7da8,0x7da9,0x7daa,0x7dab,0x7dac,0x7dad,0x7dae,0x7daf,
+ 0x7db0,0x7db1,0x7db2,0x7db3,0x7db4,0x7db5,0x7db6,0x7db7,
+ 0x7db8,0x7db9,0x7dba,0x7dbb,0x7dbc,0x7dbd,0x7dbe,0x7dbf,
+ 0x7dc0,0x7dc1,0x7dc2,0x7dc3,0x7dc4,0x7dc5,0x7dc6,0x7dc7,
+ 0x7dc8,0x7dc9,0x7dca,0x7dcb,0x7dcc,0x7dcd,0x7dce,0x7dcf,
+ 0x7dd0,0x7dd1,0x7dd2,0x7dd3,0x7dd4,0x7dd5,0x7dd6,0x7dd7,
+ 0x7dd8,0x7dd9,0x7dda,0x7ddb,0x7ddc,0x7ddd,0x7dde,0x7ddf,
+ 0x7de0,0x7de1,0x7de2,0x7de3,0x7de4,0x7de5,0x7de6,0x7de7,
+ 0x7de8,0x7de9,0x7dea,0x7deb,0x7dec,0x7ded,0x7dee,0x7def,
+ 0x7df0,0x7df1,0x7df2,0x7df3,0x7df4,0x7df5,0x7df6,0x7df7,
+ 0x7df8,0x7df9,0x7dfa,0x7dfb,0x7dfc,0x7dfd,0x7dfe,0x7dff,
+ 0x7e00,0x7e01,0x7e02,0x7e03,0x7e04,0x7e05,0x7e06,0x7e07,
+ 0x7e08,0x7e09,0x7e0a,0x7e0b,0x7e0c,0x7e0d,0x7e0e,0x7e0f,
+ 0x7e10,0x7e11,0x7e12,0x7e13,0x7e14,0x7e15,0x7e16,0x7e17,
+ 0x7e18,0x7e19,0x7e1a,0x7e1b,0x7e1c,0x7e1d,0x7e1e,0x7e1f,
+ 0x7e20,0x7e21,0x7e22,0x7e23,0x7e24,0x7e25,0x7e26,0x7e27,
+ 0x7e28,0x7e29,0x7e2a,0x7e2b,0x7e2c,0x7e2d,0x7e2e,0x7e2f,
+ 0x7e30,0x7e31,0x7e32,0x7e33,0x7e34,0x7e35,0x7e36,0x7e37,
+ 0x7e38,0x7e39,0x7e3a,0x7e3b,0x7e3c,0x7e3d,0x7e3e,0x7e3f,
+ 0x7e40,0x7e41,0x7e42,0x7e43,0x7e44,0x7e45,0x7e46,0x7e47,
+ 0x7e48,0x7e49,0x7e4a,0x7e4b,0x7e4c,0x7e4d,0x7e4e,0x7e4f,
+ 0x7e50,0x7e51,0x7e52,0x7e53,0x7e54,0x7e55,0x7e56,0x7e57,
+ 0x7e58,0x7e59,0x7e5a,0x7e5b,0x7e5c,0x7e5d,0x7e5e,0x7e5f,
+ 0x7e60,0x7e61,0x7e62,0x7e63,0x7e64,0x7e65,0x7e66,0x7e67,
+ 0x7e68,0x7e69,0x7e6a,0x7e6b,0x7e6c,0x7e6d,0x7e6e,0x7e6f,
+ 0x7e70,0x7e71,0x7e72,0x7e73,0x7e74,0x7e75,0x7e76,0x7e77,
+ 0x7e78,0x7e79,0x7e7a,0x7e7b,0x7e7c,0x7e7d,0x7e7e,0x7e7f,
+ 0x7e80,0x7e81,0x7e82,0x7e83,0x7e84,0x7e85,0x7e86,0x7e87,
+ 0x7e88,0x7e89,0x7e8a,0x7e8b,0x7e8c,0x7e8d,0x7e8e,0x7e8f,
+ 0x7e90,0x7e91,0x7e92,0x7e93,0x7e94,0x7e95,0x7e96,0x7e97,
+ 0x7e98,0x7e99,0x7e9a,0x7e9b,0x7e9c,0x7e9d,0x7e9e,0x7e9f,
+ 0x7ea0,0x7ea1,0x7ea2,0x7ea3,0x7ea4,0x7ea5,0x7ea6,0x7ea7,
+ 0x7ea8,0x7ea9,0x7eaa,0x7eab,0x7eac,0x7ead,0x7eae,0x7eaf,
+ 0x7eb0,0x7eb1,0x7eb2,0x7eb3,0x7eb4,0x7eb5,0x7eb6,0x7eb7,
+ 0x7eb8,0x7eb9,0x7eba,0x7ebb,0x7ebc,0x7ebd,0x7ebe,0x7ebf,
+ 0x7ec0,0x7ec1,0x7ec2,0x7ec3,0x7ec4,0x7ec5,0x7ec6,0x7ec7,
+ 0x7ec8,0x7ec9,0x7eca,0x7ecb,0x7ecc,0x7ecd,0x7ece,0x7ecf,
+ 0x7ed0,0x7ed1,0x7ed2,0x7ed3,0x7ed4,0x7ed5,0x7ed6,0x7ed7,
+ 0x7ed8,0x7ed9,0x7eda,0x7edb,0x7edc,0x7edd,0x7ede,0x7edf,
+ 0x7ee0,0x7ee1,0x7ee2,0x7ee3,0x7ee4,0x7ee5,0x7ee6,0x7ee7,
+ 0x7ee8,0x7ee9,0x7eea,0x7eeb,0x7eec,0x7eed,0x7eee,0x7eef,
+ 0x7ef0,0x7ef1,0x7ef2,0x7ef3,0x7ef4,0x7ef5,0x7ef6,0x7ef7,
+ 0x7ef8,0x7ef9,0x7efa,0x7efb,0x7efc,0x7efd,0x7efe,0x7eff,
+ 0x7f00,0x7f01,0x7f02,0x7f03,0x7f04,0x7f05,0x7f06,0x7f07,
+ 0x7f08,0x7f09,0x7f0a,0x7f0b,0x7f0c,0x7f0d,0x7f0e,0x7f0f,
+ 0x7f10,0x7f11,0x7f12,0x7f13,0x7f14,0x7f15,0x7f16,0x7f17,
+ 0x7f18,0x7f19,0x7f1a,0x7f1b,0x7f1c,0x7f1d,0x7f1e,0x7f1f,
+ 0x7f20,0x7f21,0x7f22,0x7f23,0x7f24,0x7f25,0x7f26,0x7f27,
+ 0x7f28,0x7f29,0x7f2a,0x7f2b,0x7f2c,0x7f2d,0x7f2e,0x7f2f,
+ 0x7f30,0x7f31,0x7f32,0x7f33,0x7f34,0x7f35,0x7f36,0x7f37,
+ 0x7f38,0x7f39,0x7f3a,0x7f3b,0x7f3c,0x7f3d,0x7f3e,0x7f3f,
+ 0x7f40,0x7f41,0x7f42,0x7f43,0x7f44,0x7f45,0x7f46,0x7f47,
+ 0x7f48,0x7f49,0x7f4a,0x7f4b,0x7f4c,0x7f4d,0x7f4e,0x7f4f,
+ 0x7f50,0x7f51,0x7f52,0x7f53,0x7f54,0x7f55,0x7f56,0x7f57,
+ 0x7f58,0x7f59,0x7f5a,0x7f5b,0x7f5c,0x7f5d,0x7f5e,0x7f5f,
+ 0x7f60,0x7f61,0x7f62,0x7f63,0x7f64,0x7f65,0x7f66,0x7f67,
+ 0x7f68,0x7f69,0x7f6a,0x7f6b,0x7f6c,0x7f6d,0x7f6e,0x7f6f,
+ 0x7f70,0x7f71,0x7f72,0x7f73,0x7f74,0x7f75,0x7f76,0x7f77,
+ 0x7f78,0x7f79,0x7f7a,0x7f7b,0x7f7c,0x7f7d,0x7f7e,0x7f7f,
+ 0x7f80,0x7f81,0x7f82,0x7f83,0x7f84,0x7f85,0x7f86,0x7f87,
+ 0x7f88,0x7f89,0x7f8a,0x7f8b,0x7f8c,0x7f8d,0x7f8e,0x7f8f,
+ 0x7f90,0x7f91,0x7f92,0x7f93,0x7f94,0x7f95,0x7f96,0x7f97,
+ 0x7f98,0x7f99,0x7f9a,0x7f9b,0x7f9c,0x7f9d,0x7f9e,0x7f9f,
+ 0x7fa0,0x7fa1,0x7fa2,0x7fa3,0x7fa4,0x7fa5,0x7fa6,0x7fa7,
+ 0x7fa8,0x7fa9,0x7faa,0x7fab,0x7fac,0x7fad,0x7fae,0x7faf,
+ 0x7fb0,0x7fb1,0x7fb2,0x7fb3,0x7fb4,0x7fb5,0x7fb6,0x7fb7,
+ 0x7fb8,0x7fb9,0x7fba,0x7fbb,0x7fbc,0x7fbd,0x7fbe,0x7fbf,
+ 0x7fc0,0x7fc1,0x7fc2,0x7fc3,0x7fc4,0x7fc5,0x7fc6,0x7fc7,
+ 0x7fc8,0x7fc9,0x7fca,0x7fcb,0x7fcc,0x7fcd,0x7fce,0x7fcf,
+ 0x7fd0,0x7fd1,0x7fd2,0x7fd3,0x7fd4,0x7fd5,0x7fd6,0x7fd7,
+ 0x7fd8,0x7fd9,0x7fda,0x7fdb,0x7fdc,0x7fdd,0x7fde,0x7fdf,
+ 0x7fe0,0x7fe1,0x7fe2,0x7fe3,0x7fe4,0x7fe5,0x7fe6,0x7fe7,
+ 0x7fe8,0x7fe9,0x7fea,0x7feb,0x7fec,0x7fed,0x7fee,0x7fef,
+ 0x7ff0,0x7ff1,0x7ff2,0x7ff3,0x7ff4,0x7ff5,0x7ff6,0x7ff7,
+ 0x7ff8,0x7ff9,0x7ffa,0x7ffb,0x7ffc,0x7ffd,0x7ffe,0x7fff,
+ 0x8000,0x8001,0x8002,0x8003,0x8004,0x8005,0x8006,0x8007,
+ 0x8008,0x8009,0x800a,0x800b,0x800c,0x800d,0x800e,0x800f,
+ 0x8010,0x8011,0x8012,0x8013,0x8014,0x8015,0x8016,0x8017,
+ 0x8018,0x8019,0x801a,0x801b,0x801c,0x801d,0x801e,0x801f,
+ 0x8020,0x8021,0x8022,0x8023,0x8024,0x8025,0x8026,0x8027,
+ 0x8028,0x8029,0x802a,0x802b,0x802c,0x802d,0x802e,0x802f,
+ 0x8030,0x8031,0x8032,0x8033,0x8034,0x8035,0x8036,0x8037,
+ 0x8038,0x8039,0x803a,0x803b,0x803c,0x803d,0x803e,0x803f,
+ 0x8040,0x8041,0x8042,0x8043,0x8044,0x8045,0x8046,0x8047,
+ 0x8048,0x8049,0x804a,0x804b,0x804c,0x804d,0x804e,0x804f,
+ 0x8050,0x8051,0x8052,0x8053,0x8054,0x8055,0x8056,0x8057,
+ 0x8058,0x8059,0x805a,0x805b,0x805c,0x805d,0x805e,0x805f,
+ 0x8060,0x8061,0x8062,0x8063,0x8064,0x8065,0x8066,0x8067,
+ 0x8068,0x8069,0x806a,0x806b,0x806c,0x806d,0x806e,0x806f,
+ 0x8070,0x8071,0x8072,0x8073,0x8074,0x8075,0x8076,0x8077,
+ 0x8078,0x8079,0x807a,0x807b,0x807c,0x807d,0x807e,0x807f,
+ 0x8080,0x8081,0x8082,0x8083,0x8084,0x8085,0x8086,0x8087,
+ 0x8088,0x8089,0x808a,0x808b,0x808c,0x808d,0x808e,0x808f,
+ 0x8090,0x8091,0x8092,0x8093,0x8094,0x8095,0x8096,0x8097,
+ 0x8098,0x8099,0x809a,0x809b,0x809c,0x809d,0x809e,0x809f,
+ 0x80a0,0x80a1,0x80a2,0x80a3,0x80a4,0x80a5,0x80a6,0x80a7,
+ 0x80a8,0x80a9,0x80aa,0x80ab,0x80ac,0x80ad,0x80ae,0x80af,
+ 0x80b0,0x80b1,0x80b2,0x80b3,0x80b4,0x80b5,0x80b6,0x80b7,
+ 0x80b8,0x80b9,0x80ba,0x80bb,0x80bc,0x80bd,0x80be,0x80bf,
+ 0x80c0,0x80c1,0x80c2,0x80c3,0x80c4,0x80c5,0x80c6,0x80c7,
+ 0x80c8,0x80c9,0x80ca,0x80cb,0x80cc,0x80cd,0x80ce,0x80cf,
+ 0x80d0,0x80d1,0x80d2,0x80d3,0x80d4,0x80d5,0x80d6,0x80d7,
+ 0x80d8,0x80d9,0x80da,0x80db,0x80dc,0x80dd,0x80de,0x80df,
+ 0x80e0,0x80e1,0x80e2,0x80e3,0x80e4,0x80e5,0x80e6,0x80e7,
+ 0x80e8,0x80e9,0x80ea,0x80eb,0x80ec,0x80ed,0x80ee,0x80ef,
+ 0x80f0,0x80f1,0x80f2,0x80f3,0x80f4,0x80f5,0x80f6,0x80f7,
+ 0x80f8,0x80f9,0x80fa,0x80fb,0x80fc,0x80fd,0x80fe,0x80ff,
+ 0x8100,0x8101,0x8102,0x8103,0x8104,0x8105,0x8106,0x8107,
+ 0x8108,0x8109,0x810a,0x810b,0x810c,0x810d,0x810e,0x810f,
+ 0x8110,0x8111,0x8112,0x8113,0x8114,0x8115,0x8116,0x8117,
+ 0x8118,0x8119,0x811a,0x811b,0x811c,0x811d,0x811e,0x811f,
+ 0x8120,0x8121,0x8122,0x8123,0x8124,0x8125,0x8126,0x8127,
+ 0x8128,0x8129,0x812a,0x812b,0x812c,0x812d,0x812e,0x812f,
+ 0x8130,0x8131,0x8132,0x8133,0x8134,0x8135,0x8136,0x8137,
+ 0x8138,0x8139,0x813a,0x813b,0x813c,0x813d,0x813e,0x813f,
+ 0x8140,0x8141,0x8142,0x8143,0x8144,0x8145,0x8146,0x8147,
+ 0x8148,0x8149,0x814a,0x814b,0x814c,0x814d,0x814e,0x814f,
+ 0x8150,0x8151,0x8152,0x8153,0x8154,0x8155,0x8156,0x8157,
+ 0x8158,0x8159,0x815a,0x815b,0x815c,0x815d,0x815e,0x815f,
+ 0x8160,0x8161,0x8162,0x8163,0x8164,0x8165,0x8166,0x8167,
+ 0x8168,0x8169,0x816a,0x816b,0x816c,0x816d,0x816e,0x816f,
+ 0x8170,0x8171,0x8172,0x8173,0x8174,0x8175,0x8176,0x8177,
+ 0x8178,0x8179,0x817a,0x817b,0x817c,0x817d,0x817e,0x817f,
+ 0x8180,0x8181,0x8182,0x8183,0x8184,0x8185,0x8186,0x8187,
+ 0x8188,0x8189,0x818a,0x818b,0x818c,0x818d,0x818e,0x818f,
+ 0x8190,0x8191,0x8192,0x8193,0x8194,0x8195,0x8196,0x8197,
+ 0x8198,0x8199,0x819a,0x819b,0x819c,0x819d,0x819e,0x819f,
+ 0x81a0,0x81a1,0x81a2,0x81a3,0x81a4,0x81a5,0x81a6,0x81a7,
+ 0x81a8,0x81a9,0x81aa,0x81ab,0x81ac,0x81ad,0x81ae,0x81af,
+ 0x81b0,0x81b1,0x81b2,0x81b3,0x81b4,0x81b5,0x81b6,0x81b7,
+ 0x81b8,0x81b9,0x81ba,0x81bb,0x81bc,0x81bd,0x81be,0x81bf,
+ 0x81c0,0x81c1,0x81c2,0x81c3,0x81c4,0x81c5,0x81c6,0x81c7,
+ 0x81c8,0x81c9,0x81ca,0x81cb,0x81cc,0x81cd,0x81ce,0x81cf,
+ 0x81d0,0x81d1,0x81d2,0x81d3,0x81d4,0x81d5,0x81d6,0x81d7,
+ 0x81d8,0x81d9,0x81da,0x81db,0x81dc,0x81dd,0x81de,0x81df,
+ 0x81e0,0x81e1,0x81e2,0x81e3,0x81e4,0x81e5,0x81e6,0x81e7,
+ 0x81e8,0x81e9,0x81ea,0x81eb,0x81ec,0x81ed,0x81ee,0x81ef,
+ 0x81f0,0x81f1,0x81f2,0x81f3,0x81f4,0x81f5,0x81f6,0x81f7,
+ 0x81f8,0x81f9,0x81fa,0x81fb,0x81fc,0x81fd,0x81fe,0x81ff,
+ 0x8200,0x8201,0x8202,0x8203,0x8204,0x8205,0x8206,0x8207,
+ 0x8208,0x8209,0x820a,0x820b,0x820c,0x820d,0x820e,0x820f,
+ 0x8210,0x8211,0x8212,0x8213,0x8214,0x8215,0x8216,0x8217,
+ 0x8218,0x8219,0x821a,0x821b,0x821c,0x821d,0x821e,0x821f,
+ 0x8220,0x8221,0x8222,0x8223,0x8224,0x8225,0x8226,0x8227,
+ 0x8228,0x8229,0x822a,0x822b,0x822c,0x822d,0x822e,0x822f,
+ 0x8230,0x8231,0x8232,0x8233,0x8234,0x8235,0x8236,0x8237,
+ 0x8238,0x8239,0x823a,0x823b,0x823c,0x823d,0x823e,0x823f,
+ 0x8240,0x8241,0x8242,0x8243,0x8244,0x8245,0x8246,0x8247,
+ 0x8248,0x8249,0x824a,0x824b,0x824c,0x824d,0x824e,0x824f,
+ 0x8250,0x8251,0x8252,0x8253,0x8254,0x8255,0x8256,0x8257,
+ 0x8258,0x8259,0x825a,0x825b,0x825c,0x825d,0x825e,0x825f,
+ 0x8260,0x8261,0x8262,0x8263,0x8264,0x8265,0x8266,0x8267,
+ 0x8268,0x8269,0x826a,0x826b,0x826c,0x826d,0x826e,0x826f,
+ 0x8270,0x8271,0x8272,0x8273,0x8274,0x8275,0x8276,0x8277,
+ 0x8278,0x8279,0x827a,0x827b,0x827c,0x827d,0x827e,0x827f,
+ 0x8280,0x8281,0x8282,0x8283,0x8284,0x8285,0x8286,0x8287,
+ 0x8288,0x8289,0x828a,0x828b,0x828c,0x828d,0x828e,0x828f,
+ 0x8290,0x8291,0x8292,0x8293,0x8294,0x8295,0x8296,0x8297,
+ 0x8298,0x8299,0x829a,0x829b,0x829c,0x829d,0x829e,0x829f,
+ 0x82a0,0x82a1,0x82a2,0x82a3,0x82a4,0x82a5,0x82a6,0x82a7,
+ 0x82a8,0x82a9,0x82aa,0x82ab,0x82ac,0x82ad,0x82ae,0x82af,
+ 0x82b0,0x82b1,0x82b2,0x82b3,0x82b4,0x82b5,0x82b6,0x82b7,
+ 0x82b8,0x82b9,0x82ba,0x82bb,0x82bc,0x82bd,0x82be,0x82bf,
+ 0x82c0,0x82c1,0x82c2,0x82c3,0x82c4,0x82c5,0x82c6,0x82c7,
+ 0x82c8,0x82c9,0x82ca,0x82cb,0x82cc,0x82cd,0x82ce,0x82cf,
+ 0x82d0,0x82d1,0x82d2,0x82d3,0x82d4,0x82d5,0x82d6,0x82d7,
+ 0x82d8,0x82d9,0x82da,0x82db,0x82dc,0x82dd,0x82de,0x82df,
+ 0x82e0,0x82e1,0x82e2,0x82e3,0x82e4,0x82e5,0x82e6,0x82e7,
+ 0x82e8,0x82e9,0x82ea,0x82eb,0x82ec,0x82ed,0x82ee,0x82ef,
+ 0x82f0,0x82f1,0x82f2,0x82f3,0x82f4,0x82f5,0x82f6,0x82f7,
+ 0x82f8,0x82f9,0x82fa,0x82fb,0x82fc,0x82fd,0x82fe,0x82ff,
+ 0x8300,0x8301,0x8302,0x8303,0x8304,0x8305,0x8306,0x8307,
+ 0x8308,0x8309,0x830a,0x830b,0x830c,0x830d,0x830e,0x830f,
+ 0x8310,0x8311,0x8312,0x8313,0x8314,0x8315,0x8316,0x8317,
+ 0x8318,0x8319,0x831a,0x831b,0x831c,0x831d,0x831e,0x831f,
+ 0x8320,0x8321,0x8322,0x8323,0x8324,0x8325,0x8326,0x8327,
+ 0x8328,0x8329,0x832a,0x832b,0x832c,0x832d,0x832e,0x832f,
+ 0x8330,0x8331,0x8332,0x8333,0x8334,0x8335,0x8336,0x8337,
+ 0x8338,0x8339,0x833a,0x833b,0x833c,0x833d,0x833e,0x833f,
+ 0x8340,0x8341,0x8342,0x8343,0x8344,0x8345,0x8346,0x8347,
+ 0x8348,0x8349,0x834a,0x834b,0x834c,0x834d,0x834e,0x834f,
+ 0x8350,0x8351,0x8352,0x8353,0x8354,0x8355,0x8356,0x8357,
+ 0x8358,0x8359,0x835a,0x835b,0x835c,0x835d,0x835e,0x835f,
+ 0x8360,0x8361,0x8362,0x8363,0x8364,0x8365,0x8366,0x8367,
+ 0x8368,0x8369,0x836a,0x836b,0x836c,0x836d,0x836e,0x836f,
+ 0x8370,0x8371,0x8372,0x8373,0x8374,0x8375,0x8376,0x8377,
+ 0x8378,0x8379,0x837a,0x837b,0x837c,0x837d,0x837e,0x837f,
+ 0x8380,0x8381,0x8382,0x8383,0x8384,0x8385,0x8386,0x8387,
+ 0x8388,0x8389,0x838a,0x838b,0x838c,0x838d,0x838e,0x838f,
+ 0x8390,0x8391,0x8392,0x8393,0x8394,0x8395,0x8396,0x8397,
+ 0x8398,0x8399,0x839a,0x839b,0x839c,0x839d,0x839e,0x839f,
+ 0x83a0,0x83a1,0x83a2,0x83a3,0x83a4,0x83a5,0x83a6,0x83a7,
+ 0x83a8,0x83a9,0x83aa,0x83ab,0x83ac,0x83ad,0x83ae,0x83af,
+ 0x83b0,0x83b1,0x83b2,0x83b3,0x83b4,0x83b5,0x83b6,0x83b7,
+ 0x83b8,0x83b9,0x83ba,0x83bb,0x83bc,0x83bd,0x83be,0x83bf,
+ 0x83c0,0x83c1,0x83c2,0x83c3,0x83c4,0x83c5,0x83c6,0x83c7,
+ 0x83c8,0x83c9,0x83ca,0x83cb,0x83cc,0x83cd,0x83ce,0x83cf,
+ 0x83d0,0x83d1,0x83d2,0x83d3,0x83d4,0x83d5,0x83d6,0x83d7,
+ 0x83d8,0x83d9,0x83da,0x83db,0x83dc,0x83dd,0x83de,0x83df,
+ 0x83e0,0x83e1,0x83e2,0x83e3,0x83e4,0x83e5,0x83e6,0x83e7,
+ 0x83e8,0x83e9,0x83ea,0x83eb,0x83ec,0x83ed,0x83ee,0x83ef,
+ 0x83f0,0x83f1,0x83f2,0x83f3,0x83f4,0x83f5,0x83f6,0x83f7,
+ 0x83f8,0x83f9,0x83fa,0x83fb,0x83fc,0x83fd,0x83fe,0x83ff,
+ 0x8400,0x8401,0x8402,0x8403,0x8404,0x8405,0x8406,0x8407,
+ 0x8408,0x8409,0x840a,0x840b,0x840c,0x840d,0x840e,0x840f,
+ 0x8410,0x8411,0x8412,0x8413,0x8414,0x8415,0x8416,0x8417,
+ 0x8418,0x8419,0x841a,0x841b,0x841c,0x841d,0x841e,0x841f,
+ 0x8420,0x8421,0x8422,0x8423,0x8424,0x8425,0x8426,0x8427,
+ 0x8428,0x8429,0x842a,0x842b,0x842c,0x842d,0x842e,0x842f,
+ 0x8430,0x8431,0x8432,0x8433,0x8434,0x8435,0x8436,0x8437,
+ 0x8438,0x8439,0x843a,0x843b,0x843c,0x843d,0x843e,0x843f,
+ 0x8440,0x8441,0x8442,0x8443,0x8444,0x8445,0x8446,0x8447,
+ 0x8448,0x8449,0x844a,0x844b,0x844c,0x844d,0x844e,0x844f,
+ 0x8450,0x8451,0x8452,0x8453,0x8454,0x8455,0x8456,0x8457,
+ 0x8458,0x8459,0x845a,0x845b,0x845c,0x845d,0x845e,0x845f,
+ 0x8460,0x8461,0x8462,0x8463,0x8464,0x8465,0x8466,0x8467,
+ 0x8468,0x8469,0x846a,0x846b,0x846c,0x846d,0x846e,0x846f,
+ 0x8470,0x8471,0x8472,0x8473,0x8474,0x8475,0x8476,0x8477,
+ 0x8478,0x8479,0x847a,0x847b,0x847c,0x847d,0x847e,0x847f,
+ 0x8480,0x8481,0x8482,0x8483,0x8484,0x8485,0x8486,0x8487,
+ 0x8488,0x8489,0x848a,0x848b,0x848c,0x848d,0x848e,0x848f,
+ 0x8490,0x8491,0x8492,0x8493,0x8494,0x8495,0x8496,0x8497,
+ 0x8498,0x8499,0x849a,0x849b,0x849c,0x849d,0x849e,0x849f,
+ 0x84a0,0x84a1,0x84a2,0x84a3,0x84a4,0x84a5,0x84a6,0x84a7,
+ 0x84a8,0x84a9,0x84aa,0x84ab,0x84ac,0x84ad,0x84ae,0x84af,
+ 0x84b0,0x84b1,0x84b2,0x84b3,0x84b4,0x84b5,0x84b6,0x84b7,
+ 0x84b8,0x84b9,0x84ba,0x84bb,0x84bc,0x84bd,0x84be,0x84bf,
+ 0x84c0,0x84c1,0x84c2,0x84c3,0x84c4,0x84c5,0x84c6,0x84c7,
+ 0x84c8,0x84c9,0x84ca,0x84cb,0x84cc,0x84cd,0x84ce,0x84cf,
+ 0x84d0,0x84d1,0x84d2,0x84d3,0x84d4,0x84d5,0x84d6,0x84d7,
+ 0x84d8,0x84d9,0x84da,0x84db,0x84dc,0x84dd,0x84de,0x84df,
+ 0x84e0,0x84e1,0x84e2,0x84e3,0x84e4,0x84e5,0x84e6,0x84e7,
+ 0x84e8,0x84e9,0x84ea,0x84eb,0x84ec,0x84ed,0x84ee,0x84ef,
+ 0x84f0,0x84f1,0x84f2,0x84f3,0x84f4,0x84f5,0x84f6,0x84f7,
+ 0x84f8,0x84f9,0x84fa,0x84fb,0x84fc,0x84fd,0x84fe,0x84ff,
+ 0x8500,0x8501,0x8502,0x8503,0x8504,0x8505,0x8506,0x8507,
+ 0x8508,0x8509,0x850a,0x850b,0x850c,0x850d,0x850e,0x850f,
+ 0x8510,0x8511,0x8512,0x8513,0x8514,0x8515,0x8516,0x8517,
+ 0x8518,0x8519,0x851a,0x851b,0x851c,0x851d,0x851e,0x851f,
+ 0x8520,0x8521,0x8522,0x8523,0x8524,0x8525,0x8526,0x8527,
+ 0x8528,0x8529,0x852a,0x852b,0x852c,0x852d,0x852e,0x852f,
+ 0x8530,0x8531,0x8532,0x8533,0x8534,0x8535,0x8536,0x8537,
+ 0x8538,0x8539,0x853a,0x853b,0x853c,0x853d,0x853e,0x853f,
+ 0x8540,0x8541,0x8542,0x8543,0x8544,0x8545,0x8546,0x8547,
+ 0x8548,0x8549,0x854a,0x854b,0x854c,0x854d,0x854e,0x854f,
+ 0x8550,0x8551,0x8552,0x8553,0x8554,0x8555,0x8556,0x8557,
+ 0x8558,0x8559,0x855a,0x855b,0x855c,0x855d,0x855e,0x855f,
+ 0x8560,0x8561,0x8562,0x8563,0x8564,0x8565,0x8566,0x8567,
+ 0x8568,0x8569,0x856a,0x856b,0x856c,0x856d,0x856e,0x856f,
+ 0x8570,0x8571,0x8572,0x8573,0x8574,0x8575,0x8576,0x8577,
+ 0x8578,0x8579,0x857a,0x857b,0x857c,0x857d,0x857e,0x857f,
+ 0x8580,0x8581,0x8582,0x8583,0x8584,0x8585,0x8586,0x8587,
+ 0x8588,0x8589,0x858a,0x858b,0x858c,0x858d,0x858e,0x858f,
+ 0x8590,0x8591,0x8592,0x8593,0x8594,0x8595,0x8596,0x8597,
+ 0x8598,0x8599,0x859a,0x859b,0x859c,0x859d,0x859e,0x859f,
+ 0x85a0,0x85a1,0x85a2,0x85a3,0x85a4,0x85a5,0x85a6,0x85a7,
+ 0x85a8,0x85a9,0x85aa,0x85ab,0x85ac,0x85ad,0x85ae,0x85af,
+ 0x85b0,0x85b1,0x85b2,0x85b3,0x85b4,0x85b5,0x85b6,0x85b7,
+ 0x85b8,0x85b9,0x85ba,0x85bb,0x85bc,0x85bd,0x85be,0x85bf,
+ 0x85c0,0x85c1,0x85c2,0x85c3,0x85c4,0x85c5,0x85c6,0x85c7,
+ 0x85c8,0x85c9,0x85ca,0x85cb,0x85cc,0x85cd,0x85ce,0x85cf,
+ 0x85d0,0x85d1,0x85d2,0x85d3,0x85d4,0x85d5,0x85d6,0x85d7,
+ 0x85d8,0x85d9,0x85da,0x85db,0x85dc,0x85dd,0x85de,0x85df,
+ 0x85e0,0x85e1,0x85e2,0x85e3,0x85e4,0x85e5,0x85e6,0x85e7,
+ 0x85e8,0x85e9,0x85ea,0x85eb,0x85ec,0x85ed,0x85ee,0x85ef,
+ 0x85f0,0x85f1,0x85f2,0x85f3,0x85f4,0x85f5,0x85f6,0x85f7,
+ 0x85f8,0x85f9,0x85fa,0x85fb,0x85fc,0x85fd,0x85fe,0x85ff,
+ 0x8600,0x8601,0x8602,0x8603,0x8604,0x8605,0x8606,0x8607,
+ 0x8608,0x8609,0x860a,0x860b,0x860c,0x860d,0x860e,0x860f,
+ 0x8610,0x8611,0x8612,0x8613,0x8614,0x8615,0x8616,0x8617,
+ 0x8618,0x8619,0x861a,0x861b,0x861c,0x861d,0x861e,0x861f,
+ 0x8620,0x8621,0x8622,0x8623,0x8624,0x8625,0x8626,0x8627,
+ 0x8628,0x8629,0x862a,0x862b,0x862c,0x862d,0x862e,0x862f,
+ 0x8630,0x8631,0x8632,0x8633,0x8634,0x8635,0x8636,0x8637,
+ 0x8638,0x8639,0x863a,0x863b,0x863c,0x863d,0x863e,0x863f,
+ 0x8640,0x8641,0x8642,0x8643,0x8644,0x8645,0x8646,0x8647,
+ 0x8648,0x8649,0x864a,0x864b,0x864c,0x864d,0x864e,0x864f,
+ 0x8650,0x8651,0x8652,0x8653,0x8654,0x8655,0x8656,0x8657,
+ 0x8658,0x8659,0x865a,0x865b,0x865c,0x865d,0x865e,0x865f,
+ 0x8660,0x8661,0x8662,0x8663,0x8664,0x8665,0x8666,0x8667,
+ 0x8668,0x8669,0x866a,0x866b,0x866c,0x866d,0x866e,0x866f,
+ 0x8670,0x8671,0x8672,0x8673,0x8674,0x8675,0x8676,0x8677,
+ 0x8678,0x8679,0x867a,0x867b,0x867c,0x867d,0x867e,0x867f,
+ 0x8680,0x8681,0x8682,0x8683,0x8684,0x8685,0x8686,0x8687,
+ 0x8688,0x8689,0x868a,0x868b,0x868c,0x868d,0x868e,0x868f,
+ 0x8690,0x8691,0x8692,0x8693,0x8694,0x8695,0x8696,0x8697,
+ 0x8698,0x8699,0x869a,0x869b,0x869c,0x869d,0x869e,0x869f,
+ 0x86a0,0x86a1,0x86a2,0x86a3,0x86a4,0x86a5,0x86a6,0x86a7,
+ 0x86a8,0x86a9,0x86aa,0x86ab,0x86ac,0x86ad,0x86ae,0x86af,
+ 0x86b0,0x86b1,0x86b2,0x86b3,0x86b4,0x86b5,0x86b6,0x86b7,
+ 0x86b8,0x86b9,0x86ba,0x86bb,0x86bc,0x86bd,0x86be,0x86bf,
+ 0x86c0,0x86c1,0x86c2,0x86c3,0x86c4,0x86c5,0x86c6,0x86c7,
+ 0x86c8,0x86c9,0x86ca,0x86cb,0x86cc,0x86cd,0x86ce,0x86cf,
+ 0x86d0,0x86d1,0x86d2,0x86d3,0x86d4,0x86d5,0x86d6,0x86d7,
+ 0x86d8,0x86d9,0x86da,0x86db,0x86dc,0x86dd,0x86de,0x86df,
+ 0x86e0,0x86e1,0x86e2,0x86e3,0x86e4,0x86e5,0x86e6,0x86e7,
+ 0x86e8,0x86e9,0x86ea,0x86eb,0x86ec,0x86ed,0x86ee,0x86ef,
+ 0x86f0,0x86f1,0x86f2,0x86f3,0x86f4,0x86f5,0x86f6,0x86f7,
+ 0x86f8,0x86f9,0x86fa,0x86fb,0x86fc,0x86fd,0x86fe,0x86ff,
+ 0x8700,0x8701,0x8702,0x8703,0x8704,0x8705,0x8706,0x8707,
+ 0x8708,0x8709,0x870a,0x870b,0x870c,0x870d,0x870e,0x870f,
+ 0x8710,0x8711,0x8712,0x8713,0x8714,0x8715,0x8716,0x8717,
+ 0x8718,0x8719,0x871a,0x871b,0x871c,0x871d,0x871e,0x871f,
+ 0x8720,0x8721,0x8722,0x8723,0x8724,0x8725,0x8726,0x8727,
+ 0x8728,0x8729,0x872a,0x872b,0x872c,0x872d,0x872e,0x872f,
+ 0x8730,0x8731,0x8732,0x8733,0x8734,0x8735,0x8736,0x8737,
+ 0x8738,0x8739,0x873a,0x873b,0x873c,0x873d,0x873e,0x873f,
+ 0x8740,0x8741,0x8742,0x8743,0x8744,0x8745,0x8746,0x8747,
+ 0x8748,0x8749,0x874a,0x874b,0x874c,0x874d,0x874e,0x874f,
+ 0x8750,0x8751,0x8752,0x8753,0x8754,0x8755,0x8756,0x8757,
+ 0x8758,0x8759,0x875a,0x875b,0x875c,0x875d,0x875e,0x875f,
+ 0x8760,0x8761,0x8762,0x8763,0x8764,0x8765,0x8766,0x8767,
+ 0x8768,0x8769,0x876a,0x876b,0x876c,0x876d,0x876e,0x876f,
+ 0x8770,0x8771,0x8772,0x8773,0x8774,0x8775,0x8776,0x8777,
+ 0x8778,0x8779,0x877a,0x877b,0x877c,0x877d,0x877e,0x877f,
+ 0x8780,0x8781,0x8782,0x8783,0x8784,0x8785,0x8786,0x8787,
+ 0x8788,0x8789,0x878a,0x878b,0x878c,0x878d,0x878e,0x878f,
+ 0x8790,0x8791,0x8792,0x8793,0x8794,0x8795,0x8796,0x8797,
+ 0x8798,0x8799,0x879a,0x879b,0x879c,0x879d,0x879e,0x879f,
+ 0x87a0,0x87a1,0x87a2,0x87a3,0x87a4,0x87a5,0x87a6,0x87a7,
+ 0x87a8,0x87a9,0x87aa,0x87ab,0x87ac,0x87ad,0x87ae,0x87af,
+ 0x87b0,0x87b1,0x87b2,0x87b3,0x87b4,0x87b5,0x87b6,0x87b7,
+ 0x87b8,0x87b9,0x87ba,0x87bb,0x87bc,0x87bd,0x87be,0x87bf,
+ 0x87c0,0x87c1,0x87c2,0x87c3,0x87c4,0x87c5,0x87c6,0x87c7,
+ 0x87c8,0x87c9,0x87ca,0x87cb,0x87cc,0x87cd,0x87ce,0x87cf,
+ 0x87d0,0x87d1,0x87d2,0x87d3,0x87d4,0x87d5,0x87d6,0x87d7,
+ 0x87d8,0x87d9,0x87da,0x87db,0x87dc,0x87dd,0x87de,0x87df,
+ 0x87e0,0x87e1,0x87e2,0x87e3,0x87e4,0x87e5,0x87e6,0x87e7,
+ 0x87e8,0x87e9,0x87ea,0x87eb,0x87ec,0x87ed,0x87ee,0x87ef,
+ 0x87f0,0x87f1,0x87f2,0x87f3,0x87f4,0x87f5,0x87f6,0x87f7,
+ 0x87f8,0x87f9,0x87fa,0x87fb,0x87fc,0x87fd,0x87fe,0x87ff,
+ 0x8800,0x8801,0x8802,0x8803,0x8804,0x8805,0x8806,0x8807,
+ 0x8808,0x8809,0x880a,0x880b,0x880c,0x880d,0x880e,0x880f,
+ 0x8810,0x8811,0x8812,0x8813,0x8814,0x8815,0x8816,0x8817,
+ 0x8818,0x8819,0x881a,0x881b,0x881c,0x881d,0x881e,0x881f,
+ 0x8820,0x8821,0x8822,0x8823,0x8824,0x8825,0x8826,0x8827,
+ 0x8828,0x8829,0x882a,0x882b,0x882c,0x882d,0x882e,0x882f,
+ 0x8830,0x8831,0x8832,0x8833,0x8834,0x8835,0x8836,0x8837,
+ 0x8838,0x8839,0x883a,0x883b,0x883c,0x883d,0x883e,0x883f,
+ 0x8840,0x8841,0x8842,0x8843,0x8844,0x8845,0x8846,0x8847,
+ 0x8848,0x8849,0x884a,0x884b,0x884c,0x884d,0x884e,0x884f,
+ 0x8850,0x8851,0x8852,0x8853,0x8854,0x8855,0x8856,0x8857,
+ 0x8858,0x8859,0x885a,0x885b,0x885c,0x885d,0x885e,0x885f,
+ 0x8860,0x8861,0x8862,0x8863,0x8864,0x8865,0x8866,0x8867,
+ 0x8868,0x8869,0x886a,0x886b,0x886c,0x886d,0x886e,0x886f,
+ 0x8870,0x8871,0x8872,0x8873,0x8874,0x8875,0x8876,0x8877,
+ 0x8878,0x8879,0x887a,0x887b,0x887c,0x887d,0x887e,0x887f,
+ 0x8880,0x8881,0x8882,0x8883,0x8884,0x8885,0x8886,0x8887,
+ 0x8888,0x8889,0x888a,0x888b,0x888c,0x888d,0x888e,0x888f,
+ 0x8890,0x8891,0x8892,0x8893,0x8894,0x8895,0x8896,0x8897,
+ 0x8898,0x8899,0x889a,0x889b,0x889c,0x889d,0x889e,0x889f,
+ 0x88a0,0x88a1,0x88a2,0x88a3,0x88a4,0x88a5,0x88a6,0x88a7,
+ 0x88a8,0x88a9,0x88aa,0x88ab,0x88ac,0x88ad,0x88ae,0x88af,
+ 0x88b0,0x88b1,0x88b2,0x88b3,0x88b4,0x88b5,0x88b6,0x88b7,
+ 0x88b8,0x88b9,0x88ba,0x88bb,0x88bc,0x88bd,0x88be,0x88bf,
+ 0x88c0,0x88c1,0x88c2,0x88c3,0x88c4,0x88c5,0x88c6,0x88c7,
+ 0x88c8,0x88c9,0x88ca,0x88cb,0x88cc,0x88cd,0x88ce,0x88cf,
+ 0x88d0,0x88d1,0x88d2,0x88d3,0x88d4,0x88d5,0x88d6,0x88d7,
+ 0x88d8,0x88d9,0x88da,0x88db,0x88dc,0x88dd,0x88de,0x88df,
+ 0x88e0,0x88e1,0x88e2,0x88e3,0x88e4,0x88e5,0x88e6,0x88e7,
+ 0x88e8,0x88e9,0x88ea,0x88eb,0x88ec,0x88ed,0x88ee,0x88ef,
+ 0x88f0,0x88f1,0x88f2,0x88f3,0x88f4,0x88f5,0x88f6,0x88f7,
+ 0x88f8,0x88f9,0x88fa,0x88fb,0x88fc,0x88fd,0x88fe,0x88ff,
+ 0x8900,0x8901,0x8902,0x8903,0x8904,0x8905,0x8906,0x8907,
+ 0x8908,0x8909,0x890a,0x890b,0x890c,0x890d,0x890e,0x890f,
+ 0x8910,0x8911,0x8912,0x8913,0x8914,0x8915,0x8916,0x8917,
+ 0x8918,0x8919,0x891a,0x891b,0x891c,0x891d,0x891e,0x891f,
+ 0x8920,0x8921,0x8922,0x8923,0x8924,0x8925,0x8926,0x8927,
+ 0x8928,0x8929,0x892a,0x892b,0x892c,0x892d,0x892e,0x892f,
+ 0x8930,0x8931,0x8932,0x8933,0x8934,0x8935,0x8936,0x8937,
+ 0x8938,0x8939,0x893a,0x893b,0x893c,0x893d,0x893e,0x893f,
+ 0x8940,0x8941,0x8942,0x8943,0x8944,0x8945,0x8946,0x8947,
+ 0x8948,0x8949,0x894a,0x894b,0x894c,0x894d,0x894e,0x894f,
+ 0x8950,0x8951,0x8952,0x8953,0x8954,0x8955,0x8956,0x8957,
+ 0x8958,0x8959,0x895a,0x895b,0x895c,0x895d,0x895e,0x895f,
+ 0x8960,0x8961,0x8962,0x8963,0x8964,0x8965,0x8966,0x8967,
+ 0x8968,0x8969,0x896a,0x896b,0x896c,0x896d,0x896e,0x896f,
+ 0x8970,0x8971,0x8972,0x8973,0x8974,0x8975,0x8976,0x8977,
+ 0x8978,0x8979,0x897a,0x897b,0x897c,0x897d,0x897e,0x897f,
+ 0x8980,0x8981,0x8982,0x8983,0x8984,0x8985,0x8986,0x8987,
+ 0x8988,0x8989,0x898a,0x898b,0x898c,0x898d,0x898e,0x898f,
+ 0x8990,0x8991,0x8992,0x8993,0x8994,0x8995,0x8996,0x8997,
+ 0x8998,0x8999,0x899a,0x899b,0x899c,0x899d,0x899e,0x899f,
+ 0x89a0,0x89a1,0x89a2,0x89a3,0x89a4,0x89a5,0x89a6,0x89a7,
+ 0x89a8,0x89a9,0x89aa,0x89ab,0x89ac,0x89ad,0x89ae,0x89af,
+ 0x89b0,0x89b1,0x89b2,0x89b3,0x89b4,0x89b5,0x89b6,0x89b7,
+ 0x89b8,0x89b9,0x89ba,0x89bb,0x89bc,0x89bd,0x89be,0x89bf,
+ 0x89c0,0x89c1,0x89c2,0x89c3,0x89c4,0x89c5,0x89c6,0x89c7,
+ 0x89c8,0x89c9,0x89ca,0x89cb,0x89cc,0x89cd,0x89ce,0x89cf,
+ 0x89d0,0x89d1,0x89d2,0x89d3,0x89d4,0x89d5,0x89d6,0x89d7,
+ 0x89d8,0x89d9,0x89da,0x89db,0x89dc,0x89dd,0x89de,0x89df,
+ 0x89e0,0x89e1,0x89e2,0x89e3,0x89e4,0x89e5,0x89e6,0x89e7,
+ 0x89e8,0x89e9,0x89ea,0x89eb,0x89ec,0x89ed,0x89ee,0x89ef,
+ 0x89f0,0x89f1,0x89f2,0x89f3,0x89f4,0x89f5,0x89f6,0x89f7,
+ 0x89f8,0x89f9,0x89fa,0x89fb,0x89fc,0x89fd,0x89fe,0x89ff,
+ 0x8a00,0x8a01,0x8a02,0x8a03,0x8a04,0x8a05,0x8a06,0x8a07,
+ 0x8a08,0x8a09,0x8a0a,0x8a0b,0x8a0c,0x8a0d,0x8a0e,0x8a0f,
+ 0x8a10,0x8a11,0x8a12,0x8a13,0x8a14,0x8a15,0x8a16,0x8a17,
+ 0x8a18,0x8a19,0x8a1a,0x8a1b,0x8a1c,0x8a1d,0x8a1e,0x8a1f,
+ 0x8a20,0x8a21,0x8a22,0x8a23,0x8a24,0x8a25,0x8a26,0x8a27,
+ 0x8a28,0x8a29,0x8a2a,0x8a2b,0x8a2c,0x8a2d,0x8a2e,0x8a2f,
+ 0x8a30,0x8a31,0x8a32,0x8a33,0x8a34,0x8a35,0x8a36,0x8a37,
+ 0x8a38,0x8a39,0x8a3a,0x8a3b,0x8a3c,0x8a3d,0x8a3e,0x8a3f,
+ 0x8a40,0x8a41,0x8a42,0x8a43,0x8a44,0x8a45,0x8a46,0x8a47,
+ 0x8a48,0x8a49,0x8a4a,0x8a4b,0x8a4c,0x8a4d,0x8a4e,0x8a4f,
+ 0x8a50,0x8a51,0x8a52,0x8a53,0x8a54,0x8a55,0x8a56,0x8a57,
+ 0x8a58,0x8a59,0x8a5a,0x8a5b,0x8a5c,0x8a5d,0x8a5e,0x8a5f,
+ 0x8a60,0x8a61,0x8a62,0x8a63,0x8a64,0x8a65,0x8a66,0x8a67,
+ 0x8a68,0x8a69,0x8a6a,0x8a6b,0x8a6c,0x8a6d,0x8a6e,0x8a6f,
+ 0x8a70,0x8a71,0x8a72,0x8a73,0x8a74,0x8a75,0x8a76,0x8a77,
+ 0x8a78,0x8a79,0x8a7a,0x8a7b,0x8a7c,0x8a7d,0x8a7e,0x8a7f,
+ 0x8a80,0x8a81,0x8a82,0x8a83,0x8a84,0x8a85,0x8a86,0x8a87,
+ 0x8a88,0x8a89,0x8a8a,0x8a8b,0x8a8c,0x8a8d,0x8a8e,0x8a8f,
+ 0x8a90,0x8a91,0x8a92,0x8a93,0x8a94,0x8a95,0x8a96,0x8a97,
+ 0x8a98,0x8a99,0x8a9a,0x8a9b,0x8a9c,0x8a9d,0x8a9e,0x8a9f,
+ 0x8aa0,0x8aa1,0x8aa2,0x8aa3,0x8aa4,0x8aa5,0x8aa6,0x8aa7,
+ 0x8aa8,0x8aa9,0x8aaa,0x8aab,0x8aac,0x8aad,0x8aae,0x8aaf,
+ 0x8ab0,0x8ab1,0x8ab2,0x8ab3,0x8ab4,0x8ab5,0x8ab6,0x8ab7,
+ 0x8ab8,0x8ab9,0x8aba,0x8abb,0x8abc,0x8abd,0x8abe,0x8abf,
+ 0x8ac0,0x8ac1,0x8ac2,0x8ac3,0x8ac4,0x8ac5,0x8ac6,0x8ac7,
+ 0x8ac8,0x8ac9,0x8aca,0x8acb,0x8acc,0x8acd,0x8ace,0x8acf,
+ 0x8ad0,0x8ad1,0x8ad2,0x8ad3,0x8ad4,0x8ad5,0x8ad6,0x8ad7,
+ 0x8ad8,0x8ad9,0x8ada,0x8adb,0x8adc,0x8add,0x8ade,0x8adf,
+ 0x8ae0,0x8ae1,0x8ae2,0x8ae3,0x8ae4,0x8ae5,0x8ae6,0x8ae7,
+ 0x8ae8,0x8ae9,0x8aea,0x8aeb,0x8aec,0x8aed,0x8aee,0x8aef,
+ 0x8af0,0x8af1,0x8af2,0x8af3,0x8af4,0x8af5,0x8af6,0x8af7,
+ 0x8af8,0x8af9,0x8afa,0x8afb,0x8afc,0x8afd,0x8afe,0x8aff,
+ 0x8b00,0x8b01,0x8b02,0x8b03,0x8b04,0x8b05,0x8b06,0x8b07,
+ 0x8b08,0x8b09,0x8b0a,0x8b0b,0x8b0c,0x8b0d,0x8b0e,0x8b0f,
+ 0x8b10,0x8b11,0x8b12,0x8b13,0x8b14,0x8b15,0x8b16,0x8b17,
+ 0x8b18,0x8b19,0x8b1a,0x8b1b,0x8b1c,0x8b1d,0x8b1e,0x8b1f,
+ 0x8b20,0x8b21,0x8b22,0x8b23,0x8b24,0x8b25,0x8b26,0x8b27,
+ 0x8b28,0x8b29,0x8b2a,0x8b2b,0x8b2c,0x8b2d,0x8b2e,0x8b2f,
+ 0x8b30,0x8b31,0x8b32,0x8b33,0x8b34,0x8b35,0x8b36,0x8b37,
+ 0x8b38,0x8b39,0x8b3a,0x8b3b,0x8b3c,0x8b3d,0x8b3e,0x8b3f,
+ 0x8b40,0x8b41,0x8b42,0x8b43,0x8b44,0x8b45,0x8b46,0x8b47,
+ 0x8b48,0x8b49,0x8b4a,0x8b4b,0x8b4c,0x8b4d,0x8b4e,0x8b4f,
+ 0x8b50,0x8b51,0x8b52,0x8b53,0x8b54,0x8b55,0x8b56,0x8b57,
+ 0x8b58,0x8b59,0x8b5a,0x8b5b,0x8b5c,0x8b5d,0x8b5e,0x8b5f,
+ 0x8b60,0x8b61,0x8b62,0x8b63,0x8b64,0x8b65,0x8b66,0x8b67,
+ 0x8b68,0x8b69,0x8b6a,0x8b6b,0x8b6c,0x8b6d,0x8b6e,0x8b6f,
+ 0x8b70,0x8b71,0x8b72,0x8b73,0x8b74,0x8b75,0x8b76,0x8b77,
+ 0x8b78,0x8b79,0x8b7a,0x8b7b,0x8b7c,0x8b7d,0x8b7e,0x8b7f,
+ 0x8b80,0x8b81,0x8b82,0x8b83,0x8b84,0x8b85,0x8b86,0x8b87,
+ 0x8b88,0x8b89,0x8b8a,0x8b8b,0x8b8c,0x8b8d,0x8b8e,0x8b8f,
+ 0x8b90,0x8b91,0x8b92,0x8b93,0x8b94,0x8b95,0x8b96,0x8b97,
+ 0x8b98,0x8b99,0x8b9a,0x8b9b,0x8b9c,0x8b9d,0x8b9e,0x8b9f,
+ 0x8ba0,0x8ba1,0x8ba2,0x8ba3,0x8ba4,0x8ba5,0x8ba6,0x8ba7,
+ 0x8ba8,0x8ba9,0x8baa,0x8bab,0x8bac,0x8bad,0x8bae,0x8baf,
+ 0x8bb0,0x8bb1,0x8bb2,0x8bb3,0x8bb4,0x8bb5,0x8bb6,0x8bb7,
+ 0x8bb8,0x8bb9,0x8bba,0x8bbb,0x8bbc,0x8bbd,0x8bbe,0x8bbf,
+ 0x8bc0,0x8bc1,0x8bc2,0x8bc3,0x8bc4,0x8bc5,0x8bc6,0x8bc7,
+ 0x8bc8,0x8bc9,0x8bca,0x8bcb,0x8bcc,0x8bcd,0x8bce,0x8bcf,
+ 0x8bd0,0x8bd1,0x8bd2,0x8bd3,0x8bd4,0x8bd5,0x8bd6,0x8bd7,
+ 0x8bd8,0x8bd9,0x8bda,0x8bdb,0x8bdc,0x8bdd,0x8bde,0x8bdf,
+ 0x8be0,0x8be1,0x8be2,0x8be3,0x8be4,0x8be5,0x8be6,0x8be7,
+ 0x8be8,0x8be9,0x8bea,0x8beb,0x8bec,0x8bed,0x8bee,0x8bef,
+ 0x8bf0,0x8bf1,0x8bf2,0x8bf3,0x8bf4,0x8bf5,0x8bf6,0x8bf7,
+ 0x8bf8,0x8bf9,0x8bfa,0x8bfb,0x8bfc,0x8bfd,0x8bfe,0x8bff,
+ 0x8c00,0x8c01,0x8c02,0x8c03,0x8c04,0x8c05,0x8c06,0x8c07,
+ 0x8c08,0x8c09,0x8c0a,0x8c0b,0x8c0c,0x8c0d,0x8c0e,0x8c0f,
+ 0x8c10,0x8c11,0x8c12,0x8c13,0x8c14,0x8c15,0x8c16,0x8c17,
+ 0x8c18,0x8c19,0x8c1a,0x8c1b,0x8c1c,0x8c1d,0x8c1e,0x8c1f,
+ 0x8c20,0x8c21,0x8c22,0x8c23,0x8c24,0x8c25,0x8c26,0x8c27,
+ 0x8c28,0x8c29,0x8c2a,0x8c2b,0x8c2c,0x8c2d,0x8c2e,0x8c2f,
+ 0x8c30,0x8c31,0x8c32,0x8c33,0x8c34,0x8c35,0x8c36,0x8c37,
+ 0x8c38,0x8c39,0x8c3a,0x8c3b,0x8c3c,0x8c3d,0x8c3e,0x8c3f,
+ 0x8c40,0x8c41,0x8c42,0x8c43,0x8c44,0x8c45,0x8c46,0x8c47,
+ 0x8c48,0x8c49,0x8c4a,0x8c4b,0x8c4c,0x8c4d,0x8c4e,0x8c4f,
+ 0x8c50,0x8c51,0x8c52,0x8c53,0x8c54,0x8c55,0x8c56,0x8c57,
+ 0x8c58,0x8c59,0x8c5a,0x8c5b,0x8c5c,0x8c5d,0x8c5e,0x8c5f,
+ 0x8c60,0x8c61,0x8c62,0x8c63,0x8c64,0x8c65,0x8c66,0x8c67,
+ 0x8c68,0x8c69,0x8c6a,0x8c6b,0x8c6c,0x8c6d,0x8c6e,0x8c6f,
+ 0x8c70,0x8c71,0x8c72,0x8c73,0x8c74,0x8c75,0x8c76,0x8c77,
+ 0x8c78,0x8c79,0x8c7a,0x8c7b,0x8c7c,0x8c7d,0x8c7e,0x8c7f,
+ 0x8c80,0x8c81,0x8c82,0x8c83,0x8c84,0x8c85,0x8c86,0x8c87,
+ 0x8c88,0x8c89,0x8c8a,0x8c8b,0x8c8c,0x8c8d,0x8c8e,0x8c8f,
+ 0x8c90,0x8c91,0x8c92,0x8c93,0x8c94,0x8c95,0x8c96,0x8c97,
+ 0x8c98,0x8c99,0x8c9a,0x8c9b,0x8c9c,0x8c9d,0x8c9e,0x8c9f,
+ 0x8ca0,0x8ca1,0x8ca2,0x8ca3,0x8ca4,0x8ca5,0x8ca6,0x8ca7,
+ 0x8ca8,0x8ca9,0x8caa,0x8cab,0x8cac,0x8cad,0x8cae,0x8caf,
+ 0x8cb0,0x8cb1,0x8cb2,0x8cb3,0x8cb4,0x8cb5,0x8cb6,0x8cb7,
+ 0x8cb8,0x8cb9,0x8cba,0x8cbb,0x8cbc,0x8cbd,0x8cbe,0x8cbf,
+ 0x8cc0,0x8cc1,0x8cc2,0x8cc3,0x8cc4,0x8cc5,0x8cc6,0x8cc7,
+ 0x8cc8,0x8cc9,0x8cca,0x8ccb,0x8ccc,0x8ccd,0x8cce,0x8ccf,
+ 0x8cd0,0x8cd1,0x8cd2,0x8cd3,0x8cd4,0x8cd5,0x8cd6,0x8cd7,
+ 0x8cd8,0x8cd9,0x8cda,0x8cdb,0x8cdc,0x8cdd,0x8cde,0x8cdf,
+ 0x8ce0,0x8ce1,0x8ce2,0x8ce3,0x8ce4,0x8ce5,0x8ce6,0x8ce7,
+ 0x8ce8,0x8ce9,0x8cea,0x8ceb,0x8cec,0x8ced,0x8cee,0x8cef,
+ 0x8cf0,0x8cf1,0x8cf2,0x8cf3,0x8cf4,0x8cf5,0x8cf6,0x8cf7,
+ 0x8cf8,0x8cf9,0x8cfa,0x8cfb,0x8cfc,0x8cfd,0x8cfe,0x8cff,
+ 0x8d00,0x8d01,0x8d02,0x8d03,0x8d04,0x8d05,0x8d06,0x8d07,
+ 0x8d08,0x8d09,0x8d0a,0x8d0b,0x8d0c,0x8d0d,0x8d0e,0x8d0f,
+ 0x8d10,0x8d11,0x8d12,0x8d13,0x8d14,0x8d15,0x8d16,0x8d17,
+ 0x8d18,0x8d19,0x8d1a,0x8d1b,0x8d1c,0x8d1d,0x8d1e,0x8d1f,
+ 0x8d20,0x8d21,0x8d22,0x8d23,0x8d24,0x8d25,0x8d26,0x8d27,
+ 0x8d28,0x8d29,0x8d2a,0x8d2b,0x8d2c,0x8d2d,0x8d2e,0x8d2f,
+ 0x8d30,0x8d31,0x8d32,0x8d33,0x8d34,0x8d35,0x8d36,0x8d37,
+ 0x8d38,0x8d39,0x8d3a,0x8d3b,0x8d3c,0x8d3d,0x8d3e,0x8d3f,
+ 0x8d40,0x8d41,0x8d42,0x8d43,0x8d44,0x8d45,0x8d46,0x8d47,
+ 0x8d48,0x8d49,0x8d4a,0x8d4b,0x8d4c,0x8d4d,0x8d4e,0x8d4f,
+ 0x8d50,0x8d51,0x8d52,0x8d53,0x8d54,0x8d55,0x8d56,0x8d57,
+ 0x8d58,0x8d59,0x8d5a,0x8d5b,0x8d5c,0x8d5d,0x8d5e,0x8d5f,
+ 0x8d60,0x8d61,0x8d62,0x8d63,0x8d64,0x8d65,0x8d66,0x8d67,
+ 0x8d68,0x8d69,0x8d6a,0x8d6b,0x8d6c,0x8d6d,0x8d6e,0x8d6f,
+ 0x8d70,0x8d71,0x8d72,0x8d73,0x8d74,0x8d75,0x8d76,0x8d77,
+ 0x8d78,0x8d79,0x8d7a,0x8d7b,0x8d7c,0x8d7d,0x8d7e,0x8d7f,
+ 0x8d80,0x8d81,0x8d82,0x8d83,0x8d84,0x8d85,0x8d86,0x8d87,
+ 0x8d88,0x8d89,0x8d8a,0x8d8b,0x8d8c,0x8d8d,0x8d8e,0x8d8f,
+ 0x8d90,0x8d91,0x8d92,0x8d93,0x8d94,0x8d95,0x8d96,0x8d97,
+ 0x8d98,0x8d99,0x8d9a,0x8d9b,0x8d9c,0x8d9d,0x8d9e,0x8d9f,
+ 0x8da0,0x8da1,0x8da2,0x8da3,0x8da4,0x8da5,0x8da6,0x8da7,
+ 0x8da8,0x8da9,0x8daa,0x8dab,0x8dac,0x8dad,0x8dae,0x8daf,
+ 0x8db0,0x8db1,0x8db2,0x8db3,0x8db4,0x8db5,0x8db6,0x8db7,
+ 0x8db8,0x8db9,0x8dba,0x8dbb,0x8dbc,0x8dbd,0x8dbe,0x8dbf,
+ 0x8dc0,0x8dc1,0x8dc2,0x8dc3,0x8dc4,0x8dc5,0x8dc6,0x8dc7,
+ 0x8dc8,0x8dc9,0x8dca,0x8dcb,0x8dcc,0x8dcd,0x8dce,0x8dcf,
+ 0x8dd0,0x8dd1,0x8dd2,0x8dd3,0x8dd4,0x8dd5,0x8dd6,0x8dd7,
+ 0x8dd8,0x8dd9,0x8dda,0x8ddb,0x8ddc,0x8ddd,0x8dde,0x8ddf,
+ 0x8de0,0x8de1,0x8de2,0x8de3,0x8de4,0x8de5,0x8de6,0x8de7,
+ 0x8de8,0x8de9,0x8dea,0x8deb,0x8dec,0x8ded,0x8dee,0x8def,
+ 0x8df0,0x8df1,0x8df2,0x8df3,0x8df4,0x8df5,0x8df6,0x8df7,
+ 0x8df8,0x8df9,0x8dfa,0x8dfb,0x8dfc,0x8dfd,0x8dfe,0x8dff,
+ 0x8e00,0x8e01,0x8e02,0x8e03,0x8e04,0x8e05,0x8e06,0x8e07,
+ 0x8e08,0x8e09,0x8e0a,0x8e0b,0x8e0c,0x8e0d,0x8e0e,0x8e0f,
+ 0x8e10,0x8e11,0x8e12,0x8e13,0x8e14,0x8e15,0x8e16,0x8e17,
+ 0x8e18,0x8e19,0x8e1a,0x8e1b,0x8e1c,0x8e1d,0x8e1e,0x8e1f,
+ 0x8e20,0x8e21,0x8e22,0x8e23,0x8e24,0x8e25,0x8e26,0x8e27,
+ 0x8e28,0x8e29,0x8e2a,0x8e2b,0x8e2c,0x8e2d,0x8e2e,0x8e2f,
+ 0x8e30,0x8e31,0x8e32,0x8e33,0x8e34,0x8e35,0x8e36,0x8e37,
+ 0x8e38,0x8e39,0x8e3a,0x8e3b,0x8e3c,0x8e3d,0x8e3e,0x8e3f,
+ 0x8e40,0x8e41,0x8e42,0x8e43,0x8e44,0x8e45,0x8e46,0x8e47,
+ 0x8e48,0x8e49,0x8e4a,0x8e4b,0x8e4c,0x8e4d,0x8e4e,0x8e4f,
+ 0x8e50,0x8e51,0x8e52,0x8e53,0x8e54,0x8e55,0x8e56,0x8e57,
+ 0x8e58,0x8e59,0x8e5a,0x8e5b,0x8e5c,0x8e5d,0x8e5e,0x8e5f,
+ 0x8e60,0x8e61,0x8e62,0x8e63,0x8e64,0x8e65,0x8e66,0x8e67,
+ 0x8e68,0x8e69,0x8e6a,0x8e6b,0x8e6c,0x8e6d,0x8e6e,0x8e6f,
+ 0x8e70,0x8e71,0x8e72,0x8e73,0x8e74,0x8e75,0x8e76,0x8e77,
+ 0x8e78,0x8e79,0x8e7a,0x8e7b,0x8e7c,0x8e7d,0x8e7e,0x8e7f,
+ 0x8e80,0x8e81,0x8e82,0x8e83,0x8e84,0x8e85,0x8e86,0x8e87,
+ 0x8e88,0x8e89,0x8e8a,0x8e8b,0x8e8c,0x8e8d,0x8e8e,0x8e8f,
+ 0x8e90,0x8e91,0x8e92,0x8e93,0x8e94,0x8e95,0x8e96,0x8e97,
+ 0x8e98,0x8e99,0x8e9a,0x8e9b,0x8e9c,0x8e9d,0x8e9e,0x8e9f,
+ 0x8ea0,0x8ea1,0x8ea2,0x8ea3,0x8ea4,0x8ea5,0x8ea6,0x8ea7,
+ 0x8ea8,0x8ea9,0x8eaa,0x8eab,0x8eac,0x8ead,0x8eae,0x8eaf,
+ 0x8eb0,0x8eb1,0x8eb2,0x8eb3,0x8eb4,0x8eb5,0x8eb6,0x8eb7,
+ 0x8eb8,0x8eb9,0x8eba,0x8ebb,0x8ebc,0x8ebd,0x8ebe,0x8ebf,
+ 0x8ec0,0x8ec1,0x8ec2,0x8ec3,0x8ec4,0x8ec5,0x8ec6,0x8ec7,
+ 0x8ec8,0x8ec9,0x8eca,0x8ecb,0x8ecc,0x8ecd,0x8ece,0x8ecf,
+ 0x8ed0,0x8ed1,0x8ed2,0x8ed3,0x8ed4,0x8ed5,0x8ed6,0x8ed7,
+ 0x8ed8,0x8ed9,0x8eda,0x8edb,0x8edc,0x8edd,0x8ede,0x8edf,
+ 0x8ee0,0x8ee1,0x8ee2,0x8ee3,0x8ee4,0x8ee5,0x8ee6,0x8ee7,
+ 0x8ee8,0x8ee9,0x8eea,0x8eeb,0x8eec,0x8eed,0x8eee,0x8eef,
+ 0x8ef0,0x8ef1,0x8ef2,0x8ef3,0x8ef4,0x8ef5,0x8ef6,0x8ef7,
+ 0x8ef8,0x8ef9,0x8efa,0x8efb,0x8efc,0x8efd,0x8efe,0x8eff,
+ 0x8f00,0x8f01,0x8f02,0x8f03,0x8f04,0x8f05,0x8f06,0x8f07,
+ 0x8f08,0x8f09,0x8f0a,0x8f0b,0x8f0c,0x8f0d,0x8f0e,0x8f0f,
+ 0x8f10,0x8f11,0x8f12,0x8f13,0x8f14,0x8f15,0x8f16,0x8f17,
+ 0x8f18,0x8f19,0x8f1a,0x8f1b,0x8f1c,0x8f1d,0x8f1e,0x8f1f,
+ 0x8f20,0x8f21,0x8f22,0x8f23,0x8f24,0x8f25,0x8f26,0x8f27,
+ 0x8f28,0x8f29,0x8f2a,0x8f2b,0x8f2c,0x8f2d,0x8f2e,0x8f2f,
+ 0x8f30,0x8f31,0x8f32,0x8f33,0x8f34,0x8f35,0x8f36,0x8f37,
+ 0x8f38,0x8f39,0x8f3a,0x8f3b,0x8f3c,0x8f3d,0x8f3e,0x8f3f,
+ 0x8f40,0x8f41,0x8f42,0x8f43,0x8f44,0x8f45,0x8f46,0x8f47,
+ 0x8f48,0x8f49,0x8f4a,0x8f4b,0x8f4c,0x8f4d,0x8f4e,0x8f4f,
+ 0x8f50,0x8f51,0x8f52,0x8f53,0x8f54,0x8f55,0x8f56,0x8f57,
+ 0x8f58,0x8f59,0x8f5a,0x8f5b,0x8f5c,0x8f5d,0x8f5e,0x8f5f,
+ 0x8f60,0x8f61,0x8f62,0x8f63,0x8f64,0x8f65,0x8f66,0x8f67,
+ 0x8f68,0x8f69,0x8f6a,0x8f6b,0x8f6c,0x8f6d,0x8f6e,0x8f6f,
+ 0x8f70,0x8f71,0x8f72,0x8f73,0x8f74,0x8f75,0x8f76,0x8f77,
+ 0x8f78,0x8f79,0x8f7a,0x8f7b,0x8f7c,0x8f7d,0x8f7e,0x8f7f,
+ 0x8f80,0x8f81,0x8f82,0x8f83,0x8f84,0x8f85,0x8f86,0x8f87,
+ 0x8f88,0x8f89,0x8f8a,0x8f8b,0x8f8c,0x8f8d,0x8f8e,0x8f8f,
+ 0x8f90,0x8f91,0x8f92,0x8f93,0x8f94,0x8f95,0x8f96,0x8f97,
+ 0x8f98,0x8f99,0x8f9a,0x8f9b,0x8f9c,0x8f9d,0x8f9e,0x8f9f,
+ 0x8fa0,0x8fa1,0x8fa2,0x8fa3,0x8fa4,0x8fa5,0x8fa6,0x8fa7,
+ 0x8fa8,0x8fa9,0x8faa,0x8fab,0x8fac,0x8fad,0x8fae,0x8faf,
+ 0x8fb0,0x8fb1,0x8fb2,0x8fb3,0x8fb4,0x8fb5,0x8fb6,0x8fb7,
+ 0x8fb8,0x8fb9,0x8fba,0x8fbb,0x8fbc,0x8fbd,0x8fbe,0x8fbf,
+ 0x8fc0,0x8fc1,0x8fc2,0x8fc3,0x8fc4,0x8fc5,0x8fc6,0x8fc7,
+ 0x8fc8,0x8fc9,0x8fca,0x8fcb,0x8fcc,0x8fcd,0x8fce,0x8fcf,
+ 0x8fd0,0x8fd1,0x8fd2,0x8fd3,0x8fd4,0x8fd5,0x8fd6,0x8fd7,
+ 0x8fd8,0x8fd9,0x8fda,0x8fdb,0x8fdc,0x8fdd,0x8fde,0x8fdf,
+ 0x8fe0,0x8fe1,0x8fe2,0x8fe3,0x8fe4,0x8fe5,0x8fe6,0x8fe7,
+ 0x8fe8,0x8fe9,0x8fea,0x8feb,0x8fec,0x8fed,0x8fee,0x8fef,
+ 0x8ff0,0x8ff1,0x8ff2,0x8ff3,0x8ff4,0x8ff5,0x8ff6,0x8ff7,
+ 0x8ff8,0x8ff9,0x8ffa,0x8ffb,0x8ffc,0x8ffd,0x8ffe,0x8fff,
+ 0x9000,0x9001,0x9002,0x9003,0x9004,0x9005,0x9006,0x9007,
+ 0x9008,0x9009,0x900a,0x900b,0x900c,0x900d,0x900e,0x900f,
+ 0x9010,0x9011,0x9012,0x9013,0x9014,0x9015,0x9016,0x9017,
+ 0x9018,0x9019,0x901a,0x901b,0x901c,0x901d,0x901e,0x901f,
+ 0x9020,0x9021,0x9022,0x9023,0x9024,0x9025,0x9026,0x9027,
+ 0x9028,0x9029,0x902a,0x902b,0x902c,0x902d,0x902e,0x902f,
+ 0x9030,0x9031,0x9032,0x9033,0x9034,0x9035,0x9036,0x9037,
+ 0x9038,0x9039,0x903a,0x903b,0x903c,0x903d,0x903e,0x903f,
+ 0x9040,0x9041,0x9042,0x9043,0x9044,0x9045,0x9046,0x9047,
+ 0x9048,0x9049,0x904a,0x904b,0x904c,0x904d,0x904e,0x904f,
+ 0x9050,0x9051,0x9052,0x9053,0x9054,0x9055,0x9056,0x9057,
+ 0x9058,0x9059,0x905a,0x905b,0x905c,0x905d,0x905e,0x905f,
+ 0x9060,0x9061,0x9062,0x9063,0x9064,0x9065,0x9066,0x9067,
+ 0x9068,0x9069,0x906a,0x906b,0x906c,0x906d,0x906e,0x906f,
+ 0x9070,0x9071,0x9072,0x9073,0x9074,0x9075,0x9076,0x9077,
+ 0x9078,0x9079,0x907a,0x907b,0x907c,0x907d,0x907e,0x907f,
+ 0x9080,0x9081,0x9082,0x9083,0x9084,0x9085,0x9086,0x9087,
+ 0x9088,0x9089,0x908a,0x908b,0x908c,0x908d,0x908e,0x908f,
+ 0x9090,0x9091,0x9092,0x9093,0x9094,0x9095,0x9096,0x9097,
+ 0x9098,0x9099,0x909a,0x909b,0x909c,0x909d,0x909e,0x909f,
+ 0x90a0,0x90a1,0x90a2,0x90a3,0x90a4,0x90a5,0x90a6,0x90a7,
+ 0x90a8,0x90a9,0x90aa,0x90ab,0x90ac,0x90ad,0x90ae,0x90af,
+ 0x90b0,0x90b1,0x90b2,0x90b3,0x90b4,0x90b5,0x90b6,0x90b7,
+ 0x90b8,0x90b9,0x90ba,0x90bb,0x90bc,0x90bd,0x90be,0x90bf,
+ 0x90c0,0x90c1,0x90c2,0x90c3,0x90c4,0x90c5,0x90c6,0x90c7,
+ 0x90c8,0x90c9,0x90ca,0x90cb,0x90cc,0x90cd,0x90ce,0x90cf,
+ 0x90d0,0x90d1,0x90d2,0x90d3,0x90d4,0x90d5,0x90d6,0x90d7,
+ 0x90d8,0x90d9,0x90da,0x90db,0x90dc,0x90dd,0x90de,0x90df,
+ 0x90e0,0x90e1,0x90e2,0x90e3,0x90e4,0x90e5,0x90e6,0x90e7,
+ 0x90e8,0x90e9,0x90ea,0x90eb,0x90ec,0x90ed,0x90ee,0x90ef,
+ 0x90f0,0x90f1,0x90f2,0x90f3,0x90f4,0x90f5,0x90f6,0x90f7,
+ 0x90f8,0x90f9,0x90fa,0x90fb,0x90fc,0x90fd,0x90fe,0x90ff,
+ 0x9100,0x9101,0x9102,0x9103,0x9104,0x9105,0x9106,0x9107,
+ 0x9108,0x9109,0x910a,0x910b,0x910c,0x910d,0x910e,0x910f,
+ 0x9110,0x9111,0x9112,0x9113,0x9114,0x9115,0x9116,0x9117,
+ 0x9118,0x9119,0x911a,0x911b,0x911c,0x911d,0x911e,0x911f,
+ 0x9120,0x9121,0x9122,0x9123,0x9124,0x9125,0x9126,0x9127,
+ 0x9128,0x9129,0x912a,0x912b,0x912c,0x912d,0x912e,0x912f,
+ 0x9130,0x9131,0x9132,0x9133,0x9134,0x9135,0x9136,0x9137,
+ 0x9138,0x9139,0x913a,0x913b,0x913c,0x913d,0x913e,0x913f,
+ 0x9140,0x9141,0x9142,0x9143,0x9144,0x9145,0x9146,0x9147,
+ 0x9148,0x9149,0x914a,0x914b,0x914c,0x914d,0x914e,0x914f,
+ 0x9150,0x9151,0x9152,0x9153,0x9154,0x9155,0x9156,0x9157,
+ 0x9158,0x9159,0x915a,0x915b,0x915c,0x915d,0x915e,0x915f,
+ 0x9160,0x9161,0x9162,0x9163,0x9164,0x9165,0x9166,0x9167,
+ 0x9168,0x9169,0x916a,0x916b,0x916c,0x916d,0x916e,0x916f,
+ 0x9170,0x9171,0x9172,0x9173,0x9174,0x9175,0x9176,0x9177,
+ 0x9178,0x9179,0x917a,0x917b,0x917c,0x917d,0x917e,0x917f,
+ 0x9180,0x9181,0x9182,0x9183,0x9184,0x9185,0x9186,0x9187,
+ 0x9188,0x9189,0x918a,0x918b,0x918c,0x918d,0x918e,0x918f,
+ 0x9190,0x9191,0x9192,0x9193,0x9194,0x9195,0x9196,0x9197,
+ 0x9198,0x9199,0x919a,0x919b,0x919c,0x919d,0x919e,0x919f,
+ 0x91a0,0x91a1,0x91a2,0x91a3,0x91a4,0x91a5,0x91a6,0x91a7,
+ 0x91a8,0x91a9,0x91aa,0x91ab,0x91ac,0x91ad,0x91ae,0x91af,
+ 0x91b0,0x91b1,0x91b2,0x91b3,0x91b4,0x91b5,0x91b6,0x91b7,
+ 0x91b8,0x91b9,0x91ba,0x91bb,0x91bc,0x91bd,0x91be,0x91bf,
+ 0x91c0,0x91c1,0x91c2,0x91c3,0x91c4,0x91c5,0x91c6,0x91c7,
+ 0x91c8,0x91c9,0x91ca,0x91cb,0x91cc,0x91cd,0x91ce,0x91cf,
+ 0x91d0,0x91d1,0x91d2,0x91d3,0x91d4,0x91d5,0x91d6,0x91d7,
+ 0x91d8,0x91d9,0x91da,0x91db,0x91dc,0x91dd,0x91de,0x91df,
+ 0x91e0,0x91e1,0x91e2,0x91e3,0x91e4,0x91e5,0x91e6,0x91e7,
+ 0x91e8,0x91e9,0x91ea,0x91eb,0x91ec,0x91ed,0x91ee,0x91ef,
+ 0x91f0,0x91f1,0x91f2,0x91f3,0x91f4,0x91f5,0x91f6,0x91f7,
+ 0x91f8,0x91f9,0x91fa,0x91fb,0x91fc,0x91fd,0x91fe,0x91ff,
+ 0x9200,0x9201,0x9202,0x9203,0x9204,0x9205,0x9206,0x9207,
+ 0x9208,0x9209,0x920a,0x920b,0x920c,0x920d,0x920e,0x920f,
+ 0x9210,0x9211,0x9212,0x9213,0x9214,0x9215,0x9216,0x9217,
+ 0x9218,0x9219,0x921a,0x921b,0x921c,0x921d,0x921e,0x921f,
+ 0x9220,0x9221,0x9222,0x9223,0x9224,0x9225,0x9226,0x9227,
+ 0x9228,0x9229,0x922a,0x922b,0x922c,0x922d,0x922e,0x922f,
+ 0x9230,0x9231,0x9232,0x9233,0x9234,0x9235,0x9236,0x9237,
+ 0x9238,0x9239,0x923a,0x923b,0x923c,0x923d,0x923e,0x923f,
+ 0x9240,0x9241,0x9242,0x9243,0x9244,0x9245,0x9246,0x9247,
+ 0x9248,0x9249,0x924a,0x924b,0x924c,0x924d,0x924e,0x924f,
+ 0x9250,0x9251,0x9252,0x9253,0x9254,0x9255,0x9256,0x9257,
+ 0x9258,0x9259,0x925a,0x925b,0x925c,0x925d,0x925e,0x925f,
+ 0x9260,0x9261,0x9262,0x9263,0x9264,0x9265,0x9266,0x9267,
+ 0x9268,0x9269,0x926a,0x926b,0x926c,0x926d,0x926e,0x926f,
+ 0x9270,0x9271,0x9272,0x9273,0x9274,0x9275,0x9276,0x9277,
+ 0x9278,0x9279,0x927a,0x927b,0x927c,0x927d,0x927e,0x927f,
+ 0x9280,0x9281,0x9282,0x9283,0x9284,0x9285,0x9286,0x9287,
+ 0x9288,0x9289,0x928a,0x928b,0x928c,0x928d,0x928e,0x928f,
+ 0x9290,0x9291,0x9292,0x9293,0x9294,0x9295,0x9296,0x9297,
+ 0x9298,0x9299,0x929a,0x929b,0x929c,0x929d,0x929e,0x929f,
+ 0x92a0,0x92a1,0x92a2,0x92a3,0x92a4,0x92a5,0x92a6,0x92a7,
+ 0x92a8,0x92a9,0x92aa,0x92ab,0x92ac,0x92ad,0x92ae,0x92af,
+ 0x92b0,0x92b1,0x92b2,0x92b3,0x92b4,0x92b5,0x92b6,0x92b7,
+ 0x92b8,0x92b9,0x92ba,0x92bb,0x92bc,0x92bd,0x92be,0x92bf,
+ 0x92c0,0x92c1,0x92c2,0x92c3,0x92c4,0x92c5,0x92c6,0x92c7,
+ 0x92c8,0x92c9,0x92ca,0x92cb,0x92cc,0x92cd,0x92ce,0x92cf,
+ 0x92d0,0x92d1,0x92d2,0x92d3,0x92d4,0x92d5,0x92d6,0x92d7,
+ 0x92d8,0x92d9,0x92da,0x92db,0x92dc,0x92dd,0x92de,0x92df,
+ 0x92e0,0x92e1,0x92e2,0x92e3,0x92e4,0x92e5,0x92e6,0x92e7,
+ 0x92e8,0x92e9,0x92ea,0x92eb,0x92ec,0x92ed,0x92ee,0x92ef,
+ 0x92f0,0x92f1,0x92f2,0x92f3,0x92f4,0x92f5,0x92f6,0x92f7,
+ 0x92f8,0x92f9,0x92fa,0x92fb,0x92fc,0x92fd,0x92fe,0x92ff,
+ 0x9300,0x9301,0x9302,0x9303,0x9304,0x9305,0x9306,0x9307,
+ 0x9308,0x9309,0x930a,0x930b,0x930c,0x930d,0x930e,0x930f,
+ 0x9310,0x9311,0x9312,0x9313,0x9314,0x9315,0x9316,0x9317,
+ 0x9318,0x9319,0x931a,0x931b,0x931c,0x931d,0x931e,0x931f,
+ 0x9320,0x9321,0x9322,0x9323,0x9324,0x9325,0x9326,0x9327,
+ 0x9328,0x9329,0x932a,0x932b,0x932c,0x932d,0x932e,0x932f,
+ 0x9330,0x9331,0x9332,0x9333,0x9334,0x9335,0x9336,0x9337,
+ 0x9338,0x9339,0x933a,0x933b,0x933c,0x933d,0x933e,0x933f,
+ 0x9340,0x9341,0x9342,0x9343,0x9344,0x9345,0x9346,0x9347,
+ 0x9348,0x9349,0x934a,0x934b,0x934c,0x934d,0x934e,0x934f,
+ 0x9350,0x9351,0x9352,0x9353,0x9354,0x9355,0x9356,0x9357,
+ 0x9358,0x9359,0x935a,0x935b,0x935c,0x935d,0x935e,0x935f,
+ 0x9360,0x9361,0x9362,0x9363,0x9364,0x9365,0x9366,0x9367,
+ 0x9368,0x9369,0x936a,0x936b,0x936c,0x936d,0x936e,0x936f,
+ 0x9370,0x9371,0x9372,0x9373,0x9374,0x9375,0x9376,0x9377,
+ 0x9378,0x9379,0x937a,0x937b,0x937c,0x937d,0x937e,0x937f,
+ 0x9380,0x9381,0x9382,0x9383,0x9384,0x9385,0x9386,0x9387,
+ 0x9388,0x9389,0x938a,0x938b,0x938c,0x938d,0x938e,0x938f,
+ 0x9390,0x9391,0x9392,0x9393,0x9394,0x9395,0x9396,0x9397,
+ 0x9398,0x9399,0x939a,0x939b,0x939c,0x939d,0x939e,0x939f,
+ 0x93a0,0x93a1,0x93a2,0x93a3,0x93a4,0x93a5,0x93a6,0x93a7,
+ 0x93a8,0x93a9,0x93aa,0x93ab,0x93ac,0x93ad,0x93ae,0x93af,
+ 0x93b0,0x93b1,0x93b2,0x93b3,0x93b4,0x93b5,0x93b6,0x93b7,
+ 0x93b8,0x93b9,0x93ba,0x93bb,0x93bc,0x93bd,0x93be,0x93bf,
+ 0x93c0,0x93c1,0x93c2,0x93c3,0x93c4,0x93c5,0x93c6,0x93c7,
+ 0x93c8,0x93c9,0x93ca,0x93cb,0x93cc,0x93cd,0x93ce,0x93cf,
+ 0x93d0,0x93d1,0x93d2,0x93d3,0x93d4,0x93d5,0x93d6,0x93d7,
+ 0x93d8,0x93d9,0x93da,0x93db,0x93dc,0x93dd,0x93de,0x93df,
+ 0x93e0,0x93e1,0x93e2,0x93e3,0x93e4,0x93e5,0x93e6,0x93e7,
+ 0x93e8,0x93e9,0x93ea,0x93eb,0x93ec,0x93ed,0x93ee,0x93ef,
+ 0x93f0,0x93f1,0x93f2,0x93f3,0x93f4,0x93f5,0x93f6,0x93f7,
+ 0x93f8,0x93f9,0x93fa,0x93fb,0x93fc,0x93fd,0x93fe,0x93ff,
+ 0x9400,0x9401,0x9402,0x9403,0x9404,0x9405,0x9406,0x9407,
+ 0x9408,0x9409,0x940a,0x940b,0x940c,0x940d,0x940e,0x940f,
+ 0x9410,0x9411,0x9412,0x9413,0x9414,0x9415,0x9416,0x9417,
+ 0x9418,0x9419,0x941a,0x941b,0x941c,0x941d,0x941e,0x941f,
+ 0x9420,0x9421,0x9422,0x9423,0x9424,0x9425,0x9426,0x9427,
+ 0x9428,0x9429,0x942a,0x942b,0x942c,0x942d,0x942e,0x942f,
+ 0x9430,0x9431,0x9432,0x9433,0x9434,0x9435,0x9436,0x9437,
+ 0x9438,0x9439,0x943a,0x943b,0x943c,0x943d,0x943e,0x943f,
+ 0x9440,0x9441,0x9442,0x9443,0x9444,0x9445,0x9446,0x9447,
+ 0x9448,0x9449,0x944a,0x944b,0x944c,0x944d,0x944e,0x944f,
+ 0x9450,0x9451,0x9452,0x9453,0x9454,0x9455,0x9456,0x9457,
+ 0x9458,0x9459,0x945a,0x945b,0x945c,0x945d,0x945e,0x945f,
+ 0x9460,0x9461,0x9462,0x9463,0x9464,0x9465,0x9466,0x9467,
+ 0x9468,0x9469,0x946a,0x946b,0x946c,0x946d,0x946e,0x946f,
+ 0x9470,0x9471,0x9472,0x9473,0x9474,0x9475,0x9476,0x9477,
+ 0x9478,0x9479,0x947a,0x947b,0x947c,0x947d,0x947e,0x947f,
+ 0x9480,0x9481,0x9482,0x9483,0x9484,0x9485,0x9486,0x9487,
+ 0x9488,0x9489,0x948a,0x948b,0x948c,0x948d,0x948e,0x948f,
+ 0x9490,0x9491,0x9492,0x9493,0x9494,0x9495,0x9496,0x9497,
+ 0x9498,0x9499,0x949a,0x949b,0x949c,0x949d,0x949e,0x949f,
+ 0x94a0,0x94a1,0x94a2,0x94a3,0x94a4,0x94a5,0x94a6,0x94a7,
+ 0x94a8,0x94a9,0x94aa,0x94ab,0x94ac,0x94ad,0x94ae,0x94af,
+ 0x94b0,0x94b1,0x94b2,0x94b3,0x94b4,0x94b5,0x94b6,0x94b7,
+ 0x94b8,0x94b9,0x94ba,0x94bb,0x94bc,0x94bd,0x94be,0x94bf,
+ 0x94c0,0x94c1,0x94c2,0x94c3,0x94c4,0x94c5,0x94c6,0x94c7,
+ 0x94c8,0x94c9,0x94ca,0x94cb,0x94cc,0x94cd,0x94ce,0x94cf,
+ 0x94d0,0x94d1,0x94d2,0x94d3,0x94d4,0x94d5,0x94d6,0x94d7,
+ 0x94d8,0x94d9,0x94da,0x94db,0x94dc,0x94dd,0x94de,0x94df,
+ 0x94e0,0x94e1,0x94e2,0x94e3,0x94e4,0x94e5,0x94e6,0x94e7,
+ 0x94e8,0x94e9,0x94ea,0x94eb,0x94ec,0x94ed,0x94ee,0x94ef,
+ 0x94f0,0x94f1,0x94f2,0x94f3,0x94f4,0x94f5,0x94f6,0x94f7,
+ 0x94f8,0x94f9,0x94fa,0x94fb,0x94fc,0x94fd,0x94fe,0x94ff,
+ 0x9500,0x9501,0x9502,0x9503,0x9504,0x9505,0x9506,0x9507,
+ 0x9508,0x9509,0x950a,0x950b,0x950c,0x950d,0x950e,0x950f,
+ 0x9510,0x9511,0x9512,0x9513,0x9514,0x9515,0x9516,0x9517,
+ 0x9518,0x9519,0x951a,0x951b,0x951c,0x951d,0x951e,0x951f,
+ 0x9520,0x9521,0x9522,0x9523,0x9524,0x9525,0x9526,0x9527,
+ 0x9528,0x9529,0x952a,0x952b,0x952c,0x952d,0x952e,0x952f,
+ 0x9530,0x9531,0x9532,0x9533,0x9534,0x9535,0x9536,0x9537,
+ 0x9538,0x9539,0x953a,0x953b,0x953c,0x953d,0x953e,0x953f,
+ 0x9540,0x9541,0x9542,0x9543,0x9544,0x9545,0x9546,0x9547,
+ 0x9548,0x9549,0x954a,0x954b,0x954c,0x954d,0x954e,0x954f,
+ 0x9550,0x9551,0x9552,0x9553,0x9554,0x9555,0x9556,0x9557,
+ 0x9558,0x9559,0x955a,0x955b,0x955c,0x955d,0x955e,0x955f,
+ 0x9560,0x9561,0x9562,0x9563,0x9564,0x9565,0x9566,0x9567,
+ 0x9568,0x9569,0x956a,0x956b,0x956c,0x956d,0x956e,0x956f,
+ 0x9570,0x9571,0x9572,0x9573,0x9574,0x9575,0x9576,0x9577,
+ 0x9578,0x9579,0x957a,0x957b,0x957c,0x957d,0x957e,0x957f,
+ 0x9580,0x9581,0x9582,0x9583,0x9584,0x9585,0x9586,0x9587,
+ 0x9588,0x9589,0x958a,0x958b,0x958c,0x958d,0x958e,0x958f,
+ 0x9590,0x9591,0x9592,0x9593,0x9594,0x9595,0x9596,0x9597,
+ 0x9598,0x9599,0x959a,0x959b,0x959c,0x959d,0x959e,0x959f,
+ 0x95a0,0x95a1,0x95a2,0x95a3,0x95a4,0x95a5,0x95a6,0x95a7,
+ 0x95a8,0x95a9,0x95aa,0x95ab,0x95ac,0x95ad,0x95ae,0x95af,
+ 0x95b0,0x95b1,0x95b2,0x95b3,0x95b4,0x95b5,0x95b6,0x95b7,
+ 0x95b8,0x95b9,0x95ba,0x95bb,0x95bc,0x95bd,0x95be,0x95bf,
+ 0x95c0,0x95c1,0x95c2,0x95c3,0x95c4,0x95c5,0x95c6,0x95c7,
+ 0x95c8,0x95c9,0x95ca,0x95cb,0x95cc,0x95cd,0x95ce,0x95cf,
+ 0x95d0,0x95d1,0x95d2,0x95d3,0x95d4,0x95d5,0x95d6,0x95d7,
+ 0x95d8,0x95d9,0x95da,0x95db,0x95dc,0x95dd,0x95de,0x95df,
+ 0x95e0,0x95e1,0x95e2,0x95e3,0x95e4,0x95e5,0x95e6,0x95e7,
+ 0x95e8,0x95e9,0x95ea,0x95eb,0x95ec,0x95ed,0x95ee,0x95ef,
+ 0x95f0,0x95f1,0x95f2,0x95f3,0x95f4,0x95f5,0x95f6,0x95f7,
+ 0x95f8,0x95f9,0x95fa,0x95fb,0x95fc,0x95fd,0x95fe,0x95ff,
+ 0x9600,0x9601,0x9602,0x9603,0x9604,0x9605,0x9606,0x9607,
+ 0x9608,0x9609,0x960a,0x960b,0x960c,0x960d,0x960e,0x960f,
+ 0x9610,0x9611,0x9612,0x9613,0x9614,0x9615,0x9616,0x9617,
+ 0x9618,0x9619,0x961a,0x961b,0x961c,0x961d,0x961e,0x961f,
+ 0x9620,0x9621,0x9622,0x9623,0x9624,0x9625,0x9626,0x9627,
+ 0x9628,0x9629,0x962a,0x962b,0x962c,0x962d,0x962e,0x962f,
+ 0x9630,0x9631,0x9632,0x9633,0x9634,0x9635,0x9636,0x9637,
+ 0x9638,0x9639,0x963a,0x963b,0x963c,0x963d,0x963e,0x963f,
+ 0x9640,0x9641,0x9642,0x9643,0x9644,0x9645,0x9646,0x9647,
+ 0x9648,0x9649,0x964a,0x964b,0x964c,0x964d,0x964e,0x964f,
+ 0x9650,0x9651,0x9652,0x9653,0x9654,0x9655,0x9656,0x9657,
+ 0x9658,0x9659,0x965a,0x965b,0x965c,0x965d,0x965e,0x965f,
+ 0x9660,0x9661,0x9662,0x9663,0x9664,0x9665,0x9666,0x9667,
+ 0x9668,0x9669,0x966a,0x966b,0x966c,0x966d,0x966e,0x966f,
+ 0x9670,0x9671,0x9672,0x9673,0x9674,0x9675,0x9676,0x9677,
+ 0x9678,0x9679,0x967a,0x967b,0x967c,0x967d,0x967e,0x967f,
+ 0x9680,0x9681,0x9682,0x9683,0x9684,0x9685,0x9686,0x9687,
+ 0x9688,0x9689,0x968a,0x968b,0x968c,0x968d,0x968e,0x968f,
+ 0x9690,0x9691,0x9692,0x9693,0x9694,0x9695,0x9696,0x9697,
+ 0x9698,0x9699,0x969a,0x969b,0x969c,0x969d,0x969e,0x969f,
+ 0x96a0,0x96a1,0x96a2,0x96a3,0x96a4,0x96a5,0x96a6,0x96a7,
+ 0x96a8,0x96a9,0x96aa,0x96ab,0x96ac,0x96ad,0x96ae,0x96af,
+ 0x96b0,0x96b1,0x96b2,0x96b3,0x96b4,0x96b5,0x96b6,0x96b7,
+ 0x96b8,0x96b9,0x96ba,0x96bb,0x96bc,0x96bd,0x96be,0x96bf,
+ 0x96c0,0x96c1,0x96c2,0x96c3,0x96c4,0x96c5,0x96c6,0x96c7,
+ 0x96c8,0x96c9,0x96ca,0x96cb,0x96cc,0x96cd,0x96ce,0x96cf,
+ 0x96d0,0x96d1,0x96d2,0x96d3,0x96d4,0x96d5,0x96d6,0x96d7,
+ 0x96d8,0x96d9,0x96da,0x96db,0x96dc,0x96dd,0x96de,0x96df,
+ 0x96e0,0x96e1,0x96e2,0x96e3,0x96e4,0x96e5,0x96e6,0x96e7,
+ 0x96e8,0x96e9,0x96ea,0x96eb,0x96ec,0x96ed,0x96ee,0x96ef,
+ 0x96f0,0x96f1,0x96f2,0x96f3,0x96f4,0x96f5,0x96f6,0x96f7,
+ 0x96f8,0x96f9,0x96fa,0x96fb,0x96fc,0x96fd,0x96fe,0x96ff,
+ 0x9700,0x9701,0x9702,0x9703,0x9704,0x9705,0x9706,0x9707,
+ 0x9708,0x9709,0x970a,0x970b,0x970c,0x970d,0x970e,0x970f,
+ 0x9710,0x9711,0x9712,0x9713,0x9714,0x9715,0x9716,0x9717,
+ 0x9718,0x9719,0x971a,0x971b,0x971c,0x971d,0x971e,0x971f,
+ 0x9720,0x9721,0x9722,0x9723,0x9724,0x9725,0x9726,0x9727,
+ 0x9728,0x9729,0x972a,0x972b,0x972c,0x972d,0x972e,0x972f,
+ 0x9730,0x9731,0x9732,0x9733,0x9734,0x9735,0x9736,0x9737,
+ 0x9738,0x9739,0x973a,0x973b,0x973c,0x973d,0x973e,0x973f,
+ 0x9740,0x9741,0x9742,0x9743,0x9744,0x9745,0x9746,0x9747,
+ 0x9748,0x9749,0x974a,0x974b,0x974c,0x974d,0x974e,0x974f,
+ 0x9750,0x9751,0x9752,0x9753,0x9754,0x9755,0x9756,0x9757,
+ 0x9758,0x9759,0x975a,0x975b,0x975c,0x975d,0x975e,0x975f,
+ 0x9760,0x9761,0x9762,0x9763,0x9764,0x9765,0x9766,0x9767,
+ 0x9768,0x9769,0x976a,0x976b,0x976c,0x976d,0x976e,0x976f,
+ 0x9770,0x9771,0x9772,0x9773,0x9774,0x9775,0x9776,0x9777,
+ 0x9778,0x9779,0x977a,0x977b,0x977c,0x977d,0x977e,0x977f,
+ 0x9780,0x9781,0x9782,0x9783,0x9784,0x9785,0x9786,0x9787,
+ 0x9788,0x9789,0x978a,0x978b,0x978c,0x978d,0x978e,0x978f,
+ 0x9790,0x9791,0x9792,0x9793,0x9794,0x9795,0x9796,0x9797,
+ 0x9798,0x9799,0x979a,0x979b,0x979c,0x979d,0x979e,0x979f,
+ 0x97a0,0x97a1,0x97a2,0x97a3,0x97a4,0x97a5,0x97a6,0x97a7,
+ 0x97a8,0x97a9,0x97aa,0x97ab,0x97ac,0x97ad,0x97ae,0x97af,
+ 0x97b0,0x97b1,0x97b2,0x97b3,0x97b4,0x97b5,0x97b6,0x97b7,
+ 0x97b8,0x97b9,0x97ba,0x97bb,0x97bc,0x97bd,0x97be,0x97bf,
+ 0x97c0,0x97c1,0x97c2,0x97c3,0x97c4,0x97c5,0x97c6,0x97c7,
+ 0x97c8,0x97c9,0x97ca,0x97cb,0x97cc,0x97cd,0x97ce,0x97cf,
+ 0x97d0,0x97d1,0x97d2,0x97d3,0x97d4,0x97d5,0x97d6,0x97d7,
+ 0x97d8,0x97d9,0x97da,0x97db,0x97dc,0x97dd,0x97de,0x97df,
+ 0x97e0,0x97e1,0x97e2,0x97e3,0x97e4,0x97e5,0x97e6,0x97e7,
+ 0x97e8,0x97e9,0x97ea,0x97eb,0x97ec,0x97ed,0x97ee,0x97ef,
+ 0x97f0,0x97f1,0x97f2,0x97f3,0x97f4,0x97f5,0x97f6,0x97f7,
+ 0x97f8,0x97f9,0x97fa,0x97fb,0x97fc,0x97fd,0x97fe,0x97ff,
+ 0x9800,0x9801,0x9802,0x9803,0x9804,0x9805,0x9806,0x9807,
+ 0x9808,0x9809,0x980a,0x980b,0x980c,0x980d,0x980e,0x980f,
+ 0x9810,0x9811,0x9812,0x9813,0x9814,0x9815,0x9816,0x9817,
+ 0x9818,0x9819,0x981a,0x981b,0x981c,0x981d,0x981e,0x981f,
+ 0x9820,0x9821,0x9822,0x9823,0x9824,0x9825,0x9826,0x9827,
+ 0x9828,0x9829,0x982a,0x982b,0x982c,0x982d,0x982e,0x982f,
+ 0x9830,0x9831,0x9832,0x9833,0x9834,0x9835,0x9836,0x9837,
+ 0x9838,0x9839,0x983a,0x983b,0x983c,0x983d,0x983e,0x983f,
+ 0x9840,0x9841,0x9842,0x9843,0x9844,0x9845,0x9846,0x9847,
+ 0x9848,0x9849,0x984a,0x984b,0x984c,0x984d,0x984e,0x984f,
+ 0x9850,0x9851,0x9852,0x9853,0x9854,0x9855,0x9856,0x9857,
+ 0x9858,0x9859,0x985a,0x985b,0x985c,0x985d,0x985e,0x985f,
+ 0x9860,0x9861,0x9862,0x9863,0x9864,0x9865,0x9866,0x9867,
+ 0x9868,0x9869,0x986a,0x986b,0x986c,0x986d,0x986e,0x986f,
+ 0x9870,0x9871,0x9872,0x9873,0x9874,0x9875,0x9876,0x9877,
+ 0x9878,0x9879,0x987a,0x987b,0x987c,0x987d,0x987e,0x987f,
+ 0x9880,0x9881,0x9882,0x9883,0x9884,0x9885,0x9886,0x9887,
+ 0x9888,0x9889,0x988a,0x988b,0x988c,0x988d,0x988e,0x988f,
+ 0x9890,0x9891,0x9892,0x9893,0x9894,0x9895,0x9896,0x9897,
+ 0x9898,0x9899,0x989a,0x989b,0x989c,0x989d,0x989e,0x989f,
+ 0x98a0,0x98a1,0x98a2,0x98a3,0x98a4,0x98a5,0x98a6,0x98a7,
+ 0x98a8,0x98a9,0x98aa,0x98ab,0x98ac,0x98ad,0x98ae,0x98af,
+ 0x98b0,0x98b1,0x98b2,0x98b3,0x98b4,0x98b5,0x98b6,0x98b7,
+ 0x98b8,0x98b9,0x98ba,0x98bb,0x98bc,0x98bd,0x98be,0x98bf,
+ 0x98c0,0x98c1,0x98c2,0x98c3,0x98c4,0x98c5,0x98c6,0x98c7,
+ 0x98c8,0x98c9,0x98ca,0x98cb,0x98cc,0x98cd,0x98ce,0x98cf,
+ 0x98d0,0x98d1,0x98d2,0x98d3,0x98d4,0x98d5,0x98d6,0x98d7,
+ 0x98d8,0x98d9,0x98da,0x98db,0x98dc,0x98dd,0x98de,0x98df,
+ 0x98e0,0x98e1,0x98e2,0x98e3,0x98e4,0x98e5,0x98e6,0x98e7,
+ 0x98e8,0x98e9,0x98ea,0x98eb,0x98ec,0x98ed,0x98ee,0x98ef,
+ 0x98f0,0x98f1,0x98f2,0x98f3,0x98f4,0x98f5,0x98f6,0x98f7,
+ 0x98f8,0x98f9,0x98fa,0x98fb,0x98fc,0x98fd,0x98fe,0x98ff,
+ 0x9900,0x9901,0x9902,0x9903,0x9904,0x9905,0x9906,0x9907,
+ 0x9908,0x9909,0x990a,0x990b,0x990c,0x990d,0x990e,0x990f,
+ 0x9910,0x9911,0x9912,0x9913,0x9914,0x9915,0x9916,0x9917,
+ 0x9918,0x9919,0x991a,0x991b,0x991c,0x991d,0x991e,0x991f,
+ 0x9920,0x9921,0x9922,0x9923,0x9924,0x9925,0x9926,0x9927,
+ 0x9928,0x9929,0x992a,0x992b,0x992c,0x992d,0x992e,0x992f,
+ 0x9930,0x9931,0x9932,0x9933,0x9934,0x9935,0x9936,0x9937,
+ 0x9938,0x9939,0x993a,0x993b,0x993c,0x993d,0x993e,0x993f,
+ 0x9940,0x9941,0x9942,0x9943,0x9944,0x9945,0x9946,0x9947,
+ 0x9948,0x9949,0x994a,0x994b,0x994c,0x994d,0x994e,0x994f,
+ 0x9950,0x9951,0x9952,0x9953,0x9954,0x9955,0x9956,0x9957,
+ 0x9958,0x9959,0x995a,0x995b,0x995c,0x995d,0x995e,0x995f,
+ 0x9960,0x9961,0x9962,0x9963,0x9964,0x9965,0x9966,0x9967,
+ 0x9968,0x9969,0x996a,0x996b,0x996c,0x996d,0x996e,0x996f,
+ 0x9970,0x9971,0x9972,0x9973,0x9974,0x9975,0x9976,0x9977,
+ 0x9978,0x9979,0x997a,0x997b,0x997c,0x997d,0x997e,0x997f,
+ 0x9980,0x9981,0x9982,0x9983,0x9984,0x9985,0x9986,0x9987,
+ 0x9988,0x9989,0x998a,0x998b,0x998c,0x998d,0x998e,0x998f,
+ 0x9990,0x9991,0x9992,0x9993,0x9994,0x9995,0x9996,0x9997,
+ 0x9998,0x9999,0x999a,0x999b,0x999c,0x999d,0x999e,0x999f,
+ 0x99a0,0x99a1,0x99a2,0x99a3,0x99a4,0x99a5,0x99a6,0x99a7,
+ 0x99a8,0x99a9,0x99aa,0x99ab,0x99ac,0x99ad,0x99ae,0x99af,
+ 0x99b0,0x99b1,0x99b2,0x99b3,0x99b4,0x99b5,0x99b6,0x99b7,
+ 0x99b8,0x99b9,0x99ba,0x99bb,0x99bc,0x99bd,0x99be,0x99bf,
+ 0x99c0,0x99c1,0x99c2,0x99c3,0x99c4,0x99c5,0x99c6,0x99c7,
+ 0x99c8,0x99c9,0x99ca,0x99cb,0x99cc,0x99cd,0x99ce,0x99cf,
+ 0x99d0,0x99d1,0x99d2,0x99d3,0x99d4,0x99d5,0x99d6,0x99d7,
+ 0x99d8,0x99d9,0x99da,0x99db,0x99dc,0x99dd,0x99de,0x99df,
+ 0x99e0,0x99e1,0x99e2,0x99e3,0x99e4,0x99e5,0x99e6,0x99e7,
+ 0x99e8,0x99e9,0x99ea,0x99eb,0x99ec,0x99ed,0x99ee,0x99ef,
+ 0x99f0,0x99f1,0x99f2,0x99f3,0x99f4,0x99f5,0x99f6,0x99f7,
+ 0x99f8,0x99f9,0x99fa,0x99fb,0x99fc,0x99fd,0x99fe,0x99ff,
+ 0x9a00,0x9a01,0x9a02,0x9a03,0x9a04,0x9a05,0x9a06,0x9a07,
+ 0x9a08,0x9a09,0x9a0a,0x9a0b,0x9a0c,0x9a0d,0x9a0e,0x9a0f,
+ 0x9a10,0x9a11,0x9a12,0x9a13,0x9a14,0x9a15,0x9a16,0x9a17,
+ 0x9a18,0x9a19,0x9a1a,0x9a1b,0x9a1c,0x9a1d,0x9a1e,0x9a1f,
+ 0x9a20,0x9a21,0x9a22,0x9a23,0x9a24,0x9a25,0x9a26,0x9a27,
+ 0x9a28,0x9a29,0x9a2a,0x9a2b,0x9a2c,0x9a2d,0x9a2e,0x9a2f,
+ 0x9a30,0x9a31,0x9a32,0x9a33,0x9a34,0x9a35,0x9a36,0x9a37,
+ 0x9a38,0x9a39,0x9a3a,0x9a3b,0x9a3c,0x9a3d,0x9a3e,0x9a3f,
+ 0x9a40,0x9a41,0x9a42,0x9a43,0x9a44,0x9a45,0x9a46,0x9a47,
+ 0x9a48,0x9a49,0x9a4a,0x9a4b,0x9a4c,0x9a4d,0x9a4e,0x9a4f,
+ 0x9a50,0x9a51,0x9a52,0x9a53,0x9a54,0x9a55,0x9a56,0x9a57,
+ 0x9a58,0x9a59,0x9a5a,0x9a5b,0x9a5c,0x9a5d,0x9a5e,0x9a5f,
+ 0x9a60,0x9a61,0x9a62,0x9a63,0x9a64,0x9a65,0x9a66,0x9a67,
+ 0x9a68,0x9a69,0x9a6a,0x9a6b,0x9a6c,0x9a6d,0x9a6e,0x9a6f,
+ 0x9a70,0x9a71,0x9a72,0x9a73,0x9a74,0x9a75,0x9a76,0x9a77,
+ 0x9a78,0x9a79,0x9a7a,0x9a7b,0x9a7c,0x9a7d,0x9a7e,0x9a7f,
+ 0x9a80,0x9a81,0x9a82,0x9a83,0x9a84,0x9a85,0x9a86,0x9a87,
+ 0x9a88,0x9a89,0x9a8a,0x9a8b,0x9a8c,0x9a8d,0x9a8e,0x9a8f,
+ 0x9a90,0x9a91,0x9a92,0x9a93,0x9a94,0x9a95,0x9a96,0x9a97,
+ 0x9a98,0x9a99,0x9a9a,0x9a9b,0x9a9c,0x9a9d,0x9a9e,0x9a9f,
+ 0x9aa0,0x9aa1,0x9aa2,0x9aa3,0x9aa4,0x9aa5,0x9aa6,0x9aa7,
+ 0x9aa8,0x9aa9,0x9aaa,0x9aab,0x9aac,0x9aad,0x9aae,0x9aaf,
+ 0x9ab0,0x9ab1,0x9ab2,0x9ab3,0x9ab4,0x9ab5,0x9ab6,0x9ab7,
+ 0x9ab8,0x9ab9,0x9aba,0x9abb,0x9abc,0x9abd,0x9abe,0x9abf,
+ 0x9ac0,0x9ac1,0x9ac2,0x9ac3,0x9ac4,0x9ac5,0x9ac6,0x9ac7,
+ 0x9ac8,0x9ac9,0x9aca,0x9acb,0x9acc,0x9acd,0x9ace,0x9acf,
+ 0x9ad0,0x9ad1,0x9ad2,0x9ad3,0x9ad4,0x9ad5,0x9ad6,0x9ad7,
+ 0x9ad8,0x9ad9,0x9ada,0x9adb,0x9adc,0x9add,0x9ade,0x9adf,
+ 0x9ae0,0x9ae1,0x9ae2,0x9ae3,0x9ae4,0x9ae5,0x9ae6,0x9ae7,
+ 0x9ae8,0x9ae9,0x9aea,0x9aeb,0x9aec,0x9aed,0x9aee,0x9aef,
+ 0x9af0,0x9af1,0x9af2,0x9af3,0x9af4,0x9af5,0x9af6,0x9af7,
+ 0x9af8,0x9af9,0x9afa,0x9afb,0x9afc,0x9afd,0x9afe,0x9aff,
+ 0x9b00,0x9b01,0x9b02,0x9b03,0x9b04,0x9b05,0x9b06,0x9b07,
+ 0x9b08,0x9b09,0x9b0a,0x9b0b,0x9b0c,0x9b0d,0x9b0e,0x9b0f,
+ 0x9b10,0x9b11,0x9b12,0x9b13,0x9b14,0x9b15,0x9b16,0x9b17,
+ 0x9b18,0x9b19,0x9b1a,0x9b1b,0x9b1c,0x9b1d,0x9b1e,0x9b1f,
+ 0x9b20,0x9b21,0x9b22,0x9b23,0x9b24,0x9b25,0x9b26,0x9b27,
+ 0x9b28,0x9b29,0x9b2a,0x9b2b,0x9b2c,0x9b2d,0x9b2e,0x9b2f,
+ 0x9b30,0x9b31,0x9b32,0x9b33,0x9b34,0x9b35,0x9b36,0x9b37,
+ 0x9b38,0x9b39,0x9b3a,0x9b3b,0x9b3c,0x9b3d,0x9b3e,0x9b3f,
+ 0x9b40,0x9b41,0x9b42,0x9b43,0x9b44,0x9b45,0x9b46,0x9b47,
+ 0x9b48,0x9b49,0x9b4a,0x9b4b,0x9b4c,0x9b4d,0x9b4e,0x9b4f,
+ 0x9b50,0x9b51,0x9b52,0x9b53,0x9b54,0x9b55,0x9b56,0x9b57,
+ 0x9b58,0x9b59,0x9b5a,0x9b5b,0x9b5c,0x9b5d,0x9b5e,0x9b5f,
+ 0x9b60,0x9b61,0x9b62,0x9b63,0x9b64,0x9b65,0x9b66,0x9b67,
+ 0x9b68,0x9b69,0x9b6a,0x9b6b,0x9b6c,0x9b6d,0x9b6e,0x9b6f,
+ 0x9b70,0x9b71,0x9b72,0x9b73,0x9b74,0x9b75,0x9b76,0x9b77,
+ 0x9b78,0x9b79,0x9b7a,0x9b7b,0x9b7c,0x9b7d,0x9b7e,0x9b7f,
+ 0x9b80,0x9b81,0x9b82,0x9b83,0x9b84,0x9b85,0x9b86,0x9b87,
+ 0x9b88,0x9b89,0x9b8a,0x9b8b,0x9b8c,0x9b8d,0x9b8e,0x9b8f,
+ 0x9b90,0x9b91,0x9b92,0x9b93,0x9b94,0x9b95,0x9b96,0x9b97,
+ 0x9b98,0x9b99,0x9b9a,0x9b9b,0x9b9c,0x9b9d,0x9b9e,0x9b9f,
+ 0x9ba0,0x9ba1,0x9ba2,0x9ba3,0x9ba4,0x9ba5,0x9ba6,0x9ba7,
+ 0x9ba8,0x9ba9,0x9baa,0x9bab,0x9bac,0x9bad,0x9bae,0x9baf,
+ 0x9bb0,0x9bb1,0x9bb2,0x9bb3,0x9bb4,0x9bb5,0x9bb6,0x9bb7,
+ 0x9bb8,0x9bb9,0x9bba,0x9bbb,0x9bbc,0x9bbd,0x9bbe,0x9bbf,
+ 0x9bc0,0x9bc1,0x9bc2,0x9bc3,0x9bc4,0x9bc5,0x9bc6,0x9bc7,
+ 0x9bc8,0x9bc9,0x9bca,0x9bcb,0x9bcc,0x9bcd,0x9bce,0x9bcf,
+ 0x9bd0,0x9bd1,0x9bd2,0x9bd3,0x9bd4,0x9bd5,0x9bd6,0x9bd7,
+ 0x9bd8,0x9bd9,0x9bda,0x9bdb,0x9bdc,0x9bdd,0x9bde,0x9bdf,
+ 0x9be0,0x9be1,0x9be2,0x9be3,0x9be4,0x9be5,0x9be6,0x9be7,
+ 0x9be8,0x9be9,0x9bea,0x9beb,0x9bec,0x9bed,0x9bee,0x9bef,
+ 0x9bf0,0x9bf1,0x9bf2,0x9bf3,0x9bf4,0x9bf5,0x9bf6,0x9bf7,
+ 0x9bf8,0x9bf9,0x9bfa,0x9bfb,0x9bfc,0x9bfd,0x9bfe,0x9bff,
+ 0x9c00,0x9c01,0x9c02,0x9c03,0x9c04,0x9c05,0x9c06,0x9c07,
+ 0x9c08,0x9c09,0x9c0a,0x9c0b,0x9c0c,0x9c0d,0x9c0e,0x9c0f,
+ 0x9c10,0x9c11,0x9c12,0x9c13,0x9c14,0x9c15,0x9c16,0x9c17,
+ 0x9c18,0x9c19,0x9c1a,0x9c1b,0x9c1c,0x9c1d,0x9c1e,0x9c1f,
+ 0x9c20,0x9c21,0x9c22,0x9c23,0x9c24,0x9c25,0x9c26,0x9c27,
+ 0x9c28,0x9c29,0x9c2a,0x9c2b,0x9c2c,0x9c2d,0x9c2e,0x9c2f,
+ 0x9c30,0x9c31,0x9c32,0x9c33,0x9c34,0x9c35,0x9c36,0x9c37,
+ 0x9c38,0x9c39,0x9c3a,0x9c3b,0x9c3c,0x9c3d,0x9c3e,0x9c3f,
+ 0x9c40,0x9c41,0x9c42,0x9c43,0x9c44,0x9c45,0x9c46,0x9c47,
+ 0x9c48,0x9c49,0x9c4a,0x9c4b,0x9c4c,0x9c4d,0x9c4e,0x9c4f,
+ 0x9c50,0x9c51,0x9c52,0x9c53,0x9c54,0x9c55,0x9c56,0x9c57,
+ 0x9c58,0x9c59,0x9c5a,0x9c5b,0x9c5c,0x9c5d,0x9c5e,0x9c5f,
+ 0x9c60,0x9c61,0x9c62,0x9c63,0x9c64,0x9c65,0x9c66,0x9c67,
+ 0x9c68,0x9c69,0x9c6a,0x9c6b,0x9c6c,0x9c6d,0x9c6e,0x9c6f,
+ 0x9c70,0x9c71,0x9c72,0x9c73,0x9c74,0x9c75,0x9c76,0x9c77,
+ 0x9c78,0x9c79,0x9c7a,0x9c7b,0x9c7c,0x9c7d,0x9c7e,0x9c7f,
+ 0x9c80,0x9c81,0x9c82,0x9c83,0x9c84,0x9c85,0x9c86,0x9c87,
+ 0x9c88,0x9c89,0x9c8a,0x9c8b,0x9c8c,0x9c8d,0x9c8e,0x9c8f,
+ 0x9c90,0x9c91,0x9c92,0x9c93,0x9c94,0x9c95,0x9c96,0x9c97,
+ 0x9c98,0x9c99,0x9c9a,0x9c9b,0x9c9c,0x9c9d,0x9c9e,0x9c9f,
+ 0x9ca0,0x9ca1,0x9ca2,0x9ca3,0x9ca4,0x9ca5,0x9ca6,0x9ca7,
+ 0x9ca8,0x9ca9,0x9caa,0x9cab,0x9cac,0x9cad,0x9cae,0x9caf,
+ 0x9cb0,0x9cb1,0x9cb2,0x9cb3,0x9cb4,0x9cb5,0x9cb6,0x9cb7,
+ 0x9cb8,0x9cb9,0x9cba,0x9cbb,0x9cbc,0x9cbd,0x9cbe,0x9cbf,
+ 0x9cc0,0x9cc1,0x9cc2,0x9cc3,0x9cc4,0x9cc5,0x9cc6,0x9cc7,
+ 0x9cc8,0x9cc9,0x9cca,0x9ccb,0x9ccc,0x9ccd,0x9cce,0x9ccf,
+ 0x9cd0,0x9cd1,0x9cd2,0x9cd3,0x9cd4,0x9cd5,0x9cd6,0x9cd7,
+ 0x9cd8,0x9cd9,0x9cda,0x9cdb,0x9cdc,0x9cdd,0x9cde,0x9cdf,
+ 0x9ce0,0x9ce1,0x9ce2,0x9ce3,0x9ce4,0x9ce5,0x9ce6,0x9ce7,
+ 0x9ce8,0x9ce9,0x9cea,0x9ceb,0x9cec,0x9ced,0x9cee,0x9cef,
+ 0x9cf0,0x9cf1,0x9cf2,0x9cf3,0x9cf4,0x9cf5,0x9cf6,0x9cf7,
+ 0x9cf8,0x9cf9,0x9cfa,0x9cfb,0x9cfc,0x9cfd,0x9cfe,0x9cff,
+ 0x9d00,0x9d01,0x9d02,0x9d03,0x9d04,0x9d05,0x9d06,0x9d07,
+ 0x9d08,0x9d09,0x9d0a,0x9d0b,0x9d0c,0x9d0d,0x9d0e,0x9d0f,
+ 0x9d10,0x9d11,0x9d12,0x9d13,0x9d14,0x9d15,0x9d16,0x9d17,
+ 0x9d18,0x9d19,0x9d1a,0x9d1b,0x9d1c,0x9d1d,0x9d1e,0x9d1f,
+ 0x9d20,0x9d21,0x9d22,0x9d23,0x9d24,0x9d25,0x9d26,0x9d27,
+ 0x9d28,0x9d29,0x9d2a,0x9d2b,0x9d2c,0x9d2d,0x9d2e,0x9d2f,
+ 0x9d30,0x9d31,0x9d32,0x9d33,0x9d34,0x9d35,0x9d36,0x9d37,
+ 0x9d38,0x9d39,0x9d3a,0x9d3b,0x9d3c,0x9d3d,0x9d3e,0x9d3f,
+ 0x9d40,0x9d41,0x9d42,0x9d43,0x9d44,0x9d45,0x9d46,0x9d47,
+ 0x9d48,0x9d49,0x9d4a,0x9d4b,0x9d4c,0x9d4d,0x9d4e,0x9d4f,
+ 0x9d50,0x9d51,0x9d52,0x9d53,0x9d54,0x9d55,0x9d56,0x9d57,
+ 0x9d58,0x9d59,0x9d5a,0x9d5b,0x9d5c,0x9d5d,0x9d5e,0x9d5f,
+ 0x9d60,0x9d61,0x9d62,0x9d63,0x9d64,0x9d65,0x9d66,0x9d67,
+ 0x9d68,0x9d69,0x9d6a,0x9d6b,0x9d6c,0x9d6d,0x9d6e,0x9d6f,
+ 0x9d70,0x9d71,0x9d72,0x9d73,0x9d74,0x9d75,0x9d76,0x9d77,
+ 0x9d78,0x9d79,0x9d7a,0x9d7b,0x9d7c,0x9d7d,0x9d7e,0x9d7f,
+ 0x9d80,0x9d81,0x9d82,0x9d83,0x9d84,0x9d85,0x9d86,0x9d87,
+ 0x9d88,0x9d89,0x9d8a,0x9d8b,0x9d8c,0x9d8d,0x9d8e,0x9d8f,
+ 0x9d90,0x9d91,0x9d92,0x9d93,0x9d94,0x9d95,0x9d96,0x9d97,
+ 0x9d98,0x9d99,0x9d9a,0x9d9b,0x9d9c,0x9d9d,0x9d9e,0x9d9f,
+ 0x9da0,0x9da1,0x9da2,0x9da3,0x9da4,0x9da5,0x9da6,0x9da7,
+ 0x9da8,0x9da9,0x9daa,0x9dab,0x9dac,0x9dad,0x9dae,0x9daf,
+ 0x9db0,0x9db1,0x9db2,0x9db3,0x9db4,0x9db5,0x9db6,0x9db7,
+ 0x9db8,0x9db9,0x9dba,0x9dbb,0x9dbc,0x9dbd,0x9dbe,0x9dbf,
+ 0x9dc0,0x9dc1,0x9dc2,0x9dc3,0x9dc4,0x9dc5,0x9dc6,0x9dc7,
+ 0x9dc8,0x9dc9,0x9dca,0x9dcb,0x9dcc,0x9dcd,0x9dce,0x9dcf,
+ 0x9dd0,0x9dd1,0x9dd2,0x9dd3,0x9dd4,0x9dd5,0x9dd6,0x9dd7,
+ 0x9dd8,0x9dd9,0x9dda,0x9ddb,0x9ddc,0x9ddd,0x9dde,0x9ddf,
+ 0x9de0,0x9de1,0x9de2,0x9de3,0x9de4,0x9de5,0x9de6,0x9de7,
+ 0x9de8,0x9de9,0x9dea,0x9deb,0x9dec,0x9ded,0x9dee,0x9def,
+ 0x9df0,0x9df1,0x9df2,0x9df3,0x9df4,0x9df5,0x9df6,0x9df7,
+ 0x9df8,0x9df9,0x9dfa,0x9dfb,0x9dfc,0x9dfd,0x9dfe,0x9dff,
+ 0x9e00,0x9e01,0x9e02,0x9e03,0x9e04,0x9e05,0x9e06,0x9e07,
+ 0x9e08,0x9e09,0x9e0a,0x9e0b,0x9e0c,0x9e0d,0x9e0e,0x9e0f,
+ 0x9e10,0x9e11,0x9e12,0x9e13,0x9e14,0x9e15,0x9e16,0x9e17,
+ 0x9e18,0x9e19,0x9e1a,0x9e1b,0x9e1c,0x9e1d,0x9e1e,0x9e1f,
+ 0x9e20,0x9e21,0x9e22,0x9e23,0x9e24,0x9e25,0x9e26,0x9e27,
+ 0x9e28,0x9e29,0x9e2a,0x9e2b,0x9e2c,0x9e2d,0x9e2e,0x9e2f,
+ 0x9e30,0x9e31,0x9e32,0x9e33,0x9e34,0x9e35,0x9e36,0x9e37,
+ 0x9e38,0x9e39,0x9e3a,0x9e3b,0x9e3c,0x9e3d,0x9e3e,0x9e3f,
+ 0x9e40,0x9e41,0x9e42,0x9e43,0x9e44,0x9e45,0x9e46,0x9e47,
+ 0x9e48,0x9e49,0x9e4a,0x9e4b,0x9e4c,0x9e4d,0x9e4e,0x9e4f,
+ 0x9e50,0x9e51,0x9e52,0x9e53,0x9e54,0x9e55,0x9e56,0x9e57,
+ 0x9e58,0x9e59,0x9e5a,0x9e5b,0x9e5c,0x9e5d,0x9e5e,0x9e5f,
+ 0x9e60,0x9e61,0x9e62,0x9e63,0x9e64,0x9e65,0x9e66,0x9e67,
+ 0x9e68,0x9e69,0x9e6a,0x9e6b,0x9e6c,0x9e6d,0x9e6e,0x9e6f,
+ 0x9e70,0x9e71,0x9e72,0x9e73,0x9e74,0x9e75,0x9e76,0x9e77,
+ 0x9e78,0x9e79,0x9e7a,0x9e7b,0x9e7c,0x9e7d,0x9e7e,0x9e7f,
+ 0x9e80,0x9e81,0x9e82,0x9e83,0x9e84,0x9e85,0x9e86,0x9e87,
+ 0x9e88,0x9e89,0x9e8a,0x9e8b,0x9e8c,0x9e8d,0x9e8e,0x9e8f,
+ 0x9e90,0x9e91,0x9e92,0x9e93,0x9e94,0x9e95,0x9e96,0x9e97,
+ 0x9e98,0x9e99,0x9e9a,0x9e9b,0x9e9c,0x9e9d,0x9e9e,0x9e9f,
+ 0x9ea0,0x9ea1,0x9ea2,0x9ea3,0x9ea4,0x9ea5,0x9ea6,0x9ea7,
+ 0x9ea8,0x9ea9,0x9eaa,0x9eab,0x9eac,0x9ead,0x9eae,0x9eaf,
+ 0x9eb0,0x9eb1,0x9eb2,0x9eb3,0x9eb4,0x9eb5,0x9eb6,0x9eb7,
+ 0x9eb8,0x9eb9,0x9eba,0x9ebb,0x9ebc,0x9ebd,0x9ebe,0x9ebf,
+ 0x9ec0,0x9ec1,0x9ec2,0x9ec3,0x9ec4,0x9ec5,0x9ec6,0x9ec7,
+ 0x9ec8,0x9ec9,0x9eca,0x9ecb,0x9ecc,0x9ecd,0x9ece,0x9ecf,
+ 0x9ed0,0x9ed1,0x9ed2,0x9ed3,0x9ed4,0x9ed5,0x9ed6,0x9ed7,
+ 0x9ed8,0x9ed9,0x9eda,0x9edb,0x9edc,0x9edd,0x9ede,0x9edf,
+ 0x9ee0,0x9ee1,0x9ee2,0x9ee3,0x9ee4,0x9ee5,0x9ee6,0x9ee7,
+ 0x9ee8,0x9ee9,0x9eea,0x9eeb,0x9eec,0x9eed,0x9eee,0x9eef,
+ 0x9ef0,0x9ef1,0x9ef2,0x9ef3,0x9ef4,0x9ef5,0x9ef6,0x9ef7,
+ 0x9ef8,0x9ef9,0x9efa,0x9efb,0x9efc,0x9efd,0x9efe,0x9eff,
+ 0x9f00,0x9f01,0x9f02,0x9f03,0x9f04,0x9f05,0x9f06,0x9f07,
+ 0x9f08,0x9f09,0x9f0a,0x9f0b,0x9f0c,0x9f0d,0x9f0e,0x9f0f,
+ 0x9f10,0x9f11,0x9f12,0x9f13,0x9f14,0x9f15,0x9f16,0x9f17,
+ 0x9f18,0x9f19,0x9f1a,0x9f1b,0x9f1c,0x9f1d,0x9f1e,0x9f1f,
+ 0x9f20,0x9f21,0x9f22,0x9f23,0x9f24,0x9f25,0x9f26,0x9f27,
+ 0x9f28,0x9f29,0x9f2a,0x9f2b,0x9f2c,0x9f2d,0x9f2e,0x9f2f,
+ 0x9f30,0x9f31,0x9f32,0x9f33,0x9f34,0x9f35,0x9f36,0x9f37,
+ 0x9f38,0x9f39,0x9f3a,0x9f3b,0x9f3c,0x9f3d,0x9f3e,0x9f3f,
+ 0x9f40,0x9f41,0x9f42,0x9f43,0x9f44,0x9f45,0x9f46,0x9f47,
+ 0x9f48,0x9f49,0x9f4a,0x9f4b,0x9f4c,0x9f4d,0x9f4e,0x9f4f,
+ 0x9f50,0x9f51,0x9f52,0x9f53,0x9f54,0x9f55,0x9f56,0x9f57,
+ 0x9f58,0x9f59,0x9f5a,0x9f5b,0x9f5c,0x9f5d,0x9f5e,0x9f5f,
+ 0x9f60,0x9f61,0x9f62,0x9f63,0x9f64,0x9f65,0x9f66,0x9f67,
+ 0x9f68,0x9f69,0x9f6a,0x9f6b,0x9f6c,0x9f6d,0x9f6e,0x9f6f,
+ 0x9f70,0x9f71,0x9f72,0x9f73,0x9f74,0x9f75,0x9f76,0x9f77,
+ 0x9f78,0x9f79,0x9f7a,0x9f7b,0x9f7c,0x9f7d,0x9f7e,0x9f7f,
+ 0x9f80,0x9f81,0x9f82,0x9f83,0x9f84,0x9f85,0x9f86,0x9f87,
+ 0x9f88,0x9f89,0x9f8a,0x9f8b,0x9f8c,0x9f8d,0x9f8e,0x9f8f,
+ 0x9f90,0x9f91,0x9f92,0x9f93,0x9f94,0x9f95,0x9f96,0x9f97,
+ 0x9f98,0x9f99,0x9f9a,0x9f9b,0x9f9c,0x9f9d,0x9f9e,0x9f9f,
+ 0x9fa0,0x9fa1,0x9fa2,0x9fa3,0x9fa4,0x9fa5,0x9fa6,0x9fa7,
+ 0x9fa8,0x9fa9,0x9faa,0x9fab,0x9fac,0x9fad,0x9fae,0x9faf,
+ 0x9fb0,0x9fb1,0x9fb2,0x9fb3,0x9fb4,0x9fb5,0x9fb6,0x9fb7,
+ 0x9fb8,0x9fb9,0x9fba,0x9fbb,0x9fbc,0x9fbd,0x9fbe,0x9fbf,
+ 0x9fc0,0x9fc1,0x9fc2,0x9fc3,0x9fc4,0x9fc5,0x9fc6,0x9fc7,
+ 0x9fc8,0x9fc9,0x9fca,0x9fcb,0x9fcc,0x9fcd,0x9fce,0x9fcf,
+ 0x9fd0,0x9fd1,0x9fd2,0x9fd3,0x9fd4,0x9fd5,0x9fd6,0x9fd7,
+ 0x9fd8,0x9fd9,0x9fda,0x9fdb,0x9fdc,0x9fdd,0x9fde,0x9fdf,
+ 0x9fe0,0x9fe1,0x9fe2,0x9fe3,0x9fe4,0x9fe5,0x9fe6,0x9fe7,
+ 0x9fe8,0x9fe9,0x9fea,0x9feb,0x9fec,0x9fed,0x9fee,0x9fef,
+ 0x9ff0,0x9ff1,0x9ff2,0x9ff3,0x9ff4,0x9ff5,0x9ff6,0x9ff7,
+ 0x9ff8,0x9ff9,0x9ffa,0x9ffb,0x9ffc,0x9ffd,0x9ffe,0x9fff,
+ 0xa000,0xa001,0xa002,0xa003,0xa004,0xa005,0xa006,0xa007,
+ 0xa008,0xa009,0xa00a,0xa00b,0xa00c,0xa00d,0xa00e,0xa00f,
+ 0xa010,0xa011,0xa012,0xa013,0xa014,0xa015,0xa016,0xa017,
+ 0xa018,0xa019,0xa01a,0xa01b,0xa01c,0xa01d,0xa01e,0xa01f,
+ 0xa020,0xa021,0xa022,0xa023,0xa024,0xa025,0xa026,0xa027,
+ 0xa028,0xa029,0xa02a,0xa02b,0xa02c,0xa02d,0xa02e,0xa02f,
+ 0xa030,0xa031,0xa032,0xa033,0xa034,0xa035,0xa036,0xa037,
+ 0xa038,0xa039,0xa03a,0xa03b,0xa03c,0xa03d,0xa03e,0xa03f,
+ 0xa040,0xa041,0xa042,0xa043,0xa044,0xa045,0xa046,0xa047,
+ 0xa048,0xa049,0xa04a,0xa04b,0xa04c,0xa04d,0xa04e,0xa04f,
+ 0xa050,0xa051,0xa052,0xa053,0xa054,0xa055,0xa056,0xa057,
+ 0xa058,0xa059,0xa05a,0xa05b,0xa05c,0xa05d,0xa05e,0xa05f,
+ 0xa060,0xa061,0xa062,0xa063,0xa064,0xa065,0xa066,0xa067,
+ 0xa068,0xa069,0xa06a,0xa06b,0xa06c,0xa06d,0xa06e,0xa06f,
+ 0xa070,0xa071,0xa072,0xa073,0xa074,0xa075,0xa076,0xa077,
+ 0xa078,0xa079,0xa07a,0xa07b,0xa07c,0xa07d,0xa07e,0xa07f,
+ 0xa080,0xa081,0xa082,0xa083,0xa084,0xa085,0xa086,0xa087,
+ 0xa088,0xa089,0xa08a,0xa08b,0xa08c,0xa08d,0xa08e,0xa08f,
+ 0xa090,0xa091,0xa092,0xa093,0xa094,0xa095,0xa096,0xa097,
+ 0xa098,0xa099,0xa09a,0xa09b,0xa09c,0xa09d,0xa09e,0xa09f,
+ 0xa0a0,0xa0a1,0xa0a2,0xa0a3,0xa0a4,0xa0a5,0xa0a6,0xa0a7,
+ 0xa0a8,0xa0a9,0xa0aa,0xa0ab,0xa0ac,0xa0ad,0xa0ae,0xa0af,
+ 0xa0b0,0xa0b1,0xa0b2,0xa0b3,0xa0b4,0xa0b5,0xa0b6,0xa0b7,
+ 0xa0b8,0xa0b9,0xa0ba,0xa0bb,0xa0bc,0xa0bd,0xa0be,0xa0bf,
+ 0xa0c0,0xa0c1,0xa0c2,0xa0c3,0xa0c4,0xa0c5,0xa0c6,0xa0c7,
+ 0xa0c8,0xa0c9,0xa0ca,0xa0cb,0xa0cc,0xa0cd,0xa0ce,0xa0cf,
+ 0xa0d0,0xa0d1,0xa0d2,0xa0d3,0xa0d4,0xa0d5,0xa0d6,0xa0d7,
+ 0xa0d8,0xa0d9,0xa0da,0xa0db,0xa0dc,0xa0dd,0xa0de,0xa0df,
+ 0xa0e0,0xa0e1,0xa0e2,0xa0e3,0xa0e4,0xa0e5,0xa0e6,0xa0e7,
+ 0xa0e8,0xa0e9,0xa0ea,0xa0eb,0xa0ec,0xa0ed,0xa0ee,0xa0ef,
+ 0xa0f0,0xa0f1,0xa0f2,0xa0f3,0xa0f4,0xa0f5,0xa0f6,0xa0f7,
+ 0xa0f8,0xa0f9,0xa0fa,0xa0fb,0xa0fc,0xa0fd,0xa0fe,0xa0ff,
+ 0xa100,0xa101,0xa102,0xa103,0xa104,0xa105,0xa106,0xa107,
+ 0xa108,0xa109,0xa10a,0xa10b,0xa10c,0xa10d,0xa10e,0xa10f,
+ 0xa110,0xa111,0xa112,0xa113,0xa114,0xa115,0xa116,0xa117,
+ 0xa118,0xa119,0xa11a,0xa11b,0xa11c,0xa11d,0xa11e,0xa11f,
+ 0xa120,0xa121,0xa122,0xa123,0xa124,0xa125,0xa126,0xa127,
+ 0xa128,0xa129,0xa12a,0xa12b,0xa12c,0xa12d,0xa12e,0xa12f,
+ 0xa130,0xa131,0xa132,0xa133,0xa134,0xa135,0xa136,0xa137,
+ 0xa138,0xa139,0xa13a,0xa13b,0xa13c,0xa13d,0xa13e,0xa13f,
+ 0xa140,0xa141,0xa142,0xa143,0xa144,0xa145,0xa146,0xa147,
+ 0xa148,0xa149,0xa14a,0xa14b,0xa14c,0xa14d,0xa14e,0xa14f,
+ 0xa150,0xa151,0xa152,0xa153,0xa154,0xa155,0xa156,0xa157,
+ 0xa158,0xa159,0xa15a,0xa15b,0xa15c,0xa15d,0xa15e,0xa15f,
+ 0xa160,0xa161,0xa162,0xa163,0xa164,0xa165,0xa166,0xa167,
+ 0xa168,0xa169,0xa16a,0xa16b,0xa16c,0xa16d,0xa16e,0xa16f,
+ 0xa170,0xa171,0xa172,0xa173,0xa174,0xa175,0xa176,0xa177,
+ 0xa178,0xa179,0xa17a,0xa17b,0xa17c,0xa17d,0xa17e,0xa17f,
+ 0xa180,0xa181,0xa182,0xa183,0xa184,0xa185,0xa186,0xa187,
+ 0xa188,0xa189,0xa18a,0xa18b,0xa18c,0xa18d,0xa18e,0xa18f,
+ 0xa190,0xa191,0xa192,0xa193,0xa194,0xa195,0xa196,0xa197,
+ 0xa198,0xa199,0xa19a,0xa19b,0xa19c,0xa19d,0xa19e,0xa19f,
+ 0xa1a0,0xa1a1,0xa1a2,0xa1a3,0xa1a4,0xa1a5,0xa1a6,0xa1a7,
+ 0xa1a8,0xa1a9,0xa1aa,0xa1ab,0xa1ac,0xa1ad,0xa1ae,0xa1af,
+ 0xa1b0,0xa1b1,0xa1b2,0xa1b3,0xa1b4,0xa1b5,0xa1b6,0xa1b7,
+ 0xa1b8,0xa1b9,0xa1ba,0xa1bb,0xa1bc,0xa1bd,0xa1be,0xa1bf,
+ 0xa1c0,0xa1c1,0xa1c2,0xa1c3,0xa1c4,0xa1c5,0xa1c6,0xa1c7,
+ 0xa1c8,0xa1c9,0xa1ca,0xa1cb,0xa1cc,0xa1cd,0xa1ce,0xa1cf,
+ 0xa1d0,0xa1d1,0xa1d2,0xa1d3,0xa1d4,0xa1d5,0xa1d6,0xa1d7,
+ 0xa1d8,0xa1d9,0xa1da,0xa1db,0xa1dc,0xa1dd,0xa1de,0xa1df,
+ 0xa1e0,0xa1e1,0xa1e2,0xa1e3,0xa1e4,0xa1e5,0xa1e6,0xa1e7,
+ 0xa1e8,0xa1e9,0xa1ea,0xa1eb,0xa1ec,0xa1ed,0xa1ee,0xa1ef,
+ 0xa1f0,0xa1f1,0xa1f2,0xa1f3,0xa1f4,0xa1f5,0xa1f6,0xa1f7,
+ 0xa1f8,0xa1f9,0xa1fa,0xa1fb,0xa1fc,0xa1fd,0xa1fe,0xa1ff,
+ 0xa200,0xa201,0xa202,0xa203,0xa204,0xa205,0xa206,0xa207,
+ 0xa208,0xa209,0xa20a,0xa20b,0xa20c,0xa20d,0xa20e,0xa20f,
+ 0xa210,0xa211,0xa212,0xa213,0xa214,0xa215,0xa216,0xa217,
+ 0xa218,0xa219,0xa21a,0xa21b,0xa21c,0xa21d,0xa21e,0xa21f,
+ 0xa220,0xa221,0xa222,0xa223,0xa224,0xa225,0xa226,0xa227,
+ 0xa228,0xa229,0xa22a,0xa22b,0xa22c,0xa22d,0xa22e,0xa22f,
+ 0xa230,0xa231,0xa232,0xa233,0xa234,0xa235,0xa236,0xa237,
+ 0xa238,0xa239,0xa23a,0xa23b,0xa23c,0xa23d,0xa23e,0xa23f,
+ 0xa240,0xa241,0xa242,0xa243,0xa244,0xa245,0xa246,0xa247,
+ 0xa248,0xa249,0xa24a,0xa24b,0xa24c,0xa24d,0xa24e,0xa24f,
+ 0xa250,0xa251,0xa252,0xa253,0xa254,0xa255,0xa256,0xa257,
+ 0xa258,0xa259,0xa25a,0xa25b,0xa25c,0xa25d,0xa25e,0xa25f,
+ 0xa260,0xa261,0xa262,0xa263,0xa264,0xa265,0xa266,0xa267,
+ 0xa268,0xa269,0xa26a,0xa26b,0xa26c,0xa26d,0xa26e,0xa26f,
+ 0xa270,0xa271,0xa272,0xa273,0xa274,0xa275,0xa276,0xa277,
+ 0xa278,0xa279,0xa27a,0xa27b,0xa27c,0xa27d,0xa27e,0xa27f,
+ 0xa280,0xa281,0xa282,0xa283,0xa284,0xa285,0xa286,0xa287,
+ 0xa288,0xa289,0xa28a,0xa28b,0xa28c,0xa28d,0xa28e,0xa28f,
+ 0xa290,0xa291,0xa292,0xa293,0xa294,0xa295,0xa296,0xa297,
+ 0xa298,0xa299,0xa29a,0xa29b,0xa29c,0xa29d,0xa29e,0xa29f,
+ 0xa2a0,0xa2a1,0xa2a2,0xa2a3,0xa2a4,0xa2a5,0xa2a6,0xa2a7,
+ 0xa2a8,0xa2a9,0xa2aa,0xa2ab,0xa2ac,0xa2ad,0xa2ae,0xa2af,
+ 0xa2b0,0xa2b1,0xa2b2,0xa2b3,0xa2b4,0xa2b5,0xa2b6,0xa2b7,
+ 0xa2b8,0xa2b9,0xa2ba,0xa2bb,0xa2bc,0xa2bd,0xa2be,0xa2bf,
+ 0xa2c0,0xa2c1,0xa2c2,0xa2c3,0xa2c4,0xa2c5,0xa2c6,0xa2c7,
+ 0xa2c8,0xa2c9,0xa2ca,0xa2cb,0xa2cc,0xa2cd,0xa2ce,0xa2cf,
+ 0xa2d0,0xa2d1,0xa2d2,0xa2d3,0xa2d4,0xa2d5,0xa2d6,0xa2d7,
+ 0xa2d8,0xa2d9,0xa2da,0xa2db,0xa2dc,0xa2dd,0xa2de,0xa2df,
+ 0xa2e0,0xa2e1,0xa2e2,0xa2e3,0xa2e4,0xa2e5,0xa2e6,0xa2e7,
+ 0xa2e8,0xa2e9,0xa2ea,0xa2eb,0xa2ec,0xa2ed,0xa2ee,0xa2ef,
+ 0xa2f0,0xa2f1,0xa2f2,0xa2f3,0xa2f4,0xa2f5,0xa2f6,0xa2f7,
+ 0xa2f8,0xa2f9,0xa2fa,0xa2fb,0xa2fc,0xa2fd,0xa2fe,0xa2ff,
+ 0xa300,0xa301,0xa302,0xa303,0xa304,0xa305,0xa306,0xa307,
+ 0xa308,0xa309,0xa30a,0xa30b,0xa30c,0xa30d,0xa30e,0xa30f,
+ 0xa310,0xa311,0xa312,0xa313,0xa314,0xa315,0xa316,0xa317,
+ 0xa318,0xa319,0xa31a,0xa31b,0xa31c,0xa31d,0xa31e,0xa31f,
+ 0xa320,0xa321,0xa322,0xa323,0xa324,0xa325,0xa326,0xa327,
+ 0xa328,0xa329,0xa32a,0xa32b,0xa32c,0xa32d,0xa32e,0xa32f,
+ 0xa330,0xa331,0xa332,0xa333,0xa334,0xa335,0xa336,0xa337,
+ 0xa338,0xa339,0xa33a,0xa33b,0xa33c,0xa33d,0xa33e,0xa33f,
+ 0xa340,0xa341,0xa342,0xa343,0xa344,0xa345,0xa346,0xa347,
+ 0xa348,0xa349,0xa34a,0xa34b,0xa34c,0xa34d,0xa34e,0xa34f,
+ 0xa350,0xa351,0xa352,0xa353,0xa354,0xa355,0xa356,0xa357,
+ 0xa358,0xa359,0xa35a,0xa35b,0xa35c,0xa35d,0xa35e,0xa35f,
+ 0xa360,0xa361,0xa362,0xa363,0xa364,0xa365,0xa366,0xa367,
+ 0xa368,0xa369,0xa36a,0xa36b,0xa36c,0xa36d,0xa36e,0xa36f,
+ 0xa370,0xa371,0xa372,0xa373,0xa374,0xa375,0xa376,0xa377,
+ 0xa378,0xa379,0xa37a,0xa37b,0xa37c,0xa37d,0xa37e,0xa37f,
+ 0xa380,0xa381,0xa382,0xa383,0xa384,0xa385,0xa386,0xa387,
+ 0xa388,0xa389,0xa38a,0xa38b,0xa38c,0xa38d,0xa38e,0xa38f,
+ 0xa390,0xa391,0xa392,0xa393,0xa394,0xa395,0xa396,0xa397,
+ 0xa398,0xa399,0xa39a,0xa39b,0xa39c,0xa39d,0xa39e,0xa39f,
+ 0xa3a0,0xa3a1,0xa3a2,0xa3a3,0xa3a4,0xa3a5,0xa3a6,0xa3a7,
+ 0xa3a8,0xa3a9,0xa3aa,0xa3ab,0xa3ac,0xa3ad,0xa3ae,0xa3af,
+ 0xa3b0,0xa3b1,0xa3b2,0xa3b3,0xa3b4,0xa3b5,0xa3b6,0xa3b7,
+ 0xa3b8,0xa3b9,0xa3ba,0xa3bb,0xa3bc,0xa3bd,0xa3be,0xa3bf,
+ 0xa3c0,0xa3c1,0xa3c2,0xa3c3,0xa3c4,0xa3c5,0xa3c6,0xa3c7,
+ 0xa3c8,0xa3c9,0xa3ca,0xa3cb,0xa3cc,0xa3cd,0xa3ce,0xa3cf,
+ 0xa3d0,0xa3d1,0xa3d2,0xa3d3,0xa3d4,0xa3d5,0xa3d6,0xa3d7,
+ 0xa3d8,0xa3d9,0xa3da,0xa3db,0xa3dc,0xa3dd,0xa3de,0xa3df,
+ 0xa3e0,0xa3e1,0xa3e2,0xa3e3,0xa3e4,0xa3e5,0xa3e6,0xa3e7,
+ 0xa3e8,0xa3e9,0xa3ea,0xa3eb,0xa3ec,0xa3ed,0xa3ee,0xa3ef,
+ 0xa3f0,0xa3f1,0xa3f2,0xa3f3,0xa3f4,0xa3f5,0xa3f6,0xa3f7,
+ 0xa3f8,0xa3f9,0xa3fa,0xa3fb,0xa3fc,0xa3fd,0xa3fe,0xa3ff,
+ 0xa400,0xa401,0xa402,0xa403,0xa404,0xa405,0xa406,0xa407,
+ 0xa408,0xa409,0xa40a,0xa40b,0xa40c,0xa40d,0xa40e,0xa40f,
+ 0xa410,0xa411,0xa412,0xa413,0xa414,0xa415,0xa416,0xa417,
+ 0xa418,0xa419,0xa41a,0xa41b,0xa41c,0xa41d,0xa41e,0xa41f,
+ 0xa420,0xa421,0xa422,0xa423,0xa424,0xa425,0xa426,0xa427,
+ 0xa428,0xa429,0xa42a,0xa42b,0xa42c,0xa42d,0xa42e,0xa42f,
+ 0xa430,0xa431,0xa432,0xa433,0xa434,0xa435,0xa436,0xa437,
+ 0xa438,0xa439,0xa43a,0xa43b,0xa43c,0xa43d,0xa43e,0xa43f,
+ 0xa440,0xa441,0xa442,0xa443,0xa444,0xa445,0xa446,0xa447,
+ 0xa448,0xa449,0xa44a,0xa44b,0xa44c,0xa44d,0xa44e,0xa44f,
+ 0xa450,0xa451,0xa452,0xa453,0xa454,0xa455,0xa456,0xa457,
+ 0xa458,0xa459,0xa45a,0xa45b,0xa45c,0xa45d,0xa45e,0xa45f,
+ 0xa460,0xa461,0xa462,0xa463,0xa464,0xa465,0xa466,0xa467,
+ 0xa468,0xa469,0xa46a,0xa46b,0xa46c,0xa46d,0xa46e,0xa46f,
+ 0xa470,0xa471,0xa472,0xa473,0xa474,0xa475,0xa476,0xa477,
+ 0xa478,0xa479,0xa47a,0xa47b,0xa47c,0xa47d,0xa47e,0xa47f,
+ 0xa480,0xa481,0xa482,0xa483,0xa484,0xa485,0xa486,0xa487,
+ 0xa488,0xa489,0xa48a,0xa48b,0xa48c,0xa48d,0xa48e,0xa48f,
+ 0xa490,0xa491,0xa492,0xa493,0xa494,0xa495,0xa496,0xa497,
+ 0xa498,0xa499,0xa49a,0xa49b,0xa49c,0xa49d,0xa49e,0xa49f,
+ 0xa4a0,0xa4a1,0xa4a2,0xa4a3,0xa4a4,0xa4a5,0xa4a6,0xa4a7,
+ 0xa4a8,0xa4a9,0xa4aa,0xa4ab,0xa4ac,0xa4ad,0xa4ae,0xa4af,
+ 0xa4b0,0xa4b1,0xa4b2,0xa4b3,0xa4b4,0xa4b5,0xa4b6,0xa4b7,
+ 0xa4b8,0xa4b9,0xa4ba,0xa4bb,0xa4bc,0xa4bd,0xa4be,0xa4bf,
+ 0xa4c0,0xa4c1,0xa4c2,0xa4c3,0xa4c4,0xa4c5,0xa4c6,0xa4c7,
+ 0xa4c8,0xa4c9,0xa4ca,0xa4cb,0xa4cc,0xa4cd,0xa4ce,0xa4cf,
+ 0xa4d0,0xa4d1,0xa4d2,0xa4d3,0xa4d4,0xa4d5,0xa4d6,0xa4d7,
+ 0xa4d8,0xa4d9,0xa4da,0xa4db,0xa4dc,0xa4dd,0xa4de,0xa4df,
+ 0xa4e0,0xa4e1,0xa4e2,0xa4e3,0xa4e4,0xa4e5,0xa4e6,0xa4e7,
+ 0xa4e8,0xa4e9,0xa4ea,0xa4eb,0xa4ec,0xa4ed,0xa4ee,0xa4ef,
+ 0xa4f0,0xa4f1,0xa4f2,0xa4f3,0xa4f4,0xa4f5,0xa4f6,0xa4f7,
+ 0xa4f8,0xa4f9,0xa4fa,0xa4fb,0xa4fc,0xa4fd,0xa4fe,0xa4ff,
+ 0xa500,0xa501,0xa502,0xa503,0xa504,0xa505,0xa506,0xa507,
+ 0xa508,0xa509,0xa50a,0xa50b,0xa50c,0xa50d,0xa50e,0xa50f,
+ 0xa510,0xa511,0xa512,0xa513,0xa514,0xa515,0xa516,0xa517,
+ 0xa518,0xa519,0xa51a,0xa51b,0xa51c,0xa51d,0xa51e,0xa51f,
+ 0xa520,0xa521,0xa522,0xa523,0xa524,0xa525,0xa526,0xa527,
+ 0xa528,0xa529,0xa52a,0xa52b,0xa52c,0xa52d,0xa52e,0xa52f,
+ 0xa530,0xa531,0xa532,0xa533,0xa534,0xa535,0xa536,0xa537,
+ 0xa538,0xa539,0xa53a,0xa53b,0xa53c,0xa53d,0xa53e,0xa53f,
+ 0xa540,0xa541,0xa542,0xa543,0xa544,0xa545,0xa546,0xa547,
+ 0xa548,0xa549,0xa54a,0xa54b,0xa54c,0xa54d,0xa54e,0xa54f,
+ 0xa550,0xa551,0xa552,0xa553,0xa554,0xa555,0xa556,0xa557,
+ 0xa558,0xa559,0xa55a,0xa55b,0xa55c,0xa55d,0xa55e,0xa55f,
+ 0xa560,0xa561,0xa562,0xa563,0xa564,0xa565,0xa566,0xa567,
+ 0xa568,0xa569,0xa56a,0xa56b,0xa56c,0xa56d,0xa56e,0xa56f,
+ 0xa570,0xa571,0xa572,0xa573,0xa574,0xa575,0xa576,0xa577,
+ 0xa578,0xa579,0xa57a,0xa57b,0xa57c,0xa57d,0xa57e,0xa57f,
+ 0xa580,0xa581,0xa582,0xa583,0xa584,0xa585,0xa586,0xa587,
+ 0xa588,0xa589,0xa58a,0xa58b,0xa58c,0xa58d,0xa58e,0xa58f,
+ 0xa590,0xa591,0xa592,0xa593,0xa594,0xa595,0xa596,0xa597,
+ 0xa598,0xa599,0xa59a,0xa59b,0xa59c,0xa59d,0xa59e,0xa59f,
+ 0xa5a0,0xa5a1,0xa5a2,0xa5a3,0xa5a4,0xa5a5,0xa5a6,0xa5a7,
+ 0xa5a8,0xa5a9,0xa5aa,0xa5ab,0xa5ac,0xa5ad,0xa5ae,0xa5af,
+ 0xa5b0,0xa5b1,0xa5b2,0xa5b3,0xa5b4,0xa5b5,0xa5b6,0xa5b7,
+ 0xa5b8,0xa5b9,0xa5ba,0xa5bb,0xa5bc,0xa5bd,0xa5be,0xa5bf,
+ 0xa5c0,0xa5c1,0xa5c2,0xa5c3,0xa5c4,0xa5c5,0xa5c6,0xa5c7,
+ 0xa5c8,0xa5c9,0xa5ca,0xa5cb,0xa5cc,0xa5cd,0xa5ce,0xa5cf,
+ 0xa5d0,0xa5d1,0xa5d2,0xa5d3,0xa5d4,0xa5d5,0xa5d6,0xa5d7,
+ 0xa5d8,0xa5d9,0xa5da,0xa5db,0xa5dc,0xa5dd,0xa5de,0xa5df,
+ 0xa5e0,0xa5e1,0xa5e2,0xa5e3,0xa5e4,0xa5e5,0xa5e6,0xa5e7,
+ 0xa5e8,0xa5e9,0xa5ea,0xa5eb,0xa5ec,0xa5ed,0xa5ee,0xa5ef,
+ 0xa5f0,0xa5f1,0xa5f2,0xa5f3,0xa5f4,0xa5f5,0xa5f6,0xa5f7,
+ 0xa5f8,0xa5f9,0xa5fa,0xa5fb,0xa5fc,0xa5fd,0xa5fe,0xa5ff,
+ 0xa600,0xa601,0xa602,0xa603,0xa604,0xa605,0xa606,0xa607,
+ 0xa608,0xa609,0xa60a,0xa60b,0xa60c,0xa60d,0xa60e,0xa60f,
+ 0xa610,0xa611,0xa612,0xa613,0xa614,0xa615,0xa616,0xa617,
+ 0xa618,0xa619,0xa61a,0xa61b,0xa61c,0xa61d,0xa61e,0xa61f,
+ 0xa620,0xa621,0xa622,0xa623,0xa624,0xa625,0xa626,0xa627,
+ 0xa628,0xa629,0xa62a,0xa62b,0xa62c,0xa62d,0xa62e,0xa62f,
+ 0xa630,0xa631,0xa632,0xa633,0xa634,0xa635,0xa636,0xa637,
+ 0xa638,0xa639,0xa63a,0xa63b,0xa63c,0xa63d,0xa63e,0xa63f,
+ 0xa640,0xa641,0xa642,0xa643,0xa644,0xa645,0xa646,0xa647,
+ 0xa648,0xa649,0xa64a,0xa64b,0xa64c,0xa64d,0xa64e,0xa64f,
+ 0xa650,0xa651,0xa652,0xa653,0xa654,0xa655,0xa656,0xa657,
+ 0xa658,0xa659,0xa65a,0xa65b,0xa65c,0xa65d,0xa65e,0xa65f,
+ 0xa660,0xa661,0xa662,0xa663,0xa664,0xa665,0xa666,0xa667,
+ 0xa668,0xa669,0xa66a,0xa66b,0xa66c,0xa66d,0xa66e,0xa66f,
+ 0xa670,0xa671,0xa672,0xa673,0xa674,0xa675,0xa676,0xa677,
+ 0xa678,0xa679,0xa67a,0xa67b,0xa67c,0xa67d,0xa67e,0xa67f,
+ 0xa680,0xa681,0xa682,0xa683,0xa684,0xa685,0xa686,0xa687,
+ 0xa688,0xa689,0xa68a,0xa68b,0xa68c,0xa68d,0xa68e,0xa68f,
+ 0xa690,0xa691,0xa692,0xa693,0xa694,0xa695,0xa696,0xa697,
+ 0xa698,0xa699,0xa69a,0xa69b,0xa69c,0xa69d,0xa69e,0xa69f,
+ 0xa6a0,0xa6a1,0xa6a2,0xa6a3,0xa6a4,0xa6a5,0xa6a6,0xa6a7,
+ 0xa6a8,0xa6a9,0xa6aa,0xa6ab,0xa6ac,0xa6ad,0xa6ae,0xa6af,
+ 0xa6b0,0xa6b1,0xa6b2,0xa6b3,0xa6b4,0xa6b5,0xa6b6,0xa6b7,
+ 0xa6b8,0xa6b9,0xa6ba,0xa6bb,0xa6bc,0xa6bd,0xa6be,0xa6bf,
+ 0xa6c0,0xa6c1,0xa6c2,0xa6c3,0xa6c4,0xa6c5,0xa6c6,0xa6c7,
+ 0xa6c8,0xa6c9,0xa6ca,0xa6cb,0xa6cc,0xa6cd,0xa6ce,0xa6cf,
+ 0xa6d0,0xa6d1,0xa6d2,0xa6d3,0xa6d4,0xa6d5,0xa6d6,0xa6d7,
+ 0xa6d8,0xa6d9,0xa6da,0xa6db,0xa6dc,0xa6dd,0xa6de,0xa6df,
+ 0xa6e0,0xa6e1,0xa6e2,0xa6e3,0xa6e4,0xa6e5,0xa6e6,0xa6e7,
+ 0xa6e8,0xa6e9,0xa6ea,0xa6eb,0xa6ec,0xa6ed,0xa6ee,0xa6ef,
+ 0xa6f0,0xa6f1,0xa6f2,0xa6f3,0xa6f4,0xa6f5,0xa6f6,0xa6f7,
+ 0xa6f8,0xa6f9,0xa6fa,0xa6fb,0xa6fc,0xa6fd,0xa6fe,0xa6ff,
+ 0xa700,0xa701,0xa702,0xa703,0xa704,0xa705,0xa706,0xa707,
+ 0xa708,0xa709,0xa70a,0xa70b,0xa70c,0xa70d,0xa70e,0xa70f,
+ 0xa710,0xa711,0xa712,0xa713,0xa714,0xa715,0xa716,0xa717,
+ 0xa718,0xa719,0xa71a,0xa71b,0xa71c,0xa71d,0xa71e,0xa71f,
+ 0xa720,0xa721,0xa722,0xa723,0xa724,0xa725,0xa726,0xa727,
+ 0xa728,0xa729,0xa72a,0xa72b,0xa72c,0xa72d,0xa72e,0xa72f,
+ 0xa730,0xa731,0xa732,0xa733,0xa734,0xa735,0xa736,0xa737,
+ 0xa738,0xa739,0xa73a,0xa73b,0xa73c,0xa73d,0xa73e,0xa73f,
+ 0xa740,0xa741,0xa742,0xa743,0xa744,0xa745,0xa746,0xa747,
+ 0xa748,0xa749,0xa74a,0xa74b,0xa74c,0xa74d,0xa74e,0xa74f,
+ 0xa750,0xa751,0xa752,0xa753,0xa754,0xa755,0xa756,0xa757,
+ 0xa758,0xa759,0xa75a,0xa75b,0xa75c,0xa75d,0xa75e,0xa75f,
+ 0xa760,0xa761,0xa762,0xa763,0xa764,0xa765,0xa766,0xa767,
+ 0xa768,0xa769,0xa76a,0xa76b,0xa76c,0xa76d,0xa76e,0xa76f,
+ 0xa770,0xa771,0xa772,0xa773,0xa774,0xa775,0xa776,0xa777,
+ 0xa778,0xa779,0xa77a,0xa77b,0xa77c,0xa77d,0xa77e,0xa77f,
+ 0xa780,0xa781,0xa782,0xa783,0xa784,0xa785,0xa786,0xa787,
+ 0xa788,0xa789,0xa78a,0xa78b,0xa78c,0xa78d,0xa78e,0xa78f,
+ 0xa790,0xa791,0xa792,0xa793,0xa794,0xa795,0xa796,0xa797,
+ 0xa798,0xa799,0xa79a,0xa79b,0xa79c,0xa79d,0xa79e,0xa79f,
+ 0xa7a0,0xa7a1,0xa7a2,0xa7a3,0xa7a4,0xa7a5,0xa7a6,0xa7a7,
+ 0xa7a8,0xa7a9,0xa7aa,0xa7ab,0xa7ac,0xa7ad,0xa7ae,0xa7af,
+ 0xa7b0,0xa7b1,0xa7b2,0xa7b3,0xa7b4,0xa7b5,0xa7b6,0xa7b7,
+ 0xa7b8,0xa7b9,0xa7ba,0xa7bb,0xa7bc,0xa7bd,0xa7be,0xa7bf,
+ 0xa7c0,0xa7c1,0xa7c2,0xa7c3,0xa7c4,0xa7c5,0xa7c6,0xa7c7,
+ 0xa7c8,0xa7c9,0xa7ca,0xa7cb,0xa7cc,0xa7cd,0xa7ce,0xa7cf,
+ 0xa7d0,0xa7d1,0xa7d2,0xa7d3,0xa7d4,0xa7d5,0xa7d6,0xa7d7,
+ 0xa7d8,0xa7d9,0xa7da,0xa7db,0xa7dc,0xa7dd,0xa7de,0xa7df,
+ 0xa7e0,0xa7e1,0xa7e2,0xa7e3,0xa7e4,0xa7e5,0xa7e6,0xa7e7,
+ 0xa7e8,0xa7e9,0xa7ea,0xa7eb,0xa7ec,0xa7ed,0xa7ee,0xa7ef,
+ 0xa7f0,0xa7f1,0xa7f2,0xa7f3,0xa7f4,0xa7f5,0xa7f6,0xa7f7,
+ 0xa7f8,0xa7f9,0xa7fa,0xa7fb,0xa7fc,0xa7fd,0xa7fe,0xa7ff,
+ 0xa800,0xa801,0xa802,0xa803,0xa804,0xa805,0xa806,0xa807,
+ 0xa808,0xa809,0xa80a,0xa80b,0xa80c,0xa80d,0xa80e,0xa80f,
+ 0xa810,0xa811,0xa812,0xa813,0xa814,0xa815,0xa816,0xa817,
+ 0xa818,0xa819,0xa81a,0xa81b,0xa81c,0xa81d,0xa81e,0xa81f,
+ 0xa820,0xa821,0xa822,0xa823,0xa824,0xa825,0xa826,0xa827,
+ 0xa828,0xa829,0xa82a,0xa82b,0xa82c,0xa82d,0xa82e,0xa82f,
+ 0xa830,0xa831,0xa832,0xa833,0xa834,0xa835,0xa836,0xa837,
+ 0xa838,0xa839,0xa83a,0xa83b,0xa83c,0xa83d,0xa83e,0xa83f,
+ 0xa840,0xa841,0xa842,0xa843,0xa844,0xa845,0xa846,0xa847,
+ 0xa848,0xa849,0xa84a,0xa84b,0xa84c,0xa84d,0xa84e,0xa84f,
+ 0xa850,0xa851,0xa852,0xa853,0xa854,0xa855,0xa856,0xa857,
+ 0xa858,0xa859,0xa85a,0xa85b,0xa85c,0xa85d,0xa85e,0xa85f,
+ 0xa860,0xa861,0xa862,0xa863,0xa864,0xa865,0xa866,0xa867,
+ 0xa868,0xa869,0xa86a,0xa86b,0xa86c,0xa86d,0xa86e,0xa86f,
+ 0xa870,0xa871,0xa872,0xa873,0xa874,0xa875,0xa876,0xa877,
+ 0xa878,0xa879,0xa87a,0xa87b,0xa87c,0xa87d,0xa87e,0xa87f,
+ 0xa880,0xa881,0xa882,0xa883,0xa884,0xa885,0xa886,0xa887,
+ 0xa888,0xa889,0xa88a,0xa88b,0xa88c,0xa88d,0xa88e,0xa88f,
+ 0xa890,0xa891,0xa892,0xa893,0xa894,0xa895,0xa896,0xa897,
+ 0xa898,0xa899,0xa89a,0xa89b,0xa89c,0xa89d,0xa89e,0xa89f,
+ 0xa8a0,0xa8a1,0xa8a2,0xa8a3,0xa8a4,0xa8a5,0xa8a6,0xa8a7,
+ 0xa8a8,0xa8a9,0xa8aa,0xa8ab,0xa8ac,0xa8ad,0xa8ae,0xa8af,
+ 0xa8b0,0xa8b1,0xa8b2,0xa8b3,0xa8b4,0xa8b5,0xa8b6,0xa8b7,
+ 0xa8b8,0xa8b9,0xa8ba,0xa8bb,0xa8bc,0xa8bd,0xa8be,0xa8bf,
+ 0xa8c0,0xa8c1,0xa8c2,0xa8c3,0xa8c4,0xa8c5,0xa8c6,0xa8c7,
+ 0xa8c8,0xa8c9,0xa8ca,0xa8cb,0xa8cc,0xa8cd,0xa8ce,0xa8cf,
+ 0xa8d0,0xa8d1,0xa8d2,0xa8d3,0xa8d4,0xa8d5,0xa8d6,0xa8d7,
+ 0xa8d8,0xa8d9,0xa8da,0xa8db,0xa8dc,0xa8dd,0xa8de,0xa8df,
+ 0xa8e0,0xa8e1,0xa8e2,0xa8e3,0xa8e4,0xa8e5,0xa8e6,0xa8e7,
+ 0xa8e8,0xa8e9,0xa8ea,0xa8eb,0xa8ec,0xa8ed,0xa8ee,0xa8ef,
+ 0xa8f0,0xa8f1,0xa8f2,0xa8f3,0xa8f4,0xa8f5,0xa8f6,0xa8f7,
+ 0xa8f8,0xa8f9,0xa8fa,0xa8fb,0xa8fc,0xa8fd,0xa8fe,0xa8ff,
+ 0xa900,0xa901,0xa902,0xa903,0xa904,0xa905,0xa906,0xa907,
+ 0xa908,0xa909,0xa90a,0xa90b,0xa90c,0xa90d,0xa90e,0xa90f,
+ 0xa910,0xa911,0xa912,0xa913,0xa914,0xa915,0xa916,0xa917,
+ 0xa918,0xa919,0xa91a,0xa91b,0xa91c,0xa91d,0xa91e,0xa91f,
+ 0xa920,0xa921,0xa922,0xa923,0xa924,0xa925,0xa926,0xa927,
+ 0xa928,0xa929,0xa92a,0xa92b,0xa92c,0xa92d,0xa92e,0xa92f,
+ 0xa930,0xa931,0xa932,0xa933,0xa934,0xa935,0xa936,0xa937,
+ 0xa938,0xa939,0xa93a,0xa93b,0xa93c,0xa93d,0xa93e,0xa93f,
+ 0xa940,0xa941,0xa942,0xa943,0xa944,0xa945,0xa946,0xa947,
+ 0xa948,0xa949,0xa94a,0xa94b,0xa94c,0xa94d,0xa94e,0xa94f,
+ 0xa950,0xa951,0xa952,0xa953,0xa954,0xa955,0xa956,0xa957,
+ 0xa958,0xa959,0xa95a,0xa95b,0xa95c,0xa95d,0xa95e,0xa95f,
+ 0xa960,0xa961,0xa962,0xa963,0xa964,0xa965,0xa966,0xa967,
+ 0xa968,0xa969,0xa96a,0xa96b,0xa96c,0xa96d,0xa96e,0xa96f,
+ 0xa970,0xa971,0xa972,0xa973,0xa974,0xa975,0xa976,0xa977,
+ 0xa978,0xa979,0xa97a,0xa97b,0xa97c,0xa97d,0xa97e,0xa97f,
+ 0xa980,0xa981,0xa982,0xa983,0xa984,0xa985,0xa986,0xa987,
+ 0xa988,0xa989,0xa98a,0xa98b,0xa98c,0xa98d,0xa98e,0xa98f,
+ 0xa990,0xa991,0xa992,0xa993,0xa994,0xa995,0xa996,0xa997,
+ 0xa998,0xa999,0xa99a,0xa99b,0xa99c,0xa99d,0xa99e,0xa99f,
+ 0xa9a0,0xa9a1,0xa9a2,0xa9a3,0xa9a4,0xa9a5,0xa9a6,0xa9a7,
+ 0xa9a8,0xa9a9,0xa9aa,0xa9ab,0xa9ac,0xa9ad,0xa9ae,0xa9af,
+ 0xa9b0,0xa9b1,0xa9b2,0xa9b3,0xa9b4,0xa9b5,0xa9b6,0xa9b7,
+ 0xa9b8,0xa9b9,0xa9ba,0xa9bb,0xa9bc,0xa9bd,0xa9be,0xa9bf,
+ 0xa9c0,0xa9c1,0xa9c2,0xa9c3,0xa9c4,0xa9c5,0xa9c6,0xa9c7,
+ 0xa9c8,0xa9c9,0xa9ca,0xa9cb,0xa9cc,0xa9cd,0xa9ce,0xa9cf,
+ 0xa9d0,0xa9d1,0xa9d2,0xa9d3,0xa9d4,0xa9d5,0xa9d6,0xa9d7,
+ 0xa9d8,0xa9d9,0xa9da,0xa9db,0xa9dc,0xa9dd,0xa9de,0xa9df,
+ 0xa9e0,0xa9e1,0xa9e2,0xa9e3,0xa9e4,0xa9e5,0xa9e6,0xa9e7,
+ 0xa9e8,0xa9e9,0xa9ea,0xa9eb,0xa9ec,0xa9ed,0xa9ee,0xa9ef,
+ 0xa9f0,0xa9f1,0xa9f2,0xa9f3,0xa9f4,0xa9f5,0xa9f6,0xa9f7,
+ 0xa9f8,0xa9f9,0xa9fa,0xa9fb,0xa9fc,0xa9fd,0xa9fe,0xa9ff,
+ 0xaa00,0xaa01,0xaa02,0xaa03,0xaa04,0xaa05,0xaa06,0xaa07,
+ 0xaa08,0xaa09,0xaa0a,0xaa0b,0xaa0c,0xaa0d,0xaa0e,0xaa0f,
+ 0xaa10,0xaa11,0xaa12,0xaa13,0xaa14,0xaa15,0xaa16,0xaa17,
+ 0xaa18,0xaa19,0xaa1a,0xaa1b,0xaa1c,0xaa1d,0xaa1e,0xaa1f,
+ 0xaa20,0xaa21,0xaa22,0xaa23,0xaa24,0xaa25,0xaa26,0xaa27,
+ 0xaa28,0xaa29,0xaa2a,0xaa2b,0xaa2c,0xaa2d,0xaa2e,0xaa2f,
+ 0xaa30,0xaa31,0xaa32,0xaa33,0xaa34,0xaa35,0xaa36,0xaa37,
+ 0xaa38,0xaa39,0xaa3a,0xaa3b,0xaa3c,0xaa3d,0xaa3e,0xaa3f,
+ 0xaa40,0xaa41,0xaa42,0xaa43,0xaa44,0xaa45,0xaa46,0xaa47,
+ 0xaa48,0xaa49,0xaa4a,0xaa4b,0xaa4c,0xaa4d,0xaa4e,0xaa4f,
+ 0xaa50,0xaa51,0xaa52,0xaa53,0xaa54,0xaa55,0xaa56,0xaa57,
+ 0xaa58,0xaa59,0xaa5a,0xaa5b,0xaa5c,0xaa5d,0xaa5e,0xaa5f,
+ 0xaa60,0xaa61,0xaa62,0xaa63,0xaa64,0xaa65,0xaa66,0xaa67,
+ 0xaa68,0xaa69,0xaa6a,0xaa6b,0xaa6c,0xaa6d,0xaa6e,0xaa6f,
+ 0xaa70,0xaa71,0xaa72,0xaa73,0xaa74,0xaa75,0xaa76,0xaa77,
+ 0xaa78,0xaa79,0xaa7a,0xaa7b,0xaa7c,0xaa7d,0xaa7e,0xaa7f,
+ 0xaa80,0xaa81,0xaa82,0xaa83,0xaa84,0xaa85,0xaa86,0xaa87,
+ 0xaa88,0xaa89,0xaa8a,0xaa8b,0xaa8c,0xaa8d,0xaa8e,0xaa8f,
+ 0xaa90,0xaa91,0xaa92,0xaa93,0xaa94,0xaa95,0xaa96,0xaa97,
+ 0xaa98,0xaa99,0xaa9a,0xaa9b,0xaa9c,0xaa9d,0xaa9e,0xaa9f,
+ 0xaaa0,0xaaa1,0xaaa2,0xaaa3,0xaaa4,0xaaa5,0xaaa6,0xaaa7,
+ 0xaaa8,0xaaa9,0xaaaa,0xaaab,0xaaac,0xaaad,0xaaae,0xaaaf,
+ 0xaab0,0xaab1,0xaab2,0xaab3,0xaab4,0xaab5,0xaab6,0xaab7,
+ 0xaab8,0xaab9,0xaaba,0xaabb,0xaabc,0xaabd,0xaabe,0xaabf,
+ 0xaac0,0xaac1,0xaac2,0xaac3,0xaac4,0xaac5,0xaac6,0xaac7,
+ 0xaac8,0xaac9,0xaaca,0xaacb,0xaacc,0xaacd,0xaace,0xaacf,
+ 0xaad0,0xaad1,0xaad2,0xaad3,0xaad4,0xaad5,0xaad6,0xaad7,
+ 0xaad8,0xaad9,0xaada,0xaadb,0xaadc,0xaadd,0xaade,0xaadf,
+ 0xaae0,0xaae1,0xaae2,0xaae3,0xaae4,0xaae5,0xaae6,0xaae7,
+ 0xaae8,0xaae9,0xaaea,0xaaeb,0xaaec,0xaaed,0xaaee,0xaaef,
+ 0xaaf0,0xaaf1,0xaaf2,0xaaf3,0xaaf4,0xaaf5,0xaaf6,0xaaf7,
+ 0xaaf8,0xaaf9,0xaafa,0xaafb,0xaafc,0xaafd,0xaafe,0xaaff,
+ 0xab00,0xab01,0xab02,0xab03,0xab04,0xab05,0xab06,0xab07,
+ 0xab08,0xab09,0xab0a,0xab0b,0xab0c,0xab0d,0xab0e,0xab0f,
+ 0xab10,0xab11,0xab12,0xab13,0xab14,0xab15,0xab16,0xab17,
+ 0xab18,0xab19,0xab1a,0xab1b,0xab1c,0xab1d,0xab1e,0xab1f,
+ 0xab20,0xab21,0xab22,0xab23,0xab24,0xab25,0xab26,0xab27,
+ 0xab28,0xab29,0xab2a,0xab2b,0xab2c,0xab2d,0xab2e,0xab2f,
+ 0xab30,0xab31,0xab32,0xab33,0xab34,0xab35,0xab36,0xab37,
+ 0xab38,0xab39,0xab3a,0xab3b,0xab3c,0xab3d,0xab3e,0xab3f,
+ 0xab40,0xab41,0xab42,0xab43,0xab44,0xab45,0xab46,0xab47,
+ 0xab48,0xab49,0xab4a,0xab4b,0xab4c,0xab4d,0xab4e,0xab4f,
+ 0xab50,0xab51,0xab52,0xab53,0xab54,0xab55,0xab56,0xab57,
+ 0xab58,0xab59,0xab5a,0xab5b,0xab5c,0xab5d,0xab5e,0xab5f,
+ 0xab60,0xab61,0xab62,0xab63,0xab64,0xab65,0xab66,0xab67,
+ 0xab68,0xab69,0xab6a,0xab6b,0xab6c,0xab6d,0xab6e,0xab6f,
+ 0xab70,0xab71,0xab72,0xab73,0xab74,0xab75,0xab76,0xab77,
+ 0xab78,0xab79,0xab7a,0xab7b,0xab7c,0xab7d,0xab7e,0xab7f,
+ 0xab80,0xab81,0xab82,0xab83,0xab84,0xab85,0xab86,0xab87,
+ 0xab88,0xab89,0xab8a,0xab8b,0xab8c,0xab8d,0xab8e,0xab8f,
+ 0xab90,0xab91,0xab92,0xab93,0xab94,0xab95,0xab96,0xab97,
+ 0xab98,0xab99,0xab9a,0xab9b,0xab9c,0xab9d,0xab9e,0xab9f,
+ 0xaba0,0xaba1,0xaba2,0xaba3,0xaba4,0xaba5,0xaba6,0xaba7,
+ 0xaba8,0xaba9,0xabaa,0xabab,0xabac,0xabad,0xabae,0xabaf,
+ 0xabb0,0xabb1,0xabb2,0xabb3,0xabb4,0xabb5,0xabb6,0xabb7,
+ 0xabb8,0xabb9,0xabba,0xabbb,0xabbc,0xabbd,0xabbe,0xabbf,
+ 0xabc0,0xabc1,0xabc2,0xabc3,0xabc4,0xabc5,0xabc6,0xabc7,
+ 0xabc8,0xabc9,0xabca,0xabcb,0xabcc,0xabcd,0xabce,0xabcf,
+ 0xabd0,0xabd1,0xabd2,0xabd3,0xabd4,0xabd5,0xabd6,0xabd7,
+ 0xabd8,0xabd9,0xabda,0xabdb,0xabdc,0xabdd,0xabde,0xabdf,
+ 0xabe0,0xabe1,0xabe2,0xabe3,0xabe4,0xabe5,0xabe6,0xabe7,
+ 0xabe8,0xabe9,0xabea,0xabeb,0xabec,0xabed,0xabee,0xabef,
+ 0xabf0,0xabf1,0xabf2,0xabf3,0xabf4,0xabf5,0xabf6,0xabf7,
+ 0xabf8,0xabf9,0xabfa,0xabfb,0xabfc,0xabfd,0xabfe,0xabff,
+ 0xac00,0xac01,0xac02,0xac03,0xac04,0xac05,0xac06,0xac07,
+ 0xac08,0xac09,0xac0a,0xac0b,0xac0c,0xac0d,0xac0e,0xac0f,
+ 0xac10,0xac11,0xac12,0xac13,0xac14,0xac15,0xac16,0xac17,
+ 0xac18,0xac19,0xac1a,0xac1b,0xac1c,0xac1d,0xac1e,0xac1f,
+ 0xac20,0xac21,0xac22,0xac23,0xac24,0xac25,0xac26,0xac27,
+ 0xac28,0xac29,0xac2a,0xac2b,0xac2c,0xac2d,0xac2e,0xac2f,
+ 0xac30,0xac31,0xac32,0xac33,0xac34,0xac35,0xac36,0xac37,
+ 0xac38,0xac39,0xac3a,0xac3b,0xac3c,0xac3d,0xac3e,0xac3f,
+ 0xac40,0xac41,0xac42,0xac43,0xac44,0xac45,0xac46,0xac47,
+ 0xac48,0xac49,0xac4a,0xac4b,0xac4c,0xac4d,0xac4e,0xac4f,
+ 0xac50,0xac51,0xac52,0xac53,0xac54,0xac55,0xac56,0xac57,
+ 0xac58,0xac59,0xac5a,0xac5b,0xac5c,0xac5d,0xac5e,0xac5f,
+ 0xac60,0xac61,0xac62,0xac63,0xac64,0xac65,0xac66,0xac67,
+ 0xac68,0xac69,0xac6a,0xac6b,0xac6c,0xac6d,0xac6e,0xac6f,
+ 0xac70,0xac71,0xac72,0xac73,0xac74,0xac75,0xac76,0xac77,
+ 0xac78,0xac79,0xac7a,0xac7b,0xac7c,0xac7d,0xac7e,0xac7f,
+ 0xac80,0xac81,0xac82,0xac83,0xac84,0xac85,0xac86,0xac87,
+ 0xac88,0xac89,0xac8a,0xac8b,0xac8c,0xac8d,0xac8e,0xac8f,
+ 0xac90,0xac91,0xac92,0xac93,0xac94,0xac95,0xac96,0xac97,
+ 0xac98,0xac99,0xac9a,0xac9b,0xac9c,0xac9d,0xac9e,0xac9f,
+ 0xaca0,0xaca1,0xaca2,0xaca3,0xaca4,0xaca5,0xaca6,0xaca7,
+ 0xaca8,0xaca9,0xacaa,0xacab,0xacac,0xacad,0xacae,0xacaf,
+ 0xacb0,0xacb1,0xacb2,0xacb3,0xacb4,0xacb5,0xacb6,0xacb7,
+ 0xacb8,0xacb9,0xacba,0xacbb,0xacbc,0xacbd,0xacbe,0xacbf,
+ 0xacc0,0xacc1,0xacc2,0xacc3,0xacc4,0xacc5,0xacc6,0xacc7,
+ 0xacc8,0xacc9,0xacca,0xaccb,0xaccc,0xaccd,0xacce,0xaccf,
+ 0xacd0,0xacd1,0xacd2,0xacd3,0xacd4,0xacd5,0xacd6,0xacd7,
+ 0xacd8,0xacd9,0xacda,0xacdb,0xacdc,0xacdd,0xacde,0xacdf,
+ 0xace0,0xace1,0xace2,0xace3,0xace4,0xace5,0xace6,0xace7,
+ 0xace8,0xace9,0xacea,0xaceb,0xacec,0xaced,0xacee,0xacef,
+ 0xacf0,0xacf1,0xacf2,0xacf3,0xacf4,0xacf5,0xacf6,0xacf7,
+ 0xacf8,0xacf9,0xacfa,0xacfb,0xacfc,0xacfd,0xacfe,0xacff,
+ 0xad00,0xad01,0xad02,0xad03,0xad04,0xad05,0xad06,0xad07,
+ 0xad08,0xad09,0xad0a,0xad0b,0xad0c,0xad0d,0xad0e,0xad0f,
+ 0xad10,0xad11,0xad12,0xad13,0xad14,0xad15,0xad16,0xad17,
+ 0xad18,0xad19,0xad1a,0xad1b,0xad1c,0xad1d,0xad1e,0xad1f,
+ 0xad20,0xad21,0xad22,0xad23,0xad24,0xad25,0xad26,0xad27,
+ 0xad28,0xad29,0xad2a,0xad2b,0xad2c,0xad2d,0xad2e,0xad2f,
+ 0xad30,0xad31,0xad32,0xad33,0xad34,0xad35,0xad36,0xad37,
+ 0xad38,0xad39,0xad3a,0xad3b,0xad3c,0xad3d,0xad3e,0xad3f,
+ 0xad40,0xad41,0xad42,0xad43,0xad44,0xad45,0xad46,0xad47,
+ 0xad48,0xad49,0xad4a,0xad4b,0xad4c,0xad4d,0xad4e,0xad4f,
+ 0xad50,0xad51,0xad52,0xad53,0xad54,0xad55,0xad56,0xad57,
+ 0xad58,0xad59,0xad5a,0xad5b,0xad5c,0xad5d,0xad5e,0xad5f,
+ 0xad60,0xad61,0xad62,0xad63,0xad64,0xad65,0xad66,0xad67,
+ 0xad68,0xad69,0xad6a,0xad6b,0xad6c,0xad6d,0xad6e,0xad6f,
+ 0xad70,0xad71,0xad72,0xad73,0xad74,0xad75,0xad76,0xad77,
+ 0xad78,0xad79,0xad7a,0xad7b,0xad7c,0xad7d,0xad7e,0xad7f,
+ 0xad80,0xad81,0xad82,0xad83,0xad84,0xad85,0xad86,0xad87,
+ 0xad88,0xad89,0xad8a,0xad8b,0xad8c,0xad8d,0xad8e,0xad8f,
+ 0xad90,0xad91,0xad92,0xad93,0xad94,0xad95,0xad96,0xad97,
+ 0xad98,0xad99,0xad9a,0xad9b,0xad9c,0xad9d,0xad9e,0xad9f,
+ 0xada0,0xada1,0xada2,0xada3,0xada4,0xada5,0xada6,0xada7,
+ 0xada8,0xada9,0xadaa,0xadab,0xadac,0xadad,0xadae,0xadaf,
+ 0xadb0,0xadb1,0xadb2,0xadb3,0xadb4,0xadb5,0xadb6,0xadb7,
+ 0xadb8,0xadb9,0xadba,0xadbb,0xadbc,0xadbd,0xadbe,0xadbf,
+ 0xadc0,0xadc1,0xadc2,0xadc3,0xadc4,0xadc5,0xadc6,0xadc7,
+ 0xadc8,0xadc9,0xadca,0xadcb,0xadcc,0xadcd,0xadce,0xadcf,
+ 0xadd0,0xadd1,0xadd2,0xadd3,0xadd4,0xadd5,0xadd6,0xadd7,
+ 0xadd8,0xadd9,0xadda,0xaddb,0xaddc,0xaddd,0xadde,0xaddf,
+ 0xade0,0xade1,0xade2,0xade3,0xade4,0xade5,0xade6,0xade7,
+ 0xade8,0xade9,0xadea,0xadeb,0xadec,0xaded,0xadee,0xadef,
+ 0xadf0,0xadf1,0xadf2,0xadf3,0xadf4,0xadf5,0xadf6,0xadf7,
+ 0xadf8,0xadf9,0xadfa,0xadfb,0xadfc,0xadfd,0xadfe,0xadff,
+ 0xae00,0xae01,0xae02,0xae03,0xae04,0xae05,0xae06,0xae07,
+ 0xae08,0xae09,0xae0a,0xae0b,0xae0c,0xae0d,0xae0e,0xae0f,
+ 0xae10,0xae11,0xae12,0xae13,0xae14,0xae15,0xae16,0xae17,
+ 0xae18,0xae19,0xae1a,0xae1b,0xae1c,0xae1d,0xae1e,0xae1f,
+ 0xae20,0xae21,0xae22,0xae23,0xae24,0xae25,0xae26,0xae27,
+ 0xae28,0xae29,0xae2a,0xae2b,0xae2c,0xae2d,0xae2e,0xae2f,
+ 0xae30,0xae31,0xae32,0xae33,0xae34,0xae35,0xae36,0xae37,
+ 0xae38,0xae39,0xae3a,0xae3b,0xae3c,0xae3d,0xae3e,0xae3f,
+ 0xae40,0xae41,0xae42,0xae43,0xae44,0xae45,0xae46,0xae47,
+ 0xae48,0xae49,0xae4a,0xae4b,0xae4c,0xae4d,0xae4e,0xae4f,
+ 0xae50,0xae51,0xae52,0xae53,0xae54,0xae55,0xae56,0xae57,
+ 0xae58,0xae59,0xae5a,0xae5b,0xae5c,0xae5d,0xae5e,0xae5f,
+ 0xae60,0xae61,0xae62,0xae63,0xae64,0xae65,0xae66,0xae67,
+ 0xae68,0xae69,0xae6a,0xae6b,0xae6c,0xae6d,0xae6e,0xae6f,
+ 0xae70,0xae71,0xae72,0xae73,0xae74,0xae75,0xae76,0xae77,
+ 0xae78,0xae79,0xae7a,0xae7b,0xae7c,0xae7d,0xae7e,0xae7f,
+ 0xae80,0xae81,0xae82,0xae83,0xae84,0xae85,0xae86,0xae87,
+ 0xae88,0xae89,0xae8a,0xae8b,0xae8c,0xae8d,0xae8e,0xae8f,
+ 0xae90,0xae91,0xae92,0xae93,0xae94,0xae95,0xae96,0xae97,
+ 0xae98,0xae99,0xae9a,0xae9b,0xae9c,0xae9d,0xae9e,0xae9f,
+ 0xaea0,0xaea1,0xaea2,0xaea3,0xaea4,0xaea5,0xaea6,0xaea7,
+ 0xaea8,0xaea9,0xaeaa,0xaeab,0xaeac,0xaead,0xaeae,0xaeaf,
+ 0xaeb0,0xaeb1,0xaeb2,0xaeb3,0xaeb4,0xaeb5,0xaeb6,0xaeb7,
+ 0xaeb8,0xaeb9,0xaeba,0xaebb,0xaebc,0xaebd,0xaebe,0xaebf,
+ 0xaec0,0xaec1,0xaec2,0xaec3,0xaec4,0xaec5,0xaec6,0xaec7,
+ 0xaec8,0xaec9,0xaeca,0xaecb,0xaecc,0xaecd,0xaece,0xaecf,
+ 0xaed0,0xaed1,0xaed2,0xaed3,0xaed4,0xaed5,0xaed6,0xaed7,
+ 0xaed8,0xaed9,0xaeda,0xaedb,0xaedc,0xaedd,0xaede,0xaedf,
+ 0xaee0,0xaee1,0xaee2,0xaee3,0xaee4,0xaee5,0xaee6,0xaee7,
+ 0xaee8,0xaee9,0xaeea,0xaeeb,0xaeec,0xaeed,0xaeee,0xaeef,
+ 0xaef0,0xaef1,0xaef2,0xaef3,0xaef4,0xaef5,0xaef6,0xaef7,
+ 0xaef8,0xaef9,0xaefa,0xaefb,0xaefc,0xaefd,0xaefe,0xaeff,
+ 0xaf00,0xaf01,0xaf02,0xaf03,0xaf04,0xaf05,0xaf06,0xaf07,
+ 0xaf08,0xaf09,0xaf0a,0xaf0b,0xaf0c,0xaf0d,0xaf0e,0xaf0f,
+ 0xaf10,0xaf11,0xaf12,0xaf13,0xaf14,0xaf15,0xaf16,0xaf17,
+ 0xaf18,0xaf19,0xaf1a,0xaf1b,0xaf1c,0xaf1d,0xaf1e,0xaf1f,
+ 0xaf20,0xaf21,0xaf22,0xaf23,0xaf24,0xaf25,0xaf26,0xaf27,
+ 0xaf28,0xaf29,0xaf2a,0xaf2b,0xaf2c,0xaf2d,0xaf2e,0xaf2f,
+ 0xaf30,0xaf31,0xaf32,0xaf33,0xaf34,0xaf35,0xaf36,0xaf37,
+ 0xaf38,0xaf39,0xaf3a,0xaf3b,0xaf3c,0xaf3d,0xaf3e,0xaf3f,
+ 0xaf40,0xaf41,0xaf42,0xaf43,0xaf44,0xaf45,0xaf46,0xaf47,
+ 0xaf48,0xaf49,0xaf4a,0xaf4b,0xaf4c,0xaf4d,0xaf4e,0xaf4f,
+ 0xaf50,0xaf51,0xaf52,0xaf53,0xaf54,0xaf55,0xaf56,0xaf57,
+ 0xaf58,0xaf59,0xaf5a,0xaf5b,0xaf5c,0xaf5d,0xaf5e,0xaf5f,
+ 0xaf60,0xaf61,0xaf62,0xaf63,0xaf64,0xaf65,0xaf66,0xaf67,
+ 0xaf68,0xaf69,0xaf6a,0xaf6b,0xaf6c,0xaf6d,0xaf6e,0xaf6f,
+ 0xaf70,0xaf71,0xaf72,0xaf73,0xaf74,0xaf75,0xaf76,0xaf77,
+ 0xaf78,0xaf79,0xaf7a,0xaf7b,0xaf7c,0xaf7d,0xaf7e,0xaf7f,
+ 0xaf80,0xaf81,0xaf82,0xaf83,0xaf84,0xaf85,0xaf86,0xaf87,
+ 0xaf88,0xaf89,0xaf8a,0xaf8b,0xaf8c,0xaf8d,0xaf8e,0xaf8f,
+ 0xaf90,0xaf91,0xaf92,0xaf93,0xaf94,0xaf95,0xaf96,0xaf97,
+ 0xaf98,0xaf99,0xaf9a,0xaf9b,0xaf9c,0xaf9d,0xaf9e,0xaf9f,
+ 0xafa0,0xafa1,0xafa2,0xafa3,0xafa4,0xafa5,0xafa6,0xafa7,
+ 0xafa8,0xafa9,0xafaa,0xafab,0xafac,0xafad,0xafae,0xafaf,
+ 0xafb0,0xafb1,0xafb2,0xafb3,0xafb4,0xafb5,0xafb6,0xafb7,
+ 0xafb8,0xafb9,0xafba,0xafbb,0xafbc,0xafbd,0xafbe,0xafbf,
+ 0xafc0,0xafc1,0xafc2,0xafc3,0xafc4,0xafc5,0xafc6,0xafc7,
+ 0xafc8,0xafc9,0xafca,0xafcb,0xafcc,0xafcd,0xafce,0xafcf,
+ 0xafd0,0xafd1,0xafd2,0xafd3,0xafd4,0xafd5,0xafd6,0xafd7,
+ 0xafd8,0xafd9,0xafda,0xafdb,0xafdc,0xafdd,0xafde,0xafdf,
+ 0xafe0,0xafe1,0xafe2,0xafe3,0xafe4,0xafe5,0xafe6,0xafe7,
+ 0xafe8,0xafe9,0xafea,0xafeb,0xafec,0xafed,0xafee,0xafef,
+ 0xaff0,0xaff1,0xaff2,0xaff3,0xaff4,0xaff5,0xaff6,0xaff7,
+ 0xaff8,0xaff9,0xaffa,0xaffb,0xaffc,0xaffd,0xaffe,0xafff,
+ 0xb000,0xb001,0xb002,0xb003,0xb004,0xb005,0xb006,0xb007,
+ 0xb008,0xb009,0xb00a,0xb00b,0xb00c,0xb00d,0xb00e,0xb00f,
+ 0xb010,0xb011,0xb012,0xb013,0xb014,0xb015,0xb016,0xb017,
+ 0xb018,0xb019,0xb01a,0xb01b,0xb01c,0xb01d,0xb01e,0xb01f,
+ 0xb020,0xb021,0xb022,0xb023,0xb024,0xb025,0xb026,0xb027,
+ 0xb028,0xb029,0xb02a,0xb02b,0xb02c,0xb02d,0xb02e,0xb02f,
+ 0xb030,0xb031,0xb032,0xb033,0xb034,0xb035,0xb036,0xb037,
+ 0xb038,0xb039,0xb03a,0xb03b,0xb03c,0xb03d,0xb03e,0xb03f,
+ 0xb040,0xb041,0xb042,0xb043,0xb044,0xb045,0xb046,0xb047,
+ 0xb048,0xb049,0xb04a,0xb04b,0xb04c,0xb04d,0xb04e,0xb04f,
+ 0xb050,0xb051,0xb052,0xb053,0xb054,0xb055,0xb056,0xb057,
+ 0xb058,0xb059,0xb05a,0xb05b,0xb05c,0xb05d,0xb05e,0xb05f,
+ 0xb060,0xb061,0xb062,0xb063,0xb064,0xb065,0xb066,0xb067,
+ 0xb068,0xb069,0xb06a,0xb06b,0xb06c,0xb06d,0xb06e,0xb06f,
+ 0xb070,0xb071,0xb072,0xb073,0xb074,0xb075,0xb076,0xb077,
+ 0xb078,0xb079,0xb07a,0xb07b,0xb07c,0xb07d,0xb07e,0xb07f,
+ 0xb080,0xb081,0xb082,0xb083,0xb084,0xb085,0xb086,0xb087,
+ 0xb088,0xb089,0xb08a,0xb08b,0xb08c,0xb08d,0xb08e,0xb08f,
+ 0xb090,0xb091,0xb092,0xb093,0xb094,0xb095,0xb096,0xb097,
+ 0xb098,0xb099,0xb09a,0xb09b,0xb09c,0xb09d,0xb09e,0xb09f,
+ 0xb0a0,0xb0a1,0xb0a2,0xb0a3,0xb0a4,0xb0a5,0xb0a6,0xb0a7,
+ 0xb0a8,0xb0a9,0xb0aa,0xb0ab,0xb0ac,0xb0ad,0xb0ae,0xb0af,
+ 0xb0b0,0xb0b1,0xb0b2,0xb0b3,0xb0b4,0xb0b5,0xb0b6,0xb0b7,
+ 0xb0b8,0xb0b9,0xb0ba,0xb0bb,0xb0bc,0xb0bd,0xb0be,0xb0bf,
+ 0xb0c0,0xb0c1,0xb0c2,0xb0c3,0xb0c4,0xb0c5,0xb0c6,0xb0c7,
+ 0xb0c8,0xb0c9,0xb0ca,0xb0cb,0xb0cc,0xb0cd,0xb0ce,0xb0cf,
+ 0xb0d0,0xb0d1,0xb0d2,0xb0d3,0xb0d4,0xb0d5,0xb0d6,0xb0d7,
+ 0xb0d8,0xb0d9,0xb0da,0xb0db,0xb0dc,0xb0dd,0xb0de,0xb0df,
+ 0xb0e0,0xb0e1,0xb0e2,0xb0e3,0xb0e4,0xb0e5,0xb0e6,0xb0e7,
+ 0xb0e8,0xb0e9,0xb0ea,0xb0eb,0xb0ec,0xb0ed,0xb0ee,0xb0ef,
+ 0xb0f0,0xb0f1,0xb0f2,0xb0f3,0xb0f4,0xb0f5,0xb0f6,0xb0f7,
+ 0xb0f8,0xb0f9,0xb0fa,0xb0fb,0xb0fc,0xb0fd,0xb0fe,0xb0ff,
+ 0xb100,0xb101,0xb102,0xb103,0xb104,0xb105,0xb106,0xb107,
+ 0xb108,0xb109,0xb10a,0xb10b,0xb10c,0xb10d,0xb10e,0xb10f,
+ 0xb110,0xb111,0xb112,0xb113,0xb114,0xb115,0xb116,0xb117,
+ 0xb118,0xb119,0xb11a,0xb11b,0xb11c,0xb11d,0xb11e,0xb11f,
+ 0xb120,0xb121,0xb122,0xb123,0xb124,0xb125,0xb126,0xb127,
+ 0xb128,0xb129,0xb12a,0xb12b,0xb12c,0xb12d,0xb12e,0xb12f,
+ 0xb130,0xb131,0xb132,0xb133,0xb134,0xb135,0xb136,0xb137,
+ 0xb138,0xb139,0xb13a,0xb13b,0xb13c,0xb13d,0xb13e,0xb13f,
+ 0xb140,0xb141,0xb142,0xb143,0xb144,0xb145,0xb146,0xb147,
+ 0xb148,0xb149,0xb14a,0xb14b,0xb14c,0xb14d,0xb14e,0xb14f,
+ 0xb150,0xb151,0xb152,0xb153,0xb154,0xb155,0xb156,0xb157,
+ 0xb158,0xb159,0xb15a,0xb15b,0xb15c,0xb15d,0xb15e,0xb15f,
+ 0xb160,0xb161,0xb162,0xb163,0xb164,0xb165,0xb166,0xb167,
+ 0xb168,0xb169,0xb16a,0xb16b,0xb16c,0xb16d,0xb16e,0xb16f,
+ 0xb170,0xb171,0xb172,0xb173,0xb174,0xb175,0xb176,0xb177,
+ 0xb178,0xb179,0xb17a,0xb17b,0xb17c,0xb17d,0xb17e,0xb17f,
+ 0xb180,0xb181,0xb182,0xb183,0xb184,0xb185,0xb186,0xb187,
+ 0xb188,0xb189,0xb18a,0xb18b,0xb18c,0xb18d,0xb18e,0xb18f,
+ 0xb190,0xb191,0xb192,0xb193,0xb194,0xb195,0xb196,0xb197,
+ 0xb198,0xb199,0xb19a,0xb19b,0xb19c,0xb19d,0xb19e,0xb19f,
+ 0xb1a0,0xb1a1,0xb1a2,0xb1a3,0xb1a4,0xb1a5,0xb1a6,0xb1a7,
+ 0xb1a8,0xb1a9,0xb1aa,0xb1ab,0xb1ac,0xb1ad,0xb1ae,0xb1af,
+ 0xb1b0,0xb1b1,0xb1b2,0xb1b3,0xb1b4,0xb1b5,0xb1b6,0xb1b7,
+ 0xb1b8,0xb1b9,0xb1ba,0xb1bb,0xb1bc,0xb1bd,0xb1be,0xb1bf,
+ 0xb1c0,0xb1c1,0xb1c2,0xb1c3,0xb1c4,0xb1c5,0xb1c6,0xb1c7,
+ 0xb1c8,0xb1c9,0xb1ca,0xb1cb,0xb1cc,0xb1cd,0xb1ce,0xb1cf,
+ 0xb1d0,0xb1d1,0xb1d2,0xb1d3,0xb1d4,0xb1d5,0xb1d6,0xb1d7,
+ 0xb1d8,0xb1d9,0xb1da,0xb1db,0xb1dc,0xb1dd,0xb1de,0xb1df,
+ 0xb1e0,0xb1e1,0xb1e2,0xb1e3,0xb1e4,0xb1e5,0xb1e6,0xb1e7,
+ 0xb1e8,0xb1e9,0xb1ea,0xb1eb,0xb1ec,0xb1ed,0xb1ee,0xb1ef,
+ 0xb1f0,0xb1f1,0xb1f2,0xb1f3,0xb1f4,0xb1f5,0xb1f6,0xb1f7,
+ 0xb1f8,0xb1f9,0xb1fa,0xb1fb,0xb1fc,0xb1fd,0xb1fe,0xb1ff,
+ 0xb200,0xb201,0xb202,0xb203,0xb204,0xb205,0xb206,0xb207,
+ 0xb208,0xb209,0xb20a,0xb20b,0xb20c,0xb20d,0xb20e,0xb20f,
+ 0xb210,0xb211,0xb212,0xb213,0xb214,0xb215,0xb216,0xb217,
+ 0xb218,0xb219,0xb21a,0xb21b,0xb21c,0xb21d,0xb21e,0xb21f,
+ 0xb220,0xb221,0xb222,0xb223,0xb224,0xb225,0xb226,0xb227,
+ 0xb228,0xb229,0xb22a,0xb22b,0xb22c,0xb22d,0xb22e,0xb22f,
+ 0xb230,0xb231,0xb232,0xb233,0xb234,0xb235,0xb236,0xb237,
+ 0xb238,0xb239,0xb23a,0xb23b,0xb23c,0xb23d,0xb23e,0xb23f,
+ 0xb240,0xb241,0xb242,0xb243,0xb244,0xb245,0xb246,0xb247,
+ 0xb248,0xb249,0xb24a,0xb24b,0xb24c,0xb24d,0xb24e,0xb24f,
+ 0xb250,0xb251,0xb252,0xb253,0xb254,0xb255,0xb256,0xb257,
+ 0xb258,0xb259,0xb25a,0xb25b,0xb25c,0xb25d,0xb25e,0xb25f,
+ 0xb260,0xb261,0xb262,0xb263,0xb264,0xb265,0xb266,0xb267,
+ 0xb268,0xb269,0xb26a,0xb26b,0xb26c,0xb26d,0xb26e,0xb26f,
+ 0xb270,0xb271,0xb272,0xb273,0xb274,0xb275,0xb276,0xb277,
+ 0xb278,0xb279,0xb27a,0xb27b,0xb27c,0xb27d,0xb27e,0xb27f,
+ 0xb280,0xb281,0xb282,0xb283,0xb284,0xb285,0xb286,0xb287,
+ 0xb288,0xb289,0xb28a,0xb28b,0xb28c,0xb28d,0xb28e,0xb28f,
+ 0xb290,0xb291,0xb292,0xb293,0xb294,0xb295,0xb296,0xb297,
+ 0xb298,0xb299,0xb29a,0xb29b,0xb29c,0xb29d,0xb29e,0xb29f,
+ 0xb2a0,0xb2a1,0xb2a2,0xb2a3,0xb2a4,0xb2a5,0xb2a6,0xb2a7,
+ 0xb2a8,0xb2a9,0xb2aa,0xb2ab,0xb2ac,0xb2ad,0xb2ae,0xb2af,
+ 0xb2b0,0xb2b1,0xb2b2,0xb2b3,0xb2b4,0xb2b5,0xb2b6,0xb2b7,
+ 0xb2b8,0xb2b9,0xb2ba,0xb2bb,0xb2bc,0xb2bd,0xb2be,0xb2bf,
+ 0xb2c0,0xb2c1,0xb2c2,0xb2c3,0xb2c4,0xb2c5,0xb2c6,0xb2c7,
+ 0xb2c8,0xb2c9,0xb2ca,0xb2cb,0xb2cc,0xb2cd,0xb2ce,0xb2cf,
+ 0xb2d0,0xb2d1,0xb2d2,0xb2d3,0xb2d4,0xb2d5,0xb2d6,0xb2d7,
+ 0xb2d8,0xb2d9,0xb2da,0xb2db,0xb2dc,0xb2dd,0xb2de,0xb2df,
+ 0xb2e0,0xb2e1,0xb2e2,0xb2e3,0xb2e4,0xb2e5,0xb2e6,0xb2e7,
+ 0xb2e8,0xb2e9,0xb2ea,0xb2eb,0xb2ec,0xb2ed,0xb2ee,0xb2ef,
+ 0xb2f0,0xb2f1,0xb2f2,0xb2f3,0xb2f4,0xb2f5,0xb2f6,0xb2f7,
+ 0xb2f8,0xb2f9,0xb2fa,0xb2fb,0xb2fc,0xb2fd,0xb2fe,0xb2ff,
+ 0xb300,0xb301,0xb302,0xb303,0xb304,0xb305,0xb306,0xb307,
+ 0xb308,0xb309,0xb30a,0xb30b,0xb30c,0xb30d,0xb30e,0xb30f,
+ 0xb310,0xb311,0xb312,0xb313,0xb314,0xb315,0xb316,0xb317,
+ 0xb318,0xb319,0xb31a,0xb31b,0xb31c,0xb31d,0xb31e,0xb31f,
+ 0xb320,0xb321,0xb322,0xb323,0xb324,0xb325,0xb326,0xb327,
+ 0xb328,0xb329,0xb32a,0xb32b,0xb32c,0xb32d,0xb32e,0xb32f,
+ 0xb330,0xb331,0xb332,0xb333,0xb334,0xb335,0xb336,0xb337,
+ 0xb338,0xb339,0xb33a,0xb33b,0xb33c,0xb33d,0xb33e,0xb33f,
+ 0xb340,0xb341,0xb342,0xb343,0xb344,0xb345,0xb346,0xb347,
+ 0xb348,0xb349,0xb34a,0xb34b,0xb34c,0xb34d,0xb34e,0xb34f,
+ 0xb350,0xb351,0xb352,0xb353,0xb354,0xb355,0xb356,0xb357,
+ 0xb358,0xb359,0xb35a,0xb35b,0xb35c,0xb35d,0xb35e,0xb35f,
+ 0xb360,0xb361,0xb362,0xb363,0xb364,0xb365,0xb366,0xb367,
+ 0xb368,0xb369,0xb36a,0xb36b,0xb36c,0xb36d,0xb36e,0xb36f,
+ 0xb370,0xb371,0xb372,0xb373,0xb374,0xb375,0xb376,0xb377,
+ 0xb378,0xb379,0xb37a,0xb37b,0xb37c,0xb37d,0xb37e,0xb37f,
+ 0xb380,0xb381,0xb382,0xb383,0xb384,0xb385,0xb386,0xb387,
+ 0xb388,0xb389,0xb38a,0xb38b,0xb38c,0xb38d,0xb38e,0xb38f,
+ 0xb390,0xb391,0xb392,0xb393,0xb394,0xb395,0xb396,0xb397,
+ 0xb398,0xb399,0xb39a,0xb39b,0xb39c,0xb39d,0xb39e,0xb39f,
+ 0xb3a0,0xb3a1,0xb3a2,0xb3a3,0xb3a4,0xb3a5,0xb3a6,0xb3a7,
+ 0xb3a8,0xb3a9,0xb3aa,0xb3ab,0xb3ac,0xb3ad,0xb3ae,0xb3af,
+ 0xb3b0,0xb3b1,0xb3b2,0xb3b3,0xb3b4,0xb3b5,0xb3b6,0xb3b7,
+ 0xb3b8,0xb3b9,0xb3ba,0xb3bb,0xb3bc,0xb3bd,0xb3be,0xb3bf,
+ 0xb3c0,0xb3c1,0xb3c2,0xb3c3,0xb3c4,0xb3c5,0xb3c6,0xb3c7,
+ 0xb3c8,0xb3c9,0xb3ca,0xb3cb,0xb3cc,0xb3cd,0xb3ce,0xb3cf,
+ 0xb3d0,0xb3d1,0xb3d2,0xb3d3,0xb3d4,0xb3d5,0xb3d6,0xb3d7,
+ 0xb3d8,0xb3d9,0xb3da,0xb3db,0xb3dc,0xb3dd,0xb3de,0xb3df,
+ 0xb3e0,0xb3e1,0xb3e2,0xb3e3,0xb3e4,0xb3e5,0xb3e6,0xb3e7,
+ 0xb3e8,0xb3e9,0xb3ea,0xb3eb,0xb3ec,0xb3ed,0xb3ee,0xb3ef,
+ 0xb3f0,0xb3f1,0xb3f2,0xb3f3,0xb3f4,0xb3f5,0xb3f6,0xb3f7,
+ 0xb3f8,0xb3f9,0xb3fa,0xb3fb,0xb3fc,0xb3fd,0xb3fe,0xb3ff,
+ 0xb400,0xb401,0xb402,0xb403,0xb404,0xb405,0xb406,0xb407,
+ 0xb408,0xb409,0xb40a,0xb40b,0xb40c,0xb40d,0xb40e,0xb40f,
+ 0xb410,0xb411,0xb412,0xb413,0xb414,0xb415,0xb416,0xb417,
+ 0xb418,0xb419,0xb41a,0xb41b,0xb41c,0xb41d,0xb41e,0xb41f,
+ 0xb420,0xb421,0xb422,0xb423,0xb424,0xb425,0xb426,0xb427,
+ 0xb428,0xb429,0xb42a,0xb42b,0xb42c,0xb42d,0xb42e,0xb42f,
+ 0xb430,0xb431,0xb432,0xb433,0xb434,0xb435,0xb436,0xb437,
+ 0xb438,0xb439,0xb43a,0xb43b,0xb43c,0xb43d,0xb43e,0xb43f,
+ 0xb440,0xb441,0xb442,0xb443,0xb444,0xb445,0xb446,0xb447,
+ 0xb448,0xb449,0xb44a,0xb44b,0xb44c,0xb44d,0xb44e,0xb44f,
+ 0xb450,0xb451,0xb452,0xb453,0xb454,0xb455,0xb456,0xb457,
+ 0xb458,0xb459,0xb45a,0xb45b,0xb45c,0xb45d,0xb45e,0xb45f,
+ 0xb460,0xb461,0xb462,0xb463,0xb464,0xb465,0xb466,0xb467,
+ 0xb468,0xb469,0xb46a,0xb46b,0xb46c,0xb46d,0xb46e,0xb46f,
+ 0xb470,0xb471,0xb472,0xb473,0xb474,0xb475,0xb476,0xb477,
+ 0xb478,0xb479,0xb47a,0xb47b,0xb47c,0xb47d,0xb47e,0xb47f,
+ 0xb480,0xb481,0xb482,0xb483,0xb484,0xb485,0xb486,0xb487,
+ 0xb488,0xb489,0xb48a,0xb48b,0xb48c,0xb48d,0xb48e,0xb48f,
+ 0xb490,0xb491,0xb492,0xb493,0xb494,0xb495,0xb496,0xb497,
+ 0xb498,0xb499,0xb49a,0xb49b,0xb49c,0xb49d,0xb49e,0xb49f,
+ 0xb4a0,0xb4a1,0xb4a2,0xb4a3,0xb4a4,0xb4a5,0xb4a6,0xb4a7,
+ 0xb4a8,0xb4a9,0xb4aa,0xb4ab,0xb4ac,0xb4ad,0xb4ae,0xb4af,
+ 0xb4b0,0xb4b1,0xb4b2,0xb4b3,0xb4b4,0xb4b5,0xb4b6,0xb4b7,
+ 0xb4b8,0xb4b9,0xb4ba,0xb4bb,0xb4bc,0xb4bd,0xb4be,0xb4bf,
+ 0xb4c0,0xb4c1,0xb4c2,0xb4c3,0xb4c4,0xb4c5,0xb4c6,0xb4c7,
+ 0xb4c8,0xb4c9,0xb4ca,0xb4cb,0xb4cc,0xb4cd,0xb4ce,0xb4cf,
+ 0xb4d0,0xb4d1,0xb4d2,0xb4d3,0xb4d4,0xb4d5,0xb4d6,0xb4d7,
+ 0xb4d8,0xb4d9,0xb4da,0xb4db,0xb4dc,0xb4dd,0xb4de,0xb4df,
+ 0xb4e0,0xb4e1,0xb4e2,0xb4e3,0xb4e4,0xb4e5,0xb4e6,0xb4e7,
+ 0xb4e8,0xb4e9,0xb4ea,0xb4eb,0xb4ec,0xb4ed,0xb4ee,0xb4ef,
+ 0xb4f0,0xb4f1,0xb4f2,0xb4f3,0xb4f4,0xb4f5,0xb4f6,0xb4f7,
+ 0xb4f8,0xb4f9,0xb4fa,0xb4fb,0xb4fc,0xb4fd,0xb4fe,0xb4ff,
+ 0xb500,0xb501,0xb502,0xb503,0xb504,0xb505,0xb506,0xb507,
+ 0xb508,0xb509,0xb50a,0xb50b,0xb50c,0xb50d,0xb50e,0xb50f,
+ 0xb510,0xb511,0xb512,0xb513,0xb514,0xb515,0xb516,0xb517,
+ 0xb518,0xb519,0xb51a,0xb51b,0xb51c,0xb51d,0xb51e,0xb51f,
+ 0xb520,0xb521,0xb522,0xb523,0xb524,0xb525,0xb526,0xb527,
+ 0xb528,0xb529,0xb52a,0xb52b,0xb52c,0xb52d,0xb52e,0xb52f,
+ 0xb530,0xb531,0xb532,0xb533,0xb534,0xb535,0xb536,0xb537,
+ 0xb538,0xb539,0xb53a,0xb53b,0xb53c,0xb53d,0xb53e,0xb53f,
+ 0xb540,0xb541,0xb542,0xb543,0xb544,0xb545,0xb546,0xb547,
+ 0xb548,0xb549,0xb54a,0xb54b,0xb54c,0xb54d,0xb54e,0xb54f,
+ 0xb550,0xb551,0xb552,0xb553,0xb554,0xb555,0xb556,0xb557,
+ 0xb558,0xb559,0xb55a,0xb55b,0xb55c,0xb55d,0xb55e,0xb55f,
+ 0xb560,0xb561,0xb562,0xb563,0xb564,0xb565,0xb566,0xb567,
+ 0xb568,0xb569,0xb56a,0xb56b,0xb56c,0xb56d,0xb56e,0xb56f,
+ 0xb570,0xb571,0xb572,0xb573,0xb574,0xb575,0xb576,0xb577,
+ 0xb578,0xb579,0xb57a,0xb57b,0xb57c,0xb57d,0xb57e,0xb57f,
+ 0xb580,0xb581,0xb582,0xb583,0xb584,0xb585,0xb586,0xb587,
+ 0xb588,0xb589,0xb58a,0xb58b,0xb58c,0xb58d,0xb58e,0xb58f,
+ 0xb590,0xb591,0xb592,0xb593,0xb594,0xb595,0xb596,0xb597,
+ 0xb598,0xb599,0xb59a,0xb59b,0xb59c,0xb59d,0xb59e,0xb59f,
+ 0xb5a0,0xb5a1,0xb5a2,0xb5a3,0xb5a4,0xb5a5,0xb5a6,0xb5a7,
+ 0xb5a8,0xb5a9,0xb5aa,0xb5ab,0xb5ac,0xb5ad,0xb5ae,0xb5af,
+ 0xb5b0,0xb5b1,0xb5b2,0xb5b3,0xb5b4,0xb5b5,0xb5b6,0xb5b7,
+ 0xb5b8,0xb5b9,0xb5ba,0xb5bb,0xb5bc,0xb5bd,0xb5be,0xb5bf,
+ 0xb5c0,0xb5c1,0xb5c2,0xb5c3,0xb5c4,0xb5c5,0xb5c6,0xb5c7,
+ 0xb5c8,0xb5c9,0xb5ca,0xb5cb,0xb5cc,0xb5cd,0xb5ce,0xb5cf,
+ 0xb5d0,0xb5d1,0xb5d2,0xb5d3,0xb5d4,0xb5d5,0xb5d6,0xb5d7,
+ 0xb5d8,0xb5d9,0xb5da,0xb5db,0xb5dc,0xb5dd,0xb5de,0xb5df,
+ 0xb5e0,0xb5e1,0xb5e2,0xb5e3,0xb5e4,0xb5e5,0xb5e6,0xb5e7,
+ 0xb5e8,0xb5e9,0xb5ea,0xb5eb,0xb5ec,0xb5ed,0xb5ee,0xb5ef,
+ 0xb5f0,0xb5f1,0xb5f2,0xb5f3,0xb5f4,0xb5f5,0xb5f6,0xb5f7,
+ 0xb5f8,0xb5f9,0xb5fa,0xb5fb,0xb5fc,0xb5fd,0xb5fe,0xb5ff,
+ 0xb600,0xb601,0xb602,0xb603,0xb604,0xb605,0xb606,0xb607,
+ 0xb608,0xb609,0xb60a,0xb60b,0xb60c,0xb60d,0xb60e,0xb60f,
+ 0xb610,0xb611,0xb612,0xb613,0xb614,0xb615,0xb616,0xb617,
+ 0xb618,0xb619,0xb61a,0xb61b,0xb61c,0xb61d,0xb61e,0xb61f,
+ 0xb620,0xb621,0xb622,0xb623,0xb624,0xb625,0xb626,0xb627,
+ 0xb628,0xb629,0xb62a,0xb62b,0xb62c,0xb62d,0xb62e,0xb62f,
+ 0xb630,0xb631,0xb632,0xb633,0xb634,0xb635,0xb636,0xb637,
+ 0xb638,0xb639,0xb63a,0xb63b,0xb63c,0xb63d,0xb63e,0xb63f,
+ 0xb640,0xb641,0xb642,0xb643,0xb644,0xb645,0xb646,0xb647,
+ 0xb648,0xb649,0xb64a,0xb64b,0xb64c,0xb64d,0xb64e,0xb64f,
+ 0xb650,0xb651,0xb652,0xb653,0xb654,0xb655,0xb656,0xb657,
+ 0xb658,0xb659,0xb65a,0xb65b,0xb65c,0xb65d,0xb65e,0xb65f,
+ 0xb660,0xb661,0xb662,0xb663,0xb664,0xb665,0xb666,0xb667,
+ 0xb668,0xb669,0xb66a,0xb66b,0xb66c,0xb66d,0xb66e,0xb66f,
+ 0xb670,0xb671,0xb672,0xb673,0xb674,0xb675,0xb676,0xb677,
+ 0xb678,0xb679,0xb67a,0xb67b,0xb67c,0xb67d,0xb67e,0xb67f,
+ 0xb680,0xb681,0xb682,0xb683,0xb684,0xb685,0xb686,0xb687,
+ 0xb688,0xb689,0xb68a,0xb68b,0xb68c,0xb68d,0xb68e,0xb68f,
+ 0xb690,0xb691,0xb692,0xb693,0xb694,0xb695,0xb696,0xb697,
+ 0xb698,0xb699,0xb69a,0xb69b,0xb69c,0xb69d,0xb69e,0xb69f,
+ 0xb6a0,0xb6a1,0xb6a2,0xb6a3,0xb6a4,0xb6a5,0xb6a6,0xb6a7,
+ 0xb6a8,0xb6a9,0xb6aa,0xb6ab,0xb6ac,0xb6ad,0xb6ae,0xb6af,
+ 0xb6b0,0xb6b1,0xb6b2,0xb6b3,0xb6b4,0xb6b5,0xb6b6,0xb6b7,
+ 0xb6b8,0xb6b9,0xb6ba,0xb6bb,0xb6bc,0xb6bd,0xb6be,0xb6bf,
+ 0xb6c0,0xb6c1,0xb6c2,0xb6c3,0xb6c4,0xb6c5,0xb6c6,0xb6c7,
+ 0xb6c8,0xb6c9,0xb6ca,0xb6cb,0xb6cc,0xb6cd,0xb6ce,0xb6cf,
+ 0xb6d0,0xb6d1,0xb6d2,0xb6d3,0xb6d4,0xb6d5,0xb6d6,0xb6d7,
+ 0xb6d8,0xb6d9,0xb6da,0xb6db,0xb6dc,0xb6dd,0xb6de,0xb6df,
+ 0xb6e0,0xb6e1,0xb6e2,0xb6e3,0xb6e4,0xb6e5,0xb6e6,0xb6e7,
+ 0xb6e8,0xb6e9,0xb6ea,0xb6eb,0xb6ec,0xb6ed,0xb6ee,0xb6ef,
+ 0xb6f0,0xb6f1,0xb6f2,0xb6f3,0xb6f4,0xb6f5,0xb6f6,0xb6f7,
+ 0xb6f8,0xb6f9,0xb6fa,0xb6fb,0xb6fc,0xb6fd,0xb6fe,0xb6ff,
+ 0xb700,0xb701,0xb702,0xb703,0xb704,0xb705,0xb706,0xb707,
+ 0xb708,0xb709,0xb70a,0xb70b,0xb70c,0xb70d,0xb70e,0xb70f,
+ 0xb710,0xb711,0xb712,0xb713,0xb714,0xb715,0xb716,0xb717,
+ 0xb718,0xb719,0xb71a,0xb71b,0xb71c,0xb71d,0xb71e,0xb71f,
+ 0xb720,0xb721,0xb722,0xb723,0xb724,0xb725,0xb726,0xb727,
+ 0xb728,0xb729,0xb72a,0xb72b,0xb72c,0xb72d,0xb72e,0xb72f,
+ 0xb730,0xb731,0xb732,0xb733,0xb734,0xb735,0xb736,0xb737,
+ 0xb738,0xb739,0xb73a,0xb73b,0xb73c,0xb73d,0xb73e,0xb73f,
+ 0xb740,0xb741,0xb742,0xb743,0xb744,0xb745,0xb746,0xb747,
+ 0xb748,0xb749,0xb74a,0xb74b,0xb74c,0xb74d,0xb74e,0xb74f,
+ 0xb750,0xb751,0xb752,0xb753,0xb754,0xb755,0xb756,0xb757,
+ 0xb758,0xb759,0xb75a,0xb75b,0xb75c,0xb75d,0xb75e,0xb75f,
+ 0xb760,0xb761,0xb762,0xb763,0xb764,0xb765,0xb766,0xb767,
+ 0xb768,0xb769,0xb76a,0xb76b,0xb76c,0xb76d,0xb76e,0xb76f,
+ 0xb770,0xb771,0xb772,0xb773,0xb774,0xb775,0xb776,0xb777,
+ 0xb778,0xb779,0xb77a,0xb77b,0xb77c,0xb77d,0xb77e,0xb77f,
+ 0xb780,0xb781,0xb782,0xb783,0xb784,0xb785,0xb786,0xb787,
+ 0xb788,0xb789,0xb78a,0xb78b,0xb78c,0xb78d,0xb78e,0xb78f,
+ 0xb790,0xb791,0xb792,0xb793,0xb794,0xb795,0xb796,0xb797,
+ 0xb798,0xb799,0xb79a,0xb79b,0xb79c,0xb79d,0xb79e,0xb79f,
+ 0xb7a0,0xb7a1,0xb7a2,0xb7a3,0xb7a4,0xb7a5,0xb7a6,0xb7a7,
+ 0xb7a8,0xb7a9,0xb7aa,0xb7ab,0xb7ac,0xb7ad,0xb7ae,0xb7af,
+ 0xb7b0,0xb7b1,0xb7b2,0xb7b3,0xb7b4,0xb7b5,0xb7b6,0xb7b7,
+ 0xb7b8,0xb7b9,0xb7ba,0xb7bb,0xb7bc,0xb7bd,0xb7be,0xb7bf,
+ 0xb7c0,0xb7c1,0xb7c2,0xb7c3,0xb7c4,0xb7c5,0xb7c6,0xb7c7,
+ 0xb7c8,0xb7c9,0xb7ca,0xb7cb,0xb7cc,0xb7cd,0xb7ce,0xb7cf,
+ 0xb7d0,0xb7d1,0xb7d2,0xb7d3,0xb7d4,0xb7d5,0xb7d6,0xb7d7,
+ 0xb7d8,0xb7d9,0xb7da,0xb7db,0xb7dc,0xb7dd,0xb7de,0xb7df,
+ 0xb7e0,0xb7e1,0xb7e2,0xb7e3,0xb7e4,0xb7e5,0xb7e6,0xb7e7,
+ 0xb7e8,0xb7e9,0xb7ea,0xb7eb,0xb7ec,0xb7ed,0xb7ee,0xb7ef,
+ 0xb7f0,0xb7f1,0xb7f2,0xb7f3,0xb7f4,0xb7f5,0xb7f6,0xb7f7,
+ 0xb7f8,0xb7f9,0xb7fa,0xb7fb,0xb7fc,0xb7fd,0xb7fe,0xb7ff,
+ 0xb800,0xb801,0xb802,0xb803,0xb804,0xb805,0xb806,0xb807,
+ 0xb808,0xb809,0xb80a,0xb80b,0xb80c,0xb80d,0xb80e,0xb80f,
+ 0xb810,0xb811,0xb812,0xb813,0xb814,0xb815,0xb816,0xb817,
+ 0xb818,0xb819,0xb81a,0xb81b,0xb81c,0xb81d,0xb81e,0xb81f,
+ 0xb820,0xb821,0xb822,0xb823,0xb824,0xb825,0xb826,0xb827,
+ 0xb828,0xb829,0xb82a,0xb82b,0xb82c,0xb82d,0xb82e,0xb82f,
+ 0xb830,0xb831,0xb832,0xb833,0xb834,0xb835,0xb836,0xb837,
+ 0xb838,0xb839,0xb83a,0xb83b,0xb83c,0xb83d,0xb83e,0xb83f,
+ 0xb840,0xb841,0xb842,0xb843,0xb844,0xb845,0xb846,0xb847,
+ 0xb848,0xb849,0xb84a,0xb84b,0xb84c,0xb84d,0xb84e,0xb84f,
+ 0xb850,0xb851,0xb852,0xb853,0xb854,0xb855,0xb856,0xb857,
+ 0xb858,0xb859,0xb85a,0xb85b,0xb85c,0xb85d,0xb85e,0xb85f,
+ 0xb860,0xb861,0xb862,0xb863,0xb864,0xb865,0xb866,0xb867,
+ 0xb868,0xb869,0xb86a,0xb86b,0xb86c,0xb86d,0xb86e,0xb86f,
+ 0xb870,0xb871,0xb872,0xb873,0xb874,0xb875,0xb876,0xb877,
+ 0xb878,0xb879,0xb87a,0xb87b,0xb87c,0xb87d,0xb87e,0xb87f,
+ 0xb880,0xb881,0xb882,0xb883,0xb884,0xb885,0xb886,0xb887,
+ 0xb888,0xb889,0xb88a,0xb88b,0xb88c,0xb88d,0xb88e,0xb88f,
+ 0xb890,0xb891,0xb892,0xb893,0xb894,0xb895,0xb896,0xb897,
+ 0xb898,0xb899,0xb89a,0xb89b,0xb89c,0xb89d,0xb89e,0xb89f,
+ 0xb8a0,0xb8a1,0xb8a2,0xb8a3,0xb8a4,0xb8a5,0xb8a6,0xb8a7,
+ 0xb8a8,0xb8a9,0xb8aa,0xb8ab,0xb8ac,0xb8ad,0xb8ae,0xb8af,
+ 0xb8b0,0xb8b1,0xb8b2,0xb8b3,0xb8b4,0xb8b5,0xb8b6,0xb8b7,
+ 0xb8b8,0xb8b9,0xb8ba,0xb8bb,0xb8bc,0xb8bd,0xb8be,0xb8bf,
+ 0xb8c0,0xb8c1,0xb8c2,0xb8c3,0xb8c4,0xb8c5,0xb8c6,0xb8c7,
+ 0xb8c8,0xb8c9,0xb8ca,0xb8cb,0xb8cc,0xb8cd,0xb8ce,0xb8cf,
+ 0xb8d0,0xb8d1,0xb8d2,0xb8d3,0xb8d4,0xb8d5,0xb8d6,0xb8d7,
+ 0xb8d8,0xb8d9,0xb8da,0xb8db,0xb8dc,0xb8dd,0xb8de,0xb8df,
+ 0xb8e0,0xb8e1,0xb8e2,0xb8e3,0xb8e4,0xb8e5,0xb8e6,0xb8e7,
+ 0xb8e8,0xb8e9,0xb8ea,0xb8eb,0xb8ec,0xb8ed,0xb8ee,0xb8ef,
+ 0xb8f0,0xb8f1,0xb8f2,0xb8f3,0xb8f4,0xb8f5,0xb8f6,0xb8f7,
+ 0xb8f8,0xb8f9,0xb8fa,0xb8fb,0xb8fc,0xb8fd,0xb8fe,0xb8ff,
+ 0xb900,0xb901,0xb902,0xb903,0xb904,0xb905,0xb906,0xb907,
+ 0xb908,0xb909,0xb90a,0xb90b,0xb90c,0xb90d,0xb90e,0xb90f,
+ 0xb910,0xb911,0xb912,0xb913,0xb914,0xb915,0xb916,0xb917,
+ 0xb918,0xb919,0xb91a,0xb91b,0xb91c,0xb91d,0xb91e,0xb91f,
+ 0xb920,0xb921,0xb922,0xb923,0xb924,0xb925,0xb926,0xb927,
+ 0xb928,0xb929,0xb92a,0xb92b,0xb92c,0xb92d,0xb92e,0xb92f,
+ 0xb930,0xb931,0xb932,0xb933,0xb934,0xb935,0xb936,0xb937,
+ 0xb938,0xb939,0xb93a,0xb93b,0xb93c,0xb93d,0xb93e,0xb93f,
+ 0xb940,0xb941,0xb942,0xb943,0xb944,0xb945,0xb946,0xb947,
+ 0xb948,0xb949,0xb94a,0xb94b,0xb94c,0xb94d,0xb94e,0xb94f,
+ 0xb950,0xb951,0xb952,0xb953,0xb954,0xb955,0xb956,0xb957,
+ 0xb958,0xb959,0xb95a,0xb95b,0xb95c,0xb95d,0xb95e,0xb95f,
+ 0xb960,0xb961,0xb962,0xb963,0xb964,0xb965,0xb966,0xb967,
+ 0xb968,0xb969,0xb96a,0xb96b,0xb96c,0xb96d,0xb96e,0xb96f,
+ 0xb970,0xb971,0xb972,0xb973,0xb974,0xb975,0xb976,0xb977,
+ 0xb978,0xb979,0xb97a,0xb97b,0xb97c,0xb97d,0xb97e,0xb97f,
+ 0xb980,0xb981,0xb982,0xb983,0xb984,0xb985,0xb986,0xb987,
+ 0xb988,0xb989,0xb98a,0xb98b,0xb98c,0xb98d,0xb98e,0xb98f,
+ 0xb990,0xb991,0xb992,0xb993,0xb994,0xb995,0xb996,0xb997,
+ 0xb998,0xb999,0xb99a,0xb99b,0xb99c,0xb99d,0xb99e,0xb99f,
+ 0xb9a0,0xb9a1,0xb9a2,0xb9a3,0xb9a4,0xb9a5,0xb9a6,0xb9a7,
+ 0xb9a8,0xb9a9,0xb9aa,0xb9ab,0xb9ac,0xb9ad,0xb9ae,0xb9af,
+ 0xb9b0,0xb9b1,0xb9b2,0xb9b3,0xb9b4,0xb9b5,0xb9b6,0xb9b7,
+ 0xb9b8,0xb9b9,0xb9ba,0xb9bb,0xb9bc,0xb9bd,0xb9be,0xb9bf,
+ 0xb9c0,0xb9c1,0xb9c2,0xb9c3,0xb9c4,0xb9c5,0xb9c6,0xb9c7,
+ 0xb9c8,0xb9c9,0xb9ca,0xb9cb,0xb9cc,0xb9cd,0xb9ce,0xb9cf,
+ 0xb9d0,0xb9d1,0xb9d2,0xb9d3,0xb9d4,0xb9d5,0xb9d6,0xb9d7,
+ 0xb9d8,0xb9d9,0xb9da,0xb9db,0xb9dc,0xb9dd,0xb9de,0xb9df,
+ 0xb9e0,0xb9e1,0xb9e2,0xb9e3,0xb9e4,0xb9e5,0xb9e6,0xb9e7,
+ 0xb9e8,0xb9e9,0xb9ea,0xb9eb,0xb9ec,0xb9ed,0xb9ee,0xb9ef,
+ 0xb9f0,0xb9f1,0xb9f2,0xb9f3,0xb9f4,0xb9f5,0xb9f6,0xb9f7,
+ 0xb9f8,0xb9f9,0xb9fa,0xb9fb,0xb9fc,0xb9fd,0xb9fe,0xb9ff,
+ 0xba00,0xba01,0xba02,0xba03,0xba04,0xba05,0xba06,0xba07,
+ 0xba08,0xba09,0xba0a,0xba0b,0xba0c,0xba0d,0xba0e,0xba0f,
+ 0xba10,0xba11,0xba12,0xba13,0xba14,0xba15,0xba16,0xba17,
+ 0xba18,0xba19,0xba1a,0xba1b,0xba1c,0xba1d,0xba1e,0xba1f,
+ 0xba20,0xba21,0xba22,0xba23,0xba24,0xba25,0xba26,0xba27,
+ 0xba28,0xba29,0xba2a,0xba2b,0xba2c,0xba2d,0xba2e,0xba2f,
+ 0xba30,0xba31,0xba32,0xba33,0xba34,0xba35,0xba36,0xba37,
+ 0xba38,0xba39,0xba3a,0xba3b,0xba3c,0xba3d,0xba3e,0xba3f,
+ 0xba40,0xba41,0xba42,0xba43,0xba44,0xba45,0xba46,0xba47,
+ 0xba48,0xba49,0xba4a,0xba4b,0xba4c,0xba4d,0xba4e,0xba4f,
+ 0xba50,0xba51,0xba52,0xba53,0xba54,0xba55,0xba56,0xba57,
+ 0xba58,0xba59,0xba5a,0xba5b,0xba5c,0xba5d,0xba5e,0xba5f,
+ 0xba60,0xba61,0xba62,0xba63,0xba64,0xba65,0xba66,0xba67,
+ 0xba68,0xba69,0xba6a,0xba6b,0xba6c,0xba6d,0xba6e,0xba6f,
+ 0xba70,0xba71,0xba72,0xba73,0xba74,0xba75,0xba76,0xba77,
+ 0xba78,0xba79,0xba7a,0xba7b,0xba7c,0xba7d,0xba7e,0xba7f,
+ 0xba80,0xba81,0xba82,0xba83,0xba84,0xba85,0xba86,0xba87,
+ 0xba88,0xba89,0xba8a,0xba8b,0xba8c,0xba8d,0xba8e,0xba8f,
+ 0xba90,0xba91,0xba92,0xba93,0xba94,0xba95,0xba96,0xba97,
+ 0xba98,0xba99,0xba9a,0xba9b,0xba9c,0xba9d,0xba9e,0xba9f,
+ 0xbaa0,0xbaa1,0xbaa2,0xbaa3,0xbaa4,0xbaa5,0xbaa6,0xbaa7,
+ 0xbaa8,0xbaa9,0xbaaa,0xbaab,0xbaac,0xbaad,0xbaae,0xbaaf,
+ 0xbab0,0xbab1,0xbab2,0xbab3,0xbab4,0xbab5,0xbab6,0xbab7,
+ 0xbab8,0xbab9,0xbaba,0xbabb,0xbabc,0xbabd,0xbabe,0xbabf,
+ 0xbac0,0xbac1,0xbac2,0xbac3,0xbac4,0xbac5,0xbac6,0xbac7,
+ 0xbac8,0xbac9,0xbaca,0xbacb,0xbacc,0xbacd,0xbace,0xbacf,
+ 0xbad0,0xbad1,0xbad2,0xbad3,0xbad4,0xbad5,0xbad6,0xbad7,
+ 0xbad8,0xbad9,0xbada,0xbadb,0xbadc,0xbadd,0xbade,0xbadf,
+ 0xbae0,0xbae1,0xbae2,0xbae3,0xbae4,0xbae5,0xbae6,0xbae7,
+ 0xbae8,0xbae9,0xbaea,0xbaeb,0xbaec,0xbaed,0xbaee,0xbaef,
+ 0xbaf0,0xbaf1,0xbaf2,0xbaf3,0xbaf4,0xbaf5,0xbaf6,0xbaf7,
+ 0xbaf8,0xbaf9,0xbafa,0xbafb,0xbafc,0xbafd,0xbafe,0xbaff,
+ 0xbb00,0xbb01,0xbb02,0xbb03,0xbb04,0xbb05,0xbb06,0xbb07,
+ 0xbb08,0xbb09,0xbb0a,0xbb0b,0xbb0c,0xbb0d,0xbb0e,0xbb0f,
+ 0xbb10,0xbb11,0xbb12,0xbb13,0xbb14,0xbb15,0xbb16,0xbb17,
+ 0xbb18,0xbb19,0xbb1a,0xbb1b,0xbb1c,0xbb1d,0xbb1e,0xbb1f,
+ 0xbb20,0xbb21,0xbb22,0xbb23,0xbb24,0xbb25,0xbb26,0xbb27,
+ 0xbb28,0xbb29,0xbb2a,0xbb2b,0xbb2c,0xbb2d,0xbb2e,0xbb2f,
+ 0xbb30,0xbb31,0xbb32,0xbb33,0xbb34,0xbb35,0xbb36,0xbb37,
+ 0xbb38,0xbb39,0xbb3a,0xbb3b,0xbb3c,0xbb3d,0xbb3e,0xbb3f,
+ 0xbb40,0xbb41,0xbb42,0xbb43,0xbb44,0xbb45,0xbb46,0xbb47,
+ 0xbb48,0xbb49,0xbb4a,0xbb4b,0xbb4c,0xbb4d,0xbb4e,0xbb4f,
+ 0xbb50,0xbb51,0xbb52,0xbb53,0xbb54,0xbb55,0xbb56,0xbb57,
+ 0xbb58,0xbb59,0xbb5a,0xbb5b,0xbb5c,0xbb5d,0xbb5e,0xbb5f,
+ 0xbb60,0xbb61,0xbb62,0xbb63,0xbb64,0xbb65,0xbb66,0xbb67,
+ 0xbb68,0xbb69,0xbb6a,0xbb6b,0xbb6c,0xbb6d,0xbb6e,0xbb6f,
+ 0xbb70,0xbb71,0xbb72,0xbb73,0xbb74,0xbb75,0xbb76,0xbb77,
+ 0xbb78,0xbb79,0xbb7a,0xbb7b,0xbb7c,0xbb7d,0xbb7e,0xbb7f,
+ 0xbb80,0xbb81,0xbb82,0xbb83,0xbb84,0xbb85,0xbb86,0xbb87,
+ 0xbb88,0xbb89,0xbb8a,0xbb8b,0xbb8c,0xbb8d,0xbb8e,0xbb8f,
+ 0xbb90,0xbb91,0xbb92,0xbb93,0xbb94,0xbb95,0xbb96,0xbb97,
+ 0xbb98,0xbb99,0xbb9a,0xbb9b,0xbb9c,0xbb9d,0xbb9e,0xbb9f,
+ 0xbba0,0xbba1,0xbba2,0xbba3,0xbba4,0xbba5,0xbba6,0xbba7,
+ 0xbba8,0xbba9,0xbbaa,0xbbab,0xbbac,0xbbad,0xbbae,0xbbaf,
+ 0xbbb0,0xbbb1,0xbbb2,0xbbb3,0xbbb4,0xbbb5,0xbbb6,0xbbb7,
+ 0xbbb8,0xbbb9,0xbbba,0xbbbb,0xbbbc,0xbbbd,0xbbbe,0xbbbf,
+ 0xbbc0,0xbbc1,0xbbc2,0xbbc3,0xbbc4,0xbbc5,0xbbc6,0xbbc7,
+ 0xbbc8,0xbbc9,0xbbca,0xbbcb,0xbbcc,0xbbcd,0xbbce,0xbbcf,
+ 0xbbd0,0xbbd1,0xbbd2,0xbbd3,0xbbd4,0xbbd5,0xbbd6,0xbbd7,
+ 0xbbd8,0xbbd9,0xbbda,0xbbdb,0xbbdc,0xbbdd,0xbbde,0xbbdf,
+ 0xbbe0,0xbbe1,0xbbe2,0xbbe3,0xbbe4,0xbbe5,0xbbe6,0xbbe7,
+ 0xbbe8,0xbbe9,0xbbea,0xbbeb,0xbbec,0xbbed,0xbbee,0xbbef,
+ 0xbbf0,0xbbf1,0xbbf2,0xbbf3,0xbbf4,0xbbf5,0xbbf6,0xbbf7,
+ 0xbbf8,0xbbf9,0xbbfa,0xbbfb,0xbbfc,0xbbfd,0xbbfe,0xbbff,
+ 0xbc00,0xbc01,0xbc02,0xbc03,0xbc04,0xbc05,0xbc06,0xbc07,
+ 0xbc08,0xbc09,0xbc0a,0xbc0b,0xbc0c,0xbc0d,0xbc0e,0xbc0f,
+ 0xbc10,0xbc11,0xbc12,0xbc13,0xbc14,0xbc15,0xbc16,0xbc17,
+ 0xbc18,0xbc19,0xbc1a,0xbc1b,0xbc1c,0xbc1d,0xbc1e,0xbc1f,
+ 0xbc20,0xbc21,0xbc22,0xbc23,0xbc24,0xbc25,0xbc26,0xbc27,
+ 0xbc28,0xbc29,0xbc2a,0xbc2b,0xbc2c,0xbc2d,0xbc2e,0xbc2f,
+ 0xbc30,0xbc31,0xbc32,0xbc33,0xbc34,0xbc35,0xbc36,0xbc37,
+ 0xbc38,0xbc39,0xbc3a,0xbc3b,0xbc3c,0xbc3d,0xbc3e,0xbc3f,
+ 0xbc40,0xbc41,0xbc42,0xbc43,0xbc44,0xbc45,0xbc46,0xbc47,
+ 0xbc48,0xbc49,0xbc4a,0xbc4b,0xbc4c,0xbc4d,0xbc4e,0xbc4f,
+ 0xbc50,0xbc51,0xbc52,0xbc53,0xbc54,0xbc55,0xbc56,0xbc57,
+ 0xbc58,0xbc59,0xbc5a,0xbc5b,0xbc5c,0xbc5d,0xbc5e,0xbc5f,
+ 0xbc60,0xbc61,0xbc62,0xbc63,0xbc64,0xbc65,0xbc66,0xbc67,
+ 0xbc68,0xbc69,0xbc6a,0xbc6b,0xbc6c,0xbc6d,0xbc6e,0xbc6f,
+ 0xbc70,0xbc71,0xbc72,0xbc73,0xbc74,0xbc75,0xbc76,0xbc77,
+ 0xbc78,0xbc79,0xbc7a,0xbc7b,0xbc7c,0xbc7d,0xbc7e,0xbc7f,
+ 0xbc80,0xbc81,0xbc82,0xbc83,0xbc84,0xbc85,0xbc86,0xbc87,
+ 0xbc88,0xbc89,0xbc8a,0xbc8b,0xbc8c,0xbc8d,0xbc8e,0xbc8f,
+ 0xbc90,0xbc91,0xbc92,0xbc93,0xbc94,0xbc95,0xbc96,0xbc97,
+ 0xbc98,0xbc99,0xbc9a,0xbc9b,0xbc9c,0xbc9d,0xbc9e,0xbc9f,
+ 0xbca0,0xbca1,0xbca2,0xbca3,0xbca4,0xbca5,0xbca6,0xbca7,
+ 0xbca8,0xbca9,0xbcaa,0xbcab,0xbcac,0xbcad,0xbcae,0xbcaf,
+ 0xbcb0,0xbcb1,0xbcb2,0xbcb3,0xbcb4,0xbcb5,0xbcb6,0xbcb7,
+ 0xbcb8,0xbcb9,0xbcba,0xbcbb,0xbcbc,0xbcbd,0xbcbe,0xbcbf,
+ 0xbcc0,0xbcc1,0xbcc2,0xbcc3,0xbcc4,0xbcc5,0xbcc6,0xbcc7,
+ 0xbcc8,0xbcc9,0xbcca,0xbccb,0xbccc,0xbccd,0xbcce,0xbccf,
+ 0xbcd0,0xbcd1,0xbcd2,0xbcd3,0xbcd4,0xbcd5,0xbcd6,0xbcd7,
+ 0xbcd8,0xbcd9,0xbcda,0xbcdb,0xbcdc,0xbcdd,0xbcde,0xbcdf,
+ 0xbce0,0xbce1,0xbce2,0xbce3,0xbce4,0xbce5,0xbce6,0xbce7,
+ 0xbce8,0xbce9,0xbcea,0xbceb,0xbcec,0xbced,0xbcee,0xbcef,
+ 0xbcf0,0xbcf1,0xbcf2,0xbcf3,0xbcf4,0xbcf5,0xbcf6,0xbcf7,
+ 0xbcf8,0xbcf9,0xbcfa,0xbcfb,0xbcfc,0xbcfd,0xbcfe,0xbcff,
+ 0xbd00,0xbd01,0xbd02,0xbd03,0xbd04,0xbd05,0xbd06,0xbd07,
+ 0xbd08,0xbd09,0xbd0a,0xbd0b,0xbd0c,0xbd0d,0xbd0e,0xbd0f,
+ 0xbd10,0xbd11,0xbd12,0xbd13,0xbd14,0xbd15,0xbd16,0xbd17,
+ 0xbd18,0xbd19,0xbd1a,0xbd1b,0xbd1c,0xbd1d,0xbd1e,0xbd1f,
+ 0xbd20,0xbd21,0xbd22,0xbd23,0xbd24,0xbd25,0xbd26,0xbd27,
+ 0xbd28,0xbd29,0xbd2a,0xbd2b,0xbd2c,0xbd2d,0xbd2e,0xbd2f,
+ 0xbd30,0xbd31,0xbd32,0xbd33,0xbd34,0xbd35,0xbd36,0xbd37,
+ 0xbd38,0xbd39,0xbd3a,0xbd3b,0xbd3c,0xbd3d,0xbd3e,0xbd3f,
+ 0xbd40,0xbd41,0xbd42,0xbd43,0xbd44,0xbd45,0xbd46,0xbd47,
+ 0xbd48,0xbd49,0xbd4a,0xbd4b,0xbd4c,0xbd4d,0xbd4e,0xbd4f,
+ 0xbd50,0xbd51,0xbd52,0xbd53,0xbd54,0xbd55,0xbd56,0xbd57,
+ 0xbd58,0xbd59,0xbd5a,0xbd5b,0xbd5c,0xbd5d,0xbd5e,0xbd5f,
+ 0xbd60,0xbd61,0xbd62,0xbd63,0xbd64,0xbd65,0xbd66,0xbd67,
+ 0xbd68,0xbd69,0xbd6a,0xbd6b,0xbd6c,0xbd6d,0xbd6e,0xbd6f,
+ 0xbd70,0xbd71,0xbd72,0xbd73,0xbd74,0xbd75,0xbd76,0xbd77,
+ 0xbd78,0xbd79,0xbd7a,0xbd7b,0xbd7c,0xbd7d,0xbd7e,0xbd7f,
+ 0xbd80,0xbd81,0xbd82,0xbd83,0xbd84,0xbd85,0xbd86,0xbd87,
+ 0xbd88,0xbd89,0xbd8a,0xbd8b,0xbd8c,0xbd8d,0xbd8e,0xbd8f,
+ 0xbd90,0xbd91,0xbd92,0xbd93,0xbd94,0xbd95,0xbd96,0xbd97,
+ 0xbd98,0xbd99,0xbd9a,0xbd9b,0xbd9c,0xbd9d,0xbd9e,0xbd9f,
+ 0xbda0,0xbda1,0xbda2,0xbda3,0xbda4,0xbda5,0xbda6,0xbda7,
+ 0xbda8,0xbda9,0xbdaa,0xbdab,0xbdac,0xbdad,0xbdae,0xbdaf,
+ 0xbdb0,0xbdb1,0xbdb2,0xbdb3,0xbdb4,0xbdb5,0xbdb6,0xbdb7,
+ 0xbdb8,0xbdb9,0xbdba,0xbdbb,0xbdbc,0xbdbd,0xbdbe,0xbdbf,
+ 0xbdc0,0xbdc1,0xbdc2,0xbdc3,0xbdc4,0xbdc5,0xbdc6,0xbdc7,
+ 0xbdc8,0xbdc9,0xbdca,0xbdcb,0xbdcc,0xbdcd,0xbdce,0xbdcf,
+ 0xbdd0,0xbdd1,0xbdd2,0xbdd3,0xbdd4,0xbdd5,0xbdd6,0xbdd7,
+ 0xbdd8,0xbdd9,0xbdda,0xbddb,0xbddc,0xbddd,0xbdde,0xbddf,
+ 0xbde0,0xbde1,0xbde2,0xbde3,0xbde4,0xbde5,0xbde6,0xbde7,
+ 0xbde8,0xbde9,0xbdea,0xbdeb,0xbdec,0xbded,0xbdee,0xbdef,
+ 0xbdf0,0xbdf1,0xbdf2,0xbdf3,0xbdf4,0xbdf5,0xbdf6,0xbdf7,
+ 0xbdf8,0xbdf9,0xbdfa,0xbdfb,0xbdfc,0xbdfd,0xbdfe,0xbdff,
+ 0xbe00,0xbe01,0xbe02,0xbe03,0xbe04,0xbe05,0xbe06,0xbe07,
+ 0xbe08,0xbe09,0xbe0a,0xbe0b,0xbe0c,0xbe0d,0xbe0e,0xbe0f,
+ 0xbe10,0xbe11,0xbe12,0xbe13,0xbe14,0xbe15,0xbe16,0xbe17,
+ 0xbe18,0xbe19,0xbe1a,0xbe1b,0xbe1c,0xbe1d,0xbe1e,0xbe1f,
+ 0xbe20,0xbe21,0xbe22,0xbe23,0xbe24,0xbe25,0xbe26,0xbe27,
+ 0xbe28,0xbe29,0xbe2a,0xbe2b,0xbe2c,0xbe2d,0xbe2e,0xbe2f,
+ 0xbe30,0xbe31,0xbe32,0xbe33,0xbe34,0xbe35,0xbe36,0xbe37,
+ 0xbe38,0xbe39,0xbe3a,0xbe3b,0xbe3c,0xbe3d,0xbe3e,0xbe3f,
+ 0xbe40,0xbe41,0xbe42,0xbe43,0xbe44,0xbe45,0xbe46,0xbe47,
+ 0xbe48,0xbe49,0xbe4a,0xbe4b,0xbe4c,0xbe4d,0xbe4e,0xbe4f,
+ 0xbe50,0xbe51,0xbe52,0xbe53,0xbe54,0xbe55,0xbe56,0xbe57,
+ 0xbe58,0xbe59,0xbe5a,0xbe5b,0xbe5c,0xbe5d,0xbe5e,0xbe5f,
+ 0xbe60,0xbe61,0xbe62,0xbe63,0xbe64,0xbe65,0xbe66,0xbe67,
+ 0xbe68,0xbe69,0xbe6a,0xbe6b,0xbe6c,0xbe6d,0xbe6e,0xbe6f,
+ 0xbe70,0xbe71,0xbe72,0xbe73,0xbe74,0xbe75,0xbe76,0xbe77,
+ 0xbe78,0xbe79,0xbe7a,0xbe7b,0xbe7c,0xbe7d,0xbe7e,0xbe7f,
+ 0xbe80,0xbe81,0xbe82,0xbe83,0xbe84,0xbe85,0xbe86,0xbe87,
+ 0xbe88,0xbe89,0xbe8a,0xbe8b,0xbe8c,0xbe8d,0xbe8e,0xbe8f,
+ 0xbe90,0xbe91,0xbe92,0xbe93,0xbe94,0xbe95,0xbe96,0xbe97,
+ 0xbe98,0xbe99,0xbe9a,0xbe9b,0xbe9c,0xbe9d,0xbe9e,0xbe9f,
+ 0xbea0,0xbea1,0xbea2,0xbea3,0xbea4,0xbea5,0xbea6,0xbea7,
+ 0xbea8,0xbea9,0xbeaa,0xbeab,0xbeac,0xbead,0xbeae,0xbeaf,
+ 0xbeb0,0xbeb1,0xbeb2,0xbeb3,0xbeb4,0xbeb5,0xbeb6,0xbeb7,
+ 0xbeb8,0xbeb9,0xbeba,0xbebb,0xbebc,0xbebd,0xbebe,0xbebf,
+ 0xbec0,0xbec1,0xbec2,0xbec3,0xbec4,0xbec5,0xbec6,0xbec7,
+ 0xbec8,0xbec9,0xbeca,0xbecb,0xbecc,0xbecd,0xbece,0xbecf,
+ 0xbed0,0xbed1,0xbed2,0xbed3,0xbed4,0xbed5,0xbed6,0xbed7,
+ 0xbed8,0xbed9,0xbeda,0xbedb,0xbedc,0xbedd,0xbede,0xbedf,
+ 0xbee0,0xbee1,0xbee2,0xbee3,0xbee4,0xbee5,0xbee6,0xbee7,
+ 0xbee8,0xbee9,0xbeea,0xbeeb,0xbeec,0xbeed,0xbeee,0xbeef,
+ 0xbef0,0xbef1,0xbef2,0xbef3,0xbef4,0xbef5,0xbef6,0xbef7,
+ 0xbef8,0xbef9,0xbefa,0xbefb,0xbefc,0xbefd,0xbefe,0xbeff,
+ 0xbf00,0xbf01,0xbf02,0xbf03,0xbf04,0xbf05,0xbf06,0xbf07,
+ 0xbf08,0xbf09,0xbf0a,0xbf0b,0xbf0c,0xbf0d,0xbf0e,0xbf0f,
+ 0xbf10,0xbf11,0xbf12,0xbf13,0xbf14,0xbf15,0xbf16,0xbf17,
+ 0xbf18,0xbf19,0xbf1a,0xbf1b,0xbf1c,0xbf1d,0xbf1e,0xbf1f,
+ 0xbf20,0xbf21,0xbf22,0xbf23,0xbf24,0xbf25,0xbf26,0xbf27,
+ 0xbf28,0xbf29,0xbf2a,0xbf2b,0xbf2c,0xbf2d,0xbf2e,0xbf2f,
+ 0xbf30,0xbf31,0xbf32,0xbf33,0xbf34,0xbf35,0xbf36,0xbf37,
+ 0xbf38,0xbf39,0xbf3a,0xbf3b,0xbf3c,0xbf3d,0xbf3e,0xbf3f,
+ 0xbf40,0xbf41,0xbf42,0xbf43,0xbf44,0xbf45,0xbf46,0xbf47,
+ 0xbf48,0xbf49,0xbf4a,0xbf4b,0xbf4c,0xbf4d,0xbf4e,0xbf4f,
+ 0xbf50,0xbf51,0xbf52,0xbf53,0xbf54,0xbf55,0xbf56,0xbf57,
+ 0xbf58,0xbf59,0xbf5a,0xbf5b,0xbf5c,0xbf5d,0xbf5e,0xbf5f,
+ 0xbf60,0xbf61,0xbf62,0xbf63,0xbf64,0xbf65,0xbf66,0xbf67,
+ 0xbf68,0xbf69,0xbf6a,0xbf6b,0xbf6c,0xbf6d,0xbf6e,0xbf6f,
+ 0xbf70,0xbf71,0xbf72,0xbf73,0xbf74,0xbf75,0xbf76,0xbf77,
+ 0xbf78,0xbf79,0xbf7a,0xbf7b,0xbf7c,0xbf7d,0xbf7e,0xbf7f,
+ 0xbf80,0xbf81,0xbf82,0xbf83,0xbf84,0xbf85,0xbf86,0xbf87,
+ 0xbf88,0xbf89,0xbf8a,0xbf8b,0xbf8c,0xbf8d,0xbf8e,0xbf8f,
+ 0xbf90,0xbf91,0xbf92,0xbf93,0xbf94,0xbf95,0xbf96,0xbf97,
+ 0xbf98,0xbf99,0xbf9a,0xbf9b,0xbf9c,0xbf9d,0xbf9e,0xbf9f,
+ 0xbfa0,0xbfa1,0xbfa2,0xbfa3,0xbfa4,0xbfa5,0xbfa6,0xbfa7,
+ 0xbfa8,0xbfa9,0xbfaa,0xbfab,0xbfac,0xbfad,0xbfae,0xbfaf,
+ 0xbfb0,0xbfb1,0xbfb2,0xbfb3,0xbfb4,0xbfb5,0xbfb6,0xbfb7,
+ 0xbfb8,0xbfb9,0xbfba,0xbfbb,0xbfbc,0xbfbd,0xbfbe,0xbfbf,
+ 0xbfc0,0xbfc1,0xbfc2,0xbfc3,0xbfc4,0xbfc5,0xbfc6,0xbfc7,
+ 0xbfc8,0xbfc9,0xbfca,0xbfcb,0xbfcc,0xbfcd,0xbfce,0xbfcf,
+ 0xbfd0,0xbfd1,0xbfd2,0xbfd3,0xbfd4,0xbfd5,0xbfd6,0xbfd7,
+ 0xbfd8,0xbfd9,0xbfda,0xbfdb,0xbfdc,0xbfdd,0xbfde,0xbfdf,
+ 0xbfe0,0xbfe1,0xbfe2,0xbfe3,0xbfe4,0xbfe5,0xbfe6,0xbfe7,
+ 0xbfe8,0xbfe9,0xbfea,0xbfeb,0xbfec,0xbfed,0xbfee,0xbfef,
+ 0xbff0,0xbff1,0xbff2,0xbff3,0xbff4,0xbff5,0xbff6,0xbff7,
+ 0xbff8,0xbff9,0xbffa,0xbffb,0xbffc,0xbffd,0xbffe,0xbfff,
+ 0xc000,0xc001,0xc002,0xc003,0xc004,0xc005,0xc006,0xc007,
+ 0xc008,0xc009,0xc00a,0xc00b,0xc00c,0xc00d,0xc00e,0xc00f,
+ 0xc010,0xc011,0xc012,0xc013,0xc014,0xc015,0xc016,0xc017,
+ 0xc018,0xc019,0xc01a,0xc01b,0xc01c,0xc01d,0xc01e,0xc01f,
+ 0xc020,0xc021,0xc022,0xc023,0xc024,0xc025,0xc026,0xc027,
+ 0xc028,0xc029,0xc02a,0xc02b,0xc02c,0xc02d,0xc02e,0xc02f,
+ 0xc030,0xc031,0xc032,0xc033,0xc034,0xc035,0xc036,0xc037,
+ 0xc038,0xc039,0xc03a,0xc03b,0xc03c,0xc03d,0xc03e,0xc03f,
+ 0xc040,0xc041,0xc042,0xc043,0xc044,0xc045,0xc046,0xc047,
+ 0xc048,0xc049,0xc04a,0xc04b,0xc04c,0xc04d,0xc04e,0xc04f,
+ 0xc050,0xc051,0xc052,0xc053,0xc054,0xc055,0xc056,0xc057,
+ 0xc058,0xc059,0xc05a,0xc05b,0xc05c,0xc05d,0xc05e,0xc05f,
+ 0xc060,0xc061,0xc062,0xc063,0xc064,0xc065,0xc066,0xc067,
+ 0xc068,0xc069,0xc06a,0xc06b,0xc06c,0xc06d,0xc06e,0xc06f,
+ 0xc070,0xc071,0xc072,0xc073,0xc074,0xc075,0xc076,0xc077,
+ 0xc078,0xc079,0xc07a,0xc07b,0xc07c,0xc07d,0xc07e,0xc07f,
+ 0xc080,0xc081,0xc082,0xc083,0xc084,0xc085,0xc086,0xc087,
+ 0xc088,0xc089,0xc08a,0xc08b,0xc08c,0xc08d,0xc08e,0xc08f,
+ 0xc090,0xc091,0xc092,0xc093,0xc094,0xc095,0xc096,0xc097,
+ 0xc098,0xc099,0xc09a,0xc09b,0xc09c,0xc09d,0xc09e,0xc09f,
+ 0xc0a0,0xc0a1,0xc0a2,0xc0a3,0xc0a4,0xc0a5,0xc0a6,0xc0a7,
+ 0xc0a8,0xc0a9,0xc0aa,0xc0ab,0xc0ac,0xc0ad,0xc0ae,0xc0af,
+ 0xc0b0,0xc0b1,0xc0b2,0xc0b3,0xc0b4,0xc0b5,0xc0b6,0xc0b7,
+ 0xc0b8,0xc0b9,0xc0ba,0xc0bb,0xc0bc,0xc0bd,0xc0be,0xc0bf,
+ 0xc0c0,0xc0c1,0xc0c2,0xc0c3,0xc0c4,0xc0c5,0xc0c6,0xc0c7,
+ 0xc0c8,0xc0c9,0xc0ca,0xc0cb,0xc0cc,0xc0cd,0xc0ce,0xc0cf,
+ 0xc0d0,0xc0d1,0xc0d2,0xc0d3,0xc0d4,0xc0d5,0xc0d6,0xc0d7,
+ 0xc0d8,0xc0d9,0xc0da,0xc0db,0xc0dc,0xc0dd,0xc0de,0xc0df,
+ 0xc0e0,0xc0e1,0xc0e2,0xc0e3,0xc0e4,0xc0e5,0xc0e6,0xc0e7,
+ 0xc0e8,0xc0e9,0xc0ea,0xc0eb,0xc0ec,0xc0ed,0xc0ee,0xc0ef,
+ 0xc0f0,0xc0f1,0xc0f2,0xc0f3,0xc0f4,0xc0f5,0xc0f6,0xc0f7,
+ 0xc0f8,0xc0f9,0xc0fa,0xc0fb,0xc0fc,0xc0fd,0xc0fe,0xc0ff,
+ 0xc100,0xc101,0xc102,0xc103,0xc104,0xc105,0xc106,0xc107,
+ 0xc108,0xc109,0xc10a,0xc10b,0xc10c,0xc10d,0xc10e,0xc10f,
+ 0xc110,0xc111,0xc112,0xc113,0xc114,0xc115,0xc116,0xc117,
+ 0xc118,0xc119,0xc11a,0xc11b,0xc11c,0xc11d,0xc11e,0xc11f,
+ 0xc120,0xc121,0xc122,0xc123,0xc124,0xc125,0xc126,0xc127,
+ 0xc128,0xc129,0xc12a,0xc12b,0xc12c,0xc12d,0xc12e,0xc12f,
+ 0xc130,0xc131,0xc132,0xc133,0xc134,0xc135,0xc136,0xc137,
+ 0xc138,0xc139,0xc13a,0xc13b,0xc13c,0xc13d,0xc13e,0xc13f,
+ 0xc140,0xc141,0xc142,0xc143,0xc144,0xc145,0xc146,0xc147,
+ 0xc148,0xc149,0xc14a,0xc14b,0xc14c,0xc14d,0xc14e,0xc14f,
+ 0xc150,0xc151,0xc152,0xc153,0xc154,0xc155,0xc156,0xc157,
+ 0xc158,0xc159,0xc15a,0xc15b,0xc15c,0xc15d,0xc15e,0xc15f,
+ 0xc160,0xc161,0xc162,0xc163,0xc164,0xc165,0xc166,0xc167,
+ 0xc168,0xc169,0xc16a,0xc16b,0xc16c,0xc16d,0xc16e,0xc16f,
+ 0xc170,0xc171,0xc172,0xc173,0xc174,0xc175,0xc176,0xc177,
+ 0xc178,0xc179,0xc17a,0xc17b,0xc17c,0xc17d,0xc17e,0xc17f,
+ 0xc180,0xc181,0xc182,0xc183,0xc184,0xc185,0xc186,0xc187,
+ 0xc188,0xc189,0xc18a,0xc18b,0xc18c,0xc18d,0xc18e,0xc18f,
+ 0xc190,0xc191,0xc192,0xc193,0xc194,0xc195,0xc196,0xc197,
+ 0xc198,0xc199,0xc19a,0xc19b,0xc19c,0xc19d,0xc19e,0xc19f,
+ 0xc1a0,0xc1a1,0xc1a2,0xc1a3,0xc1a4,0xc1a5,0xc1a6,0xc1a7,
+ 0xc1a8,0xc1a9,0xc1aa,0xc1ab,0xc1ac,0xc1ad,0xc1ae,0xc1af,
+ 0xc1b0,0xc1b1,0xc1b2,0xc1b3,0xc1b4,0xc1b5,0xc1b6,0xc1b7,
+ 0xc1b8,0xc1b9,0xc1ba,0xc1bb,0xc1bc,0xc1bd,0xc1be,0xc1bf,
+ 0xc1c0,0xc1c1,0xc1c2,0xc1c3,0xc1c4,0xc1c5,0xc1c6,0xc1c7,
+ 0xc1c8,0xc1c9,0xc1ca,0xc1cb,0xc1cc,0xc1cd,0xc1ce,0xc1cf,
+ 0xc1d0,0xc1d1,0xc1d2,0xc1d3,0xc1d4,0xc1d5,0xc1d6,0xc1d7,
+ 0xc1d8,0xc1d9,0xc1da,0xc1db,0xc1dc,0xc1dd,0xc1de,0xc1df,
+ 0xc1e0,0xc1e1,0xc1e2,0xc1e3,0xc1e4,0xc1e5,0xc1e6,0xc1e7,
+ 0xc1e8,0xc1e9,0xc1ea,0xc1eb,0xc1ec,0xc1ed,0xc1ee,0xc1ef,
+ 0xc1f0,0xc1f1,0xc1f2,0xc1f3,0xc1f4,0xc1f5,0xc1f6,0xc1f7,
+ 0xc1f8,0xc1f9,0xc1fa,0xc1fb,0xc1fc,0xc1fd,0xc1fe,0xc1ff,
+ 0xc200,0xc201,0xc202,0xc203,0xc204,0xc205,0xc206,0xc207,
+ 0xc208,0xc209,0xc20a,0xc20b,0xc20c,0xc20d,0xc20e,0xc20f,
+ 0xc210,0xc211,0xc212,0xc213,0xc214,0xc215,0xc216,0xc217,
+ 0xc218,0xc219,0xc21a,0xc21b,0xc21c,0xc21d,0xc21e,0xc21f,
+ 0xc220,0xc221,0xc222,0xc223,0xc224,0xc225,0xc226,0xc227,
+ 0xc228,0xc229,0xc22a,0xc22b,0xc22c,0xc22d,0xc22e,0xc22f,
+ 0xc230,0xc231,0xc232,0xc233,0xc234,0xc235,0xc236,0xc237,
+ 0xc238,0xc239,0xc23a,0xc23b,0xc23c,0xc23d,0xc23e,0xc23f,
+ 0xc240,0xc241,0xc242,0xc243,0xc244,0xc245,0xc246,0xc247,
+ 0xc248,0xc249,0xc24a,0xc24b,0xc24c,0xc24d,0xc24e,0xc24f,
+ 0xc250,0xc251,0xc252,0xc253,0xc254,0xc255,0xc256,0xc257,
+ 0xc258,0xc259,0xc25a,0xc25b,0xc25c,0xc25d,0xc25e,0xc25f,
+ 0xc260,0xc261,0xc262,0xc263,0xc264,0xc265,0xc266,0xc267,
+ 0xc268,0xc269,0xc26a,0xc26b,0xc26c,0xc26d,0xc26e,0xc26f,
+ 0xc270,0xc271,0xc272,0xc273,0xc274,0xc275,0xc276,0xc277,
+ 0xc278,0xc279,0xc27a,0xc27b,0xc27c,0xc27d,0xc27e,0xc27f,
+ 0xc280,0xc281,0xc282,0xc283,0xc284,0xc285,0xc286,0xc287,
+ 0xc288,0xc289,0xc28a,0xc28b,0xc28c,0xc28d,0xc28e,0xc28f,
+ 0xc290,0xc291,0xc292,0xc293,0xc294,0xc295,0xc296,0xc297,
+ 0xc298,0xc299,0xc29a,0xc29b,0xc29c,0xc29d,0xc29e,0xc29f,
+ 0xc2a0,0xc2a1,0xc2a2,0xc2a3,0xc2a4,0xc2a5,0xc2a6,0xc2a7,
+ 0xc2a8,0xc2a9,0xc2aa,0xc2ab,0xc2ac,0xc2ad,0xc2ae,0xc2af,
+ 0xc2b0,0xc2b1,0xc2b2,0xc2b3,0xc2b4,0xc2b5,0xc2b6,0xc2b7,
+ 0xc2b8,0xc2b9,0xc2ba,0xc2bb,0xc2bc,0xc2bd,0xc2be,0xc2bf,
+ 0xc2c0,0xc2c1,0xc2c2,0xc2c3,0xc2c4,0xc2c5,0xc2c6,0xc2c7,
+ 0xc2c8,0xc2c9,0xc2ca,0xc2cb,0xc2cc,0xc2cd,0xc2ce,0xc2cf,
+ 0xc2d0,0xc2d1,0xc2d2,0xc2d3,0xc2d4,0xc2d5,0xc2d6,0xc2d7,
+ 0xc2d8,0xc2d9,0xc2da,0xc2db,0xc2dc,0xc2dd,0xc2de,0xc2df,
+ 0xc2e0,0xc2e1,0xc2e2,0xc2e3,0xc2e4,0xc2e5,0xc2e6,0xc2e7,
+ 0xc2e8,0xc2e9,0xc2ea,0xc2eb,0xc2ec,0xc2ed,0xc2ee,0xc2ef,
+ 0xc2f0,0xc2f1,0xc2f2,0xc2f3,0xc2f4,0xc2f5,0xc2f6,0xc2f7,
+ 0xc2f8,0xc2f9,0xc2fa,0xc2fb,0xc2fc,0xc2fd,0xc2fe,0xc2ff,
+ 0xc300,0xc301,0xc302,0xc303,0xc304,0xc305,0xc306,0xc307,
+ 0xc308,0xc309,0xc30a,0xc30b,0xc30c,0xc30d,0xc30e,0xc30f,
+ 0xc310,0xc311,0xc312,0xc313,0xc314,0xc315,0xc316,0xc317,
+ 0xc318,0xc319,0xc31a,0xc31b,0xc31c,0xc31d,0xc31e,0xc31f,
+ 0xc320,0xc321,0xc322,0xc323,0xc324,0xc325,0xc326,0xc327,
+ 0xc328,0xc329,0xc32a,0xc32b,0xc32c,0xc32d,0xc32e,0xc32f,
+ 0xc330,0xc331,0xc332,0xc333,0xc334,0xc335,0xc336,0xc337,
+ 0xc338,0xc339,0xc33a,0xc33b,0xc33c,0xc33d,0xc33e,0xc33f,
+ 0xc340,0xc341,0xc342,0xc343,0xc344,0xc345,0xc346,0xc347,
+ 0xc348,0xc349,0xc34a,0xc34b,0xc34c,0xc34d,0xc34e,0xc34f,
+ 0xc350,0xc351,0xc352,0xc353,0xc354,0xc355,0xc356,0xc357,
+ 0xc358,0xc359,0xc35a,0xc35b,0xc35c,0xc35d,0xc35e,0xc35f,
+ 0xc360,0xc361,0xc362,0xc363,0xc364,0xc365,0xc366,0xc367,
+ 0xc368,0xc369,0xc36a,0xc36b,0xc36c,0xc36d,0xc36e,0xc36f,
+ 0xc370,0xc371,0xc372,0xc373,0xc374,0xc375,0xc376,0xc377,
+ 0xc378,0xc379,0xc37a,0xc37b,0xc37c,0xc37d,0xc37e,0xc37f,
+ 0xc380,0xc381,0xc382,0xc383,0xc384,0xc385,0xc386,0xc387,
+ 0xc388,0xc389,0xc38a,0xc38b,0xc38c,0xc38d,0xc38e,0xc38f,
+ 0xc390,0xc391,0xc392,0xc393,0xc394,0xc395,0xc396,0xc397,
+ 0xc398,0xc399,0xc39a,0xc39b,0xc39c,0xc39d,0xc39e,0xc39f,
+ 0xc3a0,0xc3a1,0xc3a2,0xc3a3,0xc3a4,0xc3a5,0xc3a6,0xc3a7,
+ 0xc3a8,0xc3a9,0xc3aa,0xc3ab,0xc3ac,0xc3ad,0xc3ae,0xc3af,
+ 0xc3b0,0xc3b1,0xc3b2,0xc3b3,0xc3b4,0xc3b5,0xc3b6,0xc3b7,
+ 0xc3b8,0xc3b9,0xc3ba,0xc3bb,0xc3bc,0xc3bd,0xc3be,0xc3bf,
+ 0xc3c0,0xc3c1,0xc3c2,0xc3c3,0xc3c4,0xc3c5,0xc3c6,0xc3c7,
+ 0xc3c8,0xc3c9,0xc3ca,0xc3cb,0xc3cc,0xc3cd,0xc3ce,0xc3cf,
+ 0xc3d0,0xc3d1,0xc3d2,0xc3d3,0xc3d4,0xc3d5,0xc3d6,0xc3d7,
+ 0xc3d8,0xc3d9,0xc3da,0xc3db,0xc3dc,0xc3dd,0xc3de,0xc3df,
+ 0xc3e0,0xc3e1,0xc3e2,0xc3e3,0xc3e4,0xc3e5,0xc3e6,0xc3e7,
+ 0xc3e8,0xc3e9,0xc3ea,0xc3eb,0xc3ec,0xc3ed,0xc3ee,0xc3ef,
+ 0xc3f0,0xc3f1,0xc3f2,0xc3f3,0xc3f4,0xc3f5,0xc3f6,0xc3f7,
+ 0xc3f8,0xc3f9,0xc3fa,0xc3fb,0xc3fc,0xc3fd,0xc3fe,0xc3ff,
+ 0xc400,0xc401,0xc402,0xc403,0xc404,0xc405,0xc406,0xc407,
+ 0xc408,0xc409,0xc40a,0xc40b,0xc40c,0xc40d,0xc40e,0xc40f,
+ 0xc410,0xc411,0xc412,0xc413,0xc414,0xc415,0xc416,0xc417,
+ 0xc418,0xc419,0xc41a,0xc41b,0xc41c,0xc41d,0xc41e,0xc41f,
+ 0xc420,0xc421,0xc422,0xc423,0xc424,0xc425,0xc426,0xc427,
+ 0xc428,0xc429,0xc42a,0xc42b,0xc42c,0xc42d,0xc42e,0xc42f,
+ 0xc430,0xc431,0xc432,0xc433,0xc434,0xc435,0xc436,0xc437,
+ 0xc438,0xc439,0xc43a,0xc43b,0xc43c,0xc43d,0xc43e,0xc43f,
+ 0xc440,0xc441,0xc442,0xc443,0xc444,0xc445,0xc446,0xc447,
+ 0xc448,0xc449,0xc44a,0xc44b,0xc44c,0xc44d,0xc44e,0xc44f,
+ 0xc450,0xc451,0xc452,0xc453,0xc454,0xc455,0xc456,0xc457,
+ 0xc458,0xc459,0xc45a,0xc45b,0xc45c,0xc45d,0xc45e,0xc45f,
+ 0xc460,0xc461,0xc462,0xc463,0xc464,0xc465,0xc466,0xc467,
+ 0xc468,0xc469,0xc46a,0xc46b,0xc46c,0xc46d,0xc46e,0xc46f,
+ 0xc470,0xc471,0xc472,0xc473,0xc474,0xc475,0xc476,0xc477,
+ 0xc478,0xc479,0xc47a,0xc47b,0xc47c,0xc47d,0xc47e,0xc47f,
+ 0xc480,0xc481,0xc482,0xc483,0xc484,0xc485,0xc486,0xc487,
+ 0xc488,0xc489,0xc48a,0xc48b,0xc48c,0xc48d,0xc48e,0xc48f,
+ 0xc490,0xc491,0xc492,0xc493,0xc494,0xc495,0xc496,0xc497,
+ 0xc498,0xc499,0xc49a,0xc49b,0xc49c,0xc49d,0xc49e,0xc49f,
+ 0xc4a0,0xc4a1,0xc4a2,0xc4a3,0xc4a4,0xc4a5,0xc4a6,0xc4a7,
+ 0xc4a8,0xc4a9,0xc4aa,0xc4ab,0xc4ac,0xc4ad,0xc4ae,0xc4af,
+ 0xc4b0,0xc4b1,0xc4b2,0xc4b3,0xc4b4,0xc4b5,0xc4b6,0xc4b7,
+ 0xc4b8,0xc4b9,0xc4ba,0xc4bb,0xc4bc,0xc4bd,0xc4be,0xc4bf,
+ 0xc4c0,0xc4c1,0xc4c2,0xc4c3,0xc4c4,0xc4c5,0xc4c6,0xc4c7,
+ 0xc4c8,0xc4c9,0xc4ca,0xc4cb,0xc4cc,0xc4cd,0xc4ce,0xc4cf,
+ 0xc4d0,0xc4d1,0xc4d2,0xc4d3,0xc4d4,0xc4d5,0xc4d6,0xc4d7,
+ 0xc4d8,0xc4d9,0xc4da,0xc4db,0xc4dc,0xc4dd,0xc4de,0xc4df,
+ 0xc4e0,0xc4e1,0xc4e2,0xc4e3,0xc4e4,0xc4e5,0xc4e6,0xc4e7,
+ 0xc4e8,0xc4e9,0xc4ea,0xc4eb,0xc4ec,0xc4ed,0xc4ee,0xc4ef,
+ 0xc4f0,0xc4f1,0xc4f2,0xc4f3,0xc4f4,0xc4f5,0xc4f6,0xc4f7,
+ 0xc4f8,0xc4f9,0xc4fa,0xc4fb,0xc4fc,0xc4fd,0xc4fe,0xc4ff,
+ 0xc500,0xc501,0xc502,0xc503,0xc504,0xc505,0xc506,0xc507,
+ 0xc508,0xc509,0xc50a,0xc50b,0xc50c,0xc50d,0xc50e,0xc50f,
+ 0xc510,0xc511,0xc512,0xc513,0xc514,0xc515,0xc516,0xc517,
+ 0xc518,0xc519,0xc51a,0xc51b,0xc51c,0xc51d,0xc51e,0xc51f,
+ 0xc520,0xc521,0xc522,0xc523,0xc524,0xc525,0xc526,0xc527,
+ 0xc528,0xc529,0xc52a,0xc52b,0xc52c,0xc52d,0xc52e,0xc52f,
+ 0xc530,0xc531,0xc532,0xc533,0xc534,0xc535,0xc536,0xc537,
+ 0xc538,0xc539,0xc53a,0xc53b,0xc53c,0xc53d,0xc53e,0xc53f,
+ 0xc540,0xc541,0xc542,0xc543,0xc544,0xc545,0xc546,0xc547,
+ 0xc548,0xc549,0xc54a,0xc54b,0xc54c,0xc54d,0xc54e,0xc54f,
+ 0xc550,0xc551,0xc552,0xc553,0xc554,0xc555,0xc556,0xc557,
+ 0xc558,0xc559,0xc55a,0xc55b,0xc55c,0xc55d,0xc55e,0xc55f,
+ 0xc560,0xc561,0xc562,0xc563,0xc564,0xc565,0xc566,0xc567,
+ 0xc568,0xc569,0xc56a,0xc56b,0xc56c,0xc56d,0xc56e,0xc56f,
+ 0xc570,0xc571,0xc572,0xc573,0xc574,0xc575,0xc576,0xc577,
+ 0xc578,0xc579,0xc57a,0xc57b,0xc57c,0xc57d,0xc57e,0xc57f,
+ 0xc580,0xc581,0xc582,0xc583,0xc584,0xc585,0xc586,0xc587,
+ 0xc588,0xc589,0xc58a,0xc58b,0xc58c,0xc58d,0xc58e,0xc58f,
+ 0xc590,0xc591,0xc592,0xc593,0xc594,0xc595,0xc596,0xc597,
+ 0xc598,0xc599,0xc59a,0xc59b,0xc59c,0xc59d,0xc59e,0xc59f,
+ 0xc5a0,0xc5a1,0xc5a2,0xc5a3,0xc5a4,0xc5a5,0xc5a6,0xc5a7,
+ 0xc5a8,0xc5a9,0xc5aa,0xc5ab,0xc5ac,0xc5ad,0xc5ae,0xc5af,
+ 0xc5b0,0xc5b1,0xc5b2,0xc5b3,0xc5b4,0xc5b5,0xc5b6,0xc5b7,
+ 0xc5b8,0xc5b9,0xc5ba,0xc5bb,0xc5bc,0xc5bd,0xc5be,0xc5bf,
+ 0xc5c0,0xc5c1,0xc5c2,0xc5c3,0xc5c4,0xc5c5,0xc5c6,0xc5c7,
+ 0xc5c8,0xc5c9,0xc5ca,0xc5cb,0xc5cc,0xc5cd,0xc5ce,0xc5cf,
+ 0xc5d0,0xc5d1,0xc5d2,0xc5d3,0xc5d4,0xc5d5,0xc5d6,0xc5d7,
+ 0xc5d8,0xc5d9,0xc5da,0xc5db,0xc5dc,0xc5dd,0xc5de,0xc5df,
+ 0xc5e0,0xc5e1,0xc5e2,0xc5e3,0xc5e4,0xc5e5,0xc5e6,0xc5e7,
+ 0xc5e8,0xc5e9,0xc5ea,0xc5eb,0xc5ec,0xc5ed,0xc5ee,0xc5ef,
+ 0xc5f0,0xc5f1,0xc5f2,0xc5f3,0xc5f4,0xc5f5,0xc5f6,0xc5f7,
+ 0xc5f8,0xc5f9,0xc5fa,0xc5fb,0xc5fc,0xc5fd,0xc5fe,0xc5ff,
+ 0xc600,0xc601,0xc602,0xc603,0xc604,0xc605,0xc606,0xc607,
+ 0xc608,0xc609,0xc60a,0xc60b,0xc60c,0xc60d,0xc60e,0xc60f,
+ 0xc610,0xc611,0xc612,0xc613,0xc614,0xc615,0xc616,0xc617,
+ 0xc618,0xc619,0xc61a,0xc61b,0xc61c,0xc61d,0xc61e,0xc61f,
+ 0xc620,0xc621,0xc622,0xc623,0xc624,0xc625,0xc626,0xc627,
+ 0xc628,0xc629,0xc62a,0xc62b,0xc62c,0xc62d,0xc62e,0xc62f,
+ 0xc630,0xc631,0xc632,0xc633,0xc634,0xc635,0xc636,0xc637,
+ 0xc638,0xc639,0xc63a,0xc63b,0xc63c,0xc63d,0xc63e,0xc63f,
+ 0xc640,0xc641,0xc642,0xc643,0xc644,0xc645,0xc646,0xc647,
+ 0xc648,0xc649,0xc64a,0xc64b,0xc64c,0xc64d,0xc64e,0xc64f,
+ 0xc650,0xc651,0xc652,0xc653,0xc654,0xc655,0xc656,0xc657,
+ 0xc658,0xc659,0xc65a,0xc65b,0xc65c,0xc65d,0xc65e,0xc65f,
+ 0xc660,0xc661,0xc662,0xc663,0xc664,0xc665,0xc666,0xc667,
+ 0xc668,0xc669,0xc66a,0xc66b,0xc66c,0xc66d,0xc66e,0xc66f,
+ 0xc670,0xc671,0xc672,0xc673,0xc674,0xc675,0xc676,0xc677,
+ 0xc678,0xc679,0xc67a,0xc67b,0xc67c,0xc67d,0xc67e,0xc67f,
+ 0xc680,0xc681,0xc682,0xc683,0xc684,0xc685,0xc686,0xc687,
+ 0xc688,0xc689,0xc68a,0xc68b,0xc68c,0xc68d,0xc68e,0xc68f,
+ 0xc690,0xc691,0xc692,0xc693,0xc694,0xc695,0xc696,0xc697,
+ 0xc698,0xc699,0xc69a,0xc69b,0xc69c,0xc69d,0xc69e,0xc69f,
+ 0xc6a0,0xc6a1,0xc6a2,0xc6a3,0xc6a4,0xc6a5,0xc6a6,0xc6a7,
+ 0xc6a8,0xc6a9,0xc6aa,0xc6ab,0xc6ac,0xc6ad,0xc6ae,0xc6af,
+ 0xc6b0,0xc6b1,0xc6b2,0xc6b3,0xc6b4,0xc6b5,0xc6b6,0xc6b7,
+ 0xc6b8,0xc6b9,0xc6ba,0xc6bb,0xc6bc,0xc6bd,0xc6be,0xc6bf,
+ 0xc6c0,0xc6c1,0xc6c2,0xc6c3,0xc6c4,0xc6c5,0xc6c6,0xc6c7,
+ 0xc6c8,0xc6c9,0xc6ca,0xc6cb,0xc6cc,0xc6cd,0xc6ce,0xc6cf,
+ 0xc6d0,0xc6d1,0xc6d2,0xc6d3,0xc6d4,0xc6d5,0xc6d6,0xc6d7,
+ 0xc6d8,0xc6d9,0xc6da,0xc6db,0xc6dc,0xc6dd,0xc6de,0xc6df,
+ 0xc6e0,0xc6e1,0xc6e2,0xc6e3,0xc6e4,0xc6e5,0xc6e6,0xc6e7,
+ 0xc6e8,0xc6e9,0xc6ea,0xc6eb,0xc6ec,0xc6ed,0xc6ee,0xc6ef,
+ 0xc6f0,0xc6f1,0xc6f2,0xc6f3,0xc6f4,0xc6f5,0xc6f6,0xc6f7,
+ 0xc6f8,0xc6f9,0xc6fa,0xc6fb,0xc6fc,0xc6fd,0xc6fe,0xc6ff,
+ 0xc700,0xc701,0xc702,0xc703,0xc704,0xc705,0xc706,0xc707,
+ 0xc708,0xc709,0xc70a,0xc70b,0xc70c,0xc70d,0xc70e,0xc70f,
+ 0xc710,0xc711,0xc712,0xc713,0xc714,0xc715,0xc716,0xc717,
+ 0xc718,0xc719,0xc71a,0xc71b,0xc71c,0xc71d,0xc71e,0xc71f,
+ 0xc720,0xc721,0xc722,0xc723,0xc724,0xc725,0xc726,0xc727,
+ 0xc728,0xc729,0xc72a,0xc72b,0xc72c,0xc72d,0xc72e,0xc72f,
+ 0xc730,0xc731,0xc732,0xc733,0xc734,0xc735,0xc736,0xc737,
+ 0xc738,0xc739,0xc73a,0xc73b,0xc73c,0xc73d,0xc73e,0xc73f,
+ 0xc740,0xc741,0xc742,0xc743,0xc744,0xc745,0xc746,0xc747,
+ 0xc748,0xc749,0xc74a,0xc74b,0xc74c,0xc74d,0xc74e,0xc74f,
+ 0xc750,0xc751,0xc752,0xc753,0xc754,0xc755,0xc756,0xc757,
+ 0xc758,0xc759,0xc75a,0xc75b,0xc75c,0xc75d,0xc75e,0xc75f,
+ 0xc760,0xc761,0xc762,0xc763,0xc764,0xc765,0xc766,0xc767,
+ 0xc768,0xc769,0xc76a,0xc76b,0xc76c,0xc76d,0xc76e,0xc76f,
+ 0xc770,0xc771,0xc772,0xc773,0xc774,0xc775,0xc776,0xc777,
+ 0xc778,0xc779,0xc77a,0xc77b,0xc77c,0xc77d,0xc77e,0xc77f,
+ 0xc780,0xc781,0xc782,0xc783,0xc784,0xc785,0xc786,0xc787,
+ 0xc788,0xc789,0xc78a,0xc78b,0xc78c,0xc78d,0xc78e,0xc78f,
+ 0xc790,0xc791,0xc792,0xc793,0xc794,0xc795,0xc796,0xc797,
+ 0xc798,0xc799,0xc79a,0xc79b,0xc79c,0xc79d,0xc79e,0xc79f,
+ 0xc7a0,0xc7a1,0xc7a2,0xc7a3,0xc7a4,0xc7a5,0xc7a6,0xc7a7,
+ 0xc7a8,0xc7a9,0xc7aa,0xc7ab,0xc7ac,0xc7ad,0xc7ae,0xc7af,
+ 0xc7b0,0xc7b1,0xc7b2,0xc7b3,0xc7b4,0xc7b5,0xc7b6,0xc7b7,
+ 0xc7b8,0xc7b9,0xc7ba,0xc7bb,0xc7bc,0xc7bd,0xc7be,0xc7bf,
+ 0xc7c0,0xc7c1,0xc7c2,0xc7c3,0xc7c4,0xc7c5,0xc7c6,0xc7c7,
+ 0xc7c8,0xc7c9,0xc7ca,0xc7cb,0xc7cc,0xc7cd,0xc7ce,0xc7cf,
+ 0xc7d0,0xc7d1,0xc7d2,0xc7d3,0xc7d4,0xc7d5,0xc7d6,0xc7d7,
+ 0xc7d8,0xc7d9,0xc7da,0xc7db,0xc7dc,0xc7dd,0xc7de,0xc7df,
+ 0xc7e0,0xc7e1,0xc7e2,0xc7e3,0xc7e4,0xc7e5,0xc7e6,0xc7e7,
+ 0xc7e8,0xc7e9,0xc7ea,0xc7eb,0xc7ec,0xc7ed,0xc7ee,0xc7ef,
+ 0xc7f0,0xc7f1,0xc7f2,0xc7f3,0xc7f4,0xc7f5,0xc7f6,0xc7f7,
+ 0xc7f8,0xc7f9,0xc7fa,0xc7fb,0xc7fc,0xc7fd,0xc7fe,0xc7ff,
+ 0xc800,0xc801,0xc802,0xc803,0xc804,0xc805,0xc806,0xc807,
+ 0xc808,0xc809,0xc80a,0xc80b,0xc80c,0xc80d,0xc80e,0xc80f,
+ 0xc810,0xc811,0xc812,0xc813,0xc814,0xc815,0xc816,0xc817,
+ 0xc818,0xc819,0xc81a,0xc81b,0xc81c,0xc81d,0xc81e,0xc81f,
+ 0xc820,0xc821,0xc822,0xc823,0xc824,0xc825,0xc826,0xc827,
+ 0xc828,0xc829,0xc82a,0xc82b,0xc82c,0xc82d,0xc82e,0xc82f,
+ 0xc830,0xc831,0xc832,0xc833,0xc834,0xc835,0xc836,0xc837,
+ 0xc838,0xc839,0xc83a,0xc83b,0xc83c,0xc83d,0xc83e,0xc83f,
+ 0xc840,0xc841,0xc842,0xc843,0xc844,0xc845,0xc846,0xc847,
+ 0xc848,0xc849,0xc84a,0xc84b,0xc84c,0xc84d,0xc84e,0xc84f,
+ 0xc850,0xc851,0xc852,0xc853,0xc854,0xc855,0xc856,0xc857,
+ 0xc858,0xc859,0xc85a,0xc85b,0xc85c,0xc85d,0xc85e,0xc85f,
+ 0xc860,0xc861,0xc862,0xc863,0xc864,0xc865,0xc866,0xc867,
+ 0xc868,0xc869,0xc86a,0xc86b,0xc86c,0xc86d,0xc86e,0xc86f,
+ 0xc870,0xc871,0xc872,0xc873,0xc874,0xc875,0xc876,0xc877,
+ 0xc878,0xc879,0xc87a,0xc87b,0xc87c,0xc87d,0xc87e,0xc87f,
+ 0xc880,0xc881,0xc882,0xc883,0xc884,0xc885,0xc886,0xc887,
+ 0xc888,0xc889,0xc88a,0xc88b,0xc88c,0xc88d,0xc88e,0xc88f,
+ 0xc890,0xc891,0xc892,0xc893,0xc894,0xc895,0xc896,0xc897,
+ 0xc898,0xc899,0xc89a,0xc89b,0xc89c,0xc89d,0xc89e,0xc89f,
+ 0xc8a0,0xc8a1,0xc8a2,0xc8a3,0xc8a4,0xc8a5,0xc8a6,0xc8a7,
+ 0xc8a8,0xc8a9,0xc8aa,0xc8ab,0xc8ac,0xc8ad,0xc8ae,0xc8af,
+ 0xc8b0,0xc8b1,0xc8b2,0xc8b3,0xc8b4,0xc8b5,0xc8b6,0xc8b7,
+ 0xc8b8,0xc8b9,0xc8ba,0xc8bb,0xc8bc,0xc8bd,0xc8be,0xc8bf,
+ 0xc8c0,0xc8c1,0xc8c2,0xc8c3,0xc8c4,0xc8c5,0xc8c6,0xc8c7,
+ 0xc8c8,0xc8c9,0xc8ca,0xc8cb,0xc8cc,0xc8cd,0xc8ce,0xc8cf,
+ 0xc8d0,0xc8d1,0xc8d2,0xc8d3,0xc8d4,0xc8d5,0xc8d6,0xc8d7,
+ 0xc8d8,0xc8d9,0xc8da,0xc8db,0xc8dc,0xc8dd,0xc8de,0xc8df,
+ 0xc8e0,0xc8e1,0xc8e2,0xc8e3,0xc8e4,0xc8e5,0xc8e6,0xc8e7,
+ 0xc8e8,0xc8e9,0xc8ea,0xc8eb,0xc8ec,0xc8ed,0xc8ee,0xc8ef,
+ 0xc8f0,0xc8f1,0xc8f2,0xc8f3,0xc8f4,0xc8f5,0xc8f6,0xc8f7,
+ 0xc8f8,0xc8f9,0xc8fa,0xc8fb,0xc8fc,0xc8fd,0xc8fe,0xc8ff,
+ 0xc900,0xc901,0xc902,0xc903,0xc904,0xc905,0xc906,0xc907,
+ 0xc908,0xc909,0xc90a,0xc90b,0xc90c,0xc90d,0xc90e,0xc90f,
+ 0xc910,0xc911,0xc912,0xc913,0xc914,0xc915,0xc916,0xc917,
+ 0xc918,0xc919,0xc91a,0xc91b,0xc91c,0xc91d,0xc91e,0xc91f,
+ 0xc920,0xc921,0xc922,0xc923,0xc924,0xc925,0xc926,0xc927,
+ 0xc928,0xc929,0xc92a,0xc92b,0xc92c,0xc92d,0xc92e,0xc92f,
+ 0xc930,0xc931,0xc932,0xc933,0xc934,0xc935,0xc936,0xc937,
+ 0xc938,0xc939,0xc93a,0xc93b,0xc93c,0xc93d,0xc93e,0xc93f,
+ 0xc940,0xc941,0xc942,0xc943,0xc944,0xc945,0xc946,0xc947,
+ 0xc948,0xc949,0xc94a,0xc94b,0xc94c,0xc94d,0xc94e,0xc94f,
+ 0xc950,0xc951,0xc952,0xc953,0xc954,0xc955,0xc956,0xc957,
+ 0xc958,0xc959,0xc95a,0xc95b,0xc95c,0xc95d,0xc95e,0xc95f,
+ 0xc960,0xc961,0xc962,0xc963,0xc964,0xc965,0xc966,0xc967,
+ 0xc968,0xc969,0xc96a,0xc96b,0xc96c,0xc96d,0xc96e,0xc96f,
+ 0xc970,0xc971,0xc972,0xc973,0xc974,0xc975,0xc976,0xc977,
+ 0xc978,0xc979,0xc97a,0xc97b,0xc97c,0xc97d,0xc97e,0xc97f,
+ 0xc980,0xc981,0xc982,0xc983,0xc984,0xc985,0xc986,0xc987,
+ 0xc988,0xc989,0xc98a,0xc98b,0xc98c,0xc98d,0xc98e,0xc98f,
+ 0xc990,0xc991,0xc992,0xc993,0xc994,0xc995,0xc996,0xc997,
+ 0xc998,0xc999,0xc99a,0xc99b,0xc99c,0xc99d,0xc99e,0xc99f,
+ 0xc9a0,0xc9a1,0xc9a2,0xc9a3,0xc9a4,0xc9a5,0xc9a6,0xc9a7,
+ 0xc9a8,0xc9a9,0xc9aa,0xc9ab,0xc9ac,0xc9ad,0xc9ae,0xc9af,
+ 0xc9b0,0xc9b1,0xc9b2,0xc9b3,0xc9b4,0xc9b5,0xc9b6,0xc9b7,
+ 0xc9b8,0xc9b9,0xc9ba,0xc9bb,0xc9bc,0xc9bd,0xc9be,0xc9bf,
+ 0xc9c0,0xc9c1,0xc9c2,0xc9c3,0xc9c4,0xc9c5,0xc9c6,0xc9c7,
+ 0xc9c8,0xc9c9,0xc9ca,0xc9cb,0xc9cc,0xc9cd,0xc9ce,0xc9cf,
+ 0xc9d0,0xc9d1,0xc9d2,0xc9d3,0xc9d4,0xc9d5,0xc9d6,0xc9d7,
+ 0xc9d8,0xc9d9,0xc9da,0xc9db,0xc9dc,0xc9dd,0xc9de,0xc9df,
+ 0xc9e0,0xc9e1,0xc9e2,0xc9e3,0xc9e4,0xc9e5,0xc9e6,0xc9e7,
+ 0xc9e8,0xc9e9,0xc9ea,0xc9eb,0xc9ec,0xc9ed,0xc9ee,0xc9ef,
+ 0xc9f0,0xc9f1,0xc9f2,0xc9f3,0xc9f4,0xc9f5,0xc9f6,0xc9f7,
+ 0xc9f8,0xc9f9,0xc9fa,0xc9fb,0xc9fc,0xc9fd,0xc9fe,0xc9ff,
+ 0xca00,0xca01,0xca02,0xca03,0xca04,0xca05,0xca06,0xca07,
+ 0xca08,0xca09,0xca0a,0xca0b,0xca0c,0xca0d,0xca0e,0xca0f,
+ 0xca10,0xca11,0xca12,0xca13,0xca14,0xca15,0xca16,0xca17,
+ 0xca18,0xca19,0xca1a,0xca1b,0xca1c,0xca1d,0xca1e,0xca1f,
+ 0xca20,0xca21,0xca22,0xca23,0xca24,0xca25,0xca26,0xca27,
+ 0xca28,0xca29,0xca2a,0xca2b,0xca2c,0xca2d,0xca2e,0xca2f,
+ 0xca30,0xca31,0xca32,0xca33,0xca34,0xca35,0xca36,0xca37,
+ 0xca38,0xca39,0xca3a,0xca3b,0xca3c,0xca3d,0xca3e,0xca3f,
+ 0xca40,0xca41,0xca42,0xca43,0xca44,0xca45,0xca46,0xca47,
+ 0xca48,0xca49,0xca4a,0xca4b,0xca4c,0xca4d,0xca4e,0xca4f,
+ 0xca50,0xca51,0xca52,0xca53,0xca54,0xca55,0xca56,0xca57,
+ 0xca58,0xca59,0xca5a,0xca5b,0xca5c,0xca5d,0xca5e,0xca5f,
+ 0xca60,0xca61,0xca62,0xca63,0xca64,0xca65,0xca66,0xca67,
+ 0xca68,0xca69,0xca6a,0xca6b,0xca6c,0xca6d,0xca6e,0xca6f,
+ 0xca70,0xca71,0xca72,0xca73,0xca74,0xca75,0xca76,0xca77,
+ 0xca78,0xca79,0xca7a,0xca7b,0xca7c,0xca7d,0xca7e,0xca7f,
+ 0xca80,0xca81,0xca82,0xca83,0xca84,0xca85,0xca86,0xca87,
+ 0xca88,0xca89,0xca8a,0xca8b,0xca8c,0xca8d,0xca8e,0xca8f,
+ 0xca90,0xca91,0xca92,0xca93,0xca94,0xca95,0xca96,0xca97,
+ 0xca98,0xca99,0xca9a,0xca9b,0xca9c,0xca9d,0xca9e,0xca9f,
+ 0xcaa0,0xcaa1,0xcaa2,0xcaa3,0xcaa4,0xcaa5,0xcaa6,0xcaa7,
+ 0xcaa8,0xcaa9,0xcaaa,0xcaab,0xcaac,0xcaad,0xcaae,0xcaaf,
+ 0xcab0,0xcab1,0xcab2,0xcab3,0xcab4,0xcab5,0xcab6,0xcab7,
+ 0xcab8,0xcab9,0xcaba,0xcabb,0xcabc,0xcabd,0xcabe,0xcabf,
+ 0xcac0,0xcac1,0xcac2,0xcac3,0xcac4,0xcac5,0xcac6,0xcac7,
+ 0xcac8,0xcac9,0xcaca,0xcacb,0xcacc,0xcacd,0xcace,0xcacf,
+ 0xcad0,0xcad1,0xcad2,0xcad3,0xcad4,0xcad5,0xcad6,0xcad7,
+ 0xcad8,0xcad9,0xcada,0xcadb,0xcadc,0xcadd,0xcade,0xcadf,
+ 0xcae0,0xcae1,0xcae2,0xcae3,0xcae4,0xcae5,0xcae6,0xcae7,
+ 0xcae8,0xcae9,0xcaea,0xcaeb,0xcaec,0xcaed,0xcaee,0xcaef,
+ 0xcaf0,0xcaf1,0xcaf2,0xcaf3,0xcaf4,0xcaf5,0xcaf6,0xcaf7,
+ 0xcaf8,0xcaf9,0xcafa,0xcafb,0xcafc,0xcafd,0xcafe,0xcaff,
+ 0xcb00,0xcb01,0xcb02,0xcb03,0xcb04,0xcb05,0xcb06,0xcb07,
+ 0xcb08,0xcb09,0xcb0a,0xcb0b,0xcb0c,0xcb0d,0xcb0e,0xcb0f,
+ 0xcb10,0xcb11,0xcb12,0xcb13,0xcb14,0xcb15,0xcb16,0xcb17,
+ 0xcb18,0xcb19,0xcb1a,0xcb1b,0xcb1c,0xcb1d,0xcb1e,0xcb1f,
+ 0xcb20,0xcb21,0xcb22,0xcb23,0xcb24,0xcb25,0xcb26,0xcb27,
+ 0xcb28,0xcb29,0xcb2a,0xcb2b,0xcb2c,0xcb2d,0xcb2e,0xcb2f,
+ 0xcb30,0xcb31,0xcb32,0xcb33,0xcb34,0xcb35,0xcb36,0xcb37,
+ 0xcb38,0xcb39,0xcb3a,0xcb3b,0xcb3c,0xcb3d,0xcb3e,0xcb3f,
+ 0xcb40,0xcb41,0xcb42,0xcb43,0xcb44,0xcb45,0xcb46,0xcb47,
+ 0xcb48,0xcb49,0xcb4a,0xcb4b,0xcb4c,0xcb4d,0xcb4e,0xcb4f,
+ 0xcb50,0xcb51,0xcb52,0xcb53,0xcb54,0xcb55,0xcb56,0xcb57,
+ 0xcb58,0xcb59,0xcb5a,0xcb5b,0xcb5c,0xcb5d,0xcb5e,0xcb5f,
+ 0xcb60,0xcb61,0xcb62,0xcb63,0xcb64,0xcb65,0xcb66,0xcb67,
+ 0xcb68,0xcb69,0xcb6a,0xcb6b,0xcb6c,0xcb6d,0xcb6e,0xcb6f,
+ 0xcb70,0xcb71,0xcb72,0xcb73,0xcb74,0xcb75,0xcb76,0xcb77,
+ 0xcb78,0xcb79,0xcb7a,0xcb7b,0xcb7c,0xcb7d,0xcb7e,0xcb7f,
+ 0xcb80,0xcb81,0xcb82,0xcb83,0xcb84,0xcb85,0xcb86,0xcb87,
+ 0xcb88,0xcb89,0xcb8a,0xcb8b,0xcb8c,0xcb8d,0xcb8e,0xcb8f,
+ 0xcb90,0xcb91,0xcb92,0xcb93,0xcb94,0xcb95,0xcb96,0xcb97,
+ 0xcb98,0xcb99,0xcb9a,0xcb9b,0xcb9c,0xcb9d,0xcb9e,0xcb9f,
+ 0xcba0,0xcba1,0xcba2,0xcba3,0xcba4,0xcba5,0xcba6,0xcba7,
+ 0xcba8,0xcba9,0xcbaa,0xcbab,0xcbac,0xcbad,0xcbae,0xcbaf,
+ 0xcbb0,0xcbb1,0xcbb2,0xcbb3,0xcbb4,0xcbb5,0xcbb6,0xcbb7,
+ 0xcbb8,0xcbb9,0xcbba,0xcbbb,0xcbbc,0xcbbd,0xcbbe,0xcbbf,
+ 0xcbc0,0xcbc1,0xcbc2,0xcbc3,0xcbc4,0xcbc5,0xcbc6,0xcbc7,
+ 0xcbc8,0xcbc9,0xcbca,0xcbcb,0xcbcc,0xcbcd,0xcbce,0xcbcf,
+ 0xcbd0,0xcbd1,0xcbd2,0xcbd3,0xcbd4,0xcbd5,0xcbd6,0xcbd7,
+ 0xcbd8,0xcbd9,0xcbda,0xcbdb,0xcbdc,0xcbdd,0xcbde,0xcbdf,
+ 0xcbe0,0xcbe1,0xcbe2,0xcbe3,0xcbe4,0xcbe5,0xcbe6,0xcbe7,
+ 0xcbe8,0xcbe9,0xcbea,0xcbeb,0xcbec,0xcbed,0xcbee,0xcbef,
+ 0xcbf0,0xcbf1,0xcbf2,0xcbf3,0xcbf4,0xcbf5,0xcbf6,0xcbf7,
+ 0xcbf8,0xcbf9,0xcbfa,0xcbfb,0xcbfc,0xcbfd,0xcbfe,0xcbff,
+ 0xcc00,0xcc01,0xcc02,0xcc03,0xcc04,0xcc05,0xcc06,0xcc07,
+ 0xcc08,0xcc09,0xcc0a,0xcc0b,0xcc0c,0xcc0d,0xcc0e,0xcc0f,
+ 0xcc10,0xcc11,0xcc12,0xcc13,0xcc14,0xcc15,0xcc16,0xcc17,
+ 0xcc18,0xcc19,0xcc1a,0xcc1b,0xcc1c,0xcc1d,0xcc1e,0xcc1f,
+ 0xcc20,0xcc21,0xcc22,0xcc23,0xcc24,0xcc25,0xcc26,0xcc27,
+ 0xcc28,0xcc29,0xcc2a,0xcc2b,0xcc2c,0xcc2d,0xcc2e,0xcc2f,
+ 0xcc30,0xcc31,0xcc32,0xcc33,0xcc34,0xcc35,0xcc36,0xcc37,
+ 0xcc38,0xcc39,0xcc3a,0xcc3b,0xcc3c,0xcc3d,0xcc3e,0xcc3f,
+ 0xcc40,0xcc41,0xcc42,0xcc43,0xcc44,0xcc45,0xcc46,0xcc47,
+ 0xcc48,0xcc49,0xcc4a,0xcc4b,0xcc4c,0xcc4d,0xcc4e,0xcc4f,
+ 0xcc50,0xcc51,0xcc52,0xcc53,0xcc54,0xcc55,0xcc56,0xcc57,
+ 0xcc58,0xcc59,0xcc5a,0xcc5b,0xcc5c,0xcc5d,0xcc5e,0xcc5f,
+ 0xcc60,0xcc61,0xcc62,0xcc63,0xcc64,0xcc65,0xcc66,0xcc67,
+ 0xcc68,0xcc69,0xcc6a,0xcc6b,0xcc6c,0xcc6d,0xcc6e,0xcc6f,
+ 0xcc70,0xcc71,0xcc72,0xcc73,0xcc74,0xcc75,0xcc76,0xcc77,
+ 0xcc78,0xcc79,0xcc7a,0xcc7b,0xcc7c,0xcc7d,0xcc7e,0xcc7f,
+ 0xcc80,0xcc81,0xcc82,0xcc83,0xcc84,0xcc85,0xcc86,0xcc87,
+ 0xcc88,0xcc89,0xcc8a,0xcc8b,0xcc8c,0xcc8d,0xcc8e,0xcc8f,
+ 0xcc90,0xcc91,0xcc92,0xcc93,0xcc94,0xcc95,0xcc96,0xcc97,
+ 0xcc98,0xcc99,0xcc9a,0xcc9b,0xcc9c,0xcc9d,0xcc9e,0xcc9f,
+ 0xcca0,0xcca1,0xcca2,0xcca3,0xcca4,0xcca5,0xcca6,0xcca7,
+ 0xcca8,0xcca9,0xccaa,0xccab,0xccac,0xccad,0xccae,0xccaf,
+ 0xccb0,0xccb1,0xccb2,0xccb3,0xccb4,0xccb5,0xccb6,0xccb7,
+ 0xccb8,0xccb9,0xccba,0xccbb,0xccbc,0xccbd,0xccbe,0xccbf,
+ 0xccc0,0xccc1,0xccc2,0xccc3,0xccc4,0xccc5,0xccc6,0xccc7,
+ 0xccc8,0xccc9,0xccca,0xcccb,0xcccc,0xcccd,0xccce,0xcccf,
+ 0xccd0,0xccd1,0xccd2,0xccd3,0xccd4,0xccd5,0xccd6,0xccd7,
+ 0xccd8,0xccd9,0xccda,0xccdb,0xccdc,0xccdd,0xccde,0xccdf,
+ 0xcce0,0xcce1,0xcce2,0xcce3,0xcce4,0xcce5,0xcce6,0xcce7,
+ 0xcce8,0xcce9,0xccea,0xcceb,0xccec,0xcced,0xccee,0xccef,
+ 0xccf0,0xccf1,0xccf2,0xccf3,0xccf4,0xccf5,0xccf6,0xccf7,
+ 0xccf8,0xccf9,0xccfa,0xccfb,0xccfc,0xccfd,0xccfe,0xccff,
+ 0xcd00,0xcd01,0xcd02,0xcd03,0xcd04,0xcd05,0xcd06,0xcd07,
+ 0xcd08,0xcd09,0xcd0a,0xcd0b,0xcd0c,0xcd0d,0xcd0e,0xcd0f,
+ 0xcd10,0xcd11,0xcd12,0xcd13,0xcd14,0xcd15,0xcd16,0xcd17,
+ 0xcd18,0xcd19,0xcd1a,0xcd1b,0xcd1c,0xcd1d,0xcd1e,0xcd1f,
+ 0xcd20,0xcd21,0xcd22,0xcd23,0xcd24,0xcd25,0xcd26,0xcd27,
+ 0xcd28,0xcd29,0xcd2a,0xcd2b,0xcd2c,0xcd2d,0xcd2e,0xcd2f,
+ 0xcd30,0xcd31,0xcd32,0xcd33,0xcd34,0xcd35,0xcd36,0xcd37,
+ 0xcd38,0xcd39,0xcd3a,0xcd3b,0xcd3c,0xcd3d,0xcd3e,0xcd3f,
+ 0xcd40,0xcd41,0xcd42,0xcd43,0xcd44,0xcd45,0xcd46,0xcd47,
+ 0xcd48,0xcd49,0xcd4a,0xcd4b,0xcd4c,0xcd4d,0xcd4e,0xcd4f,
+ 0xcd50,0xcd51,0xcd52,0xcd53,0xcd54,0xcd55,0xcd56,0xcd57,
+ 0xcd58,0xcd59,0xcd5a,0xcd5b,0xcd5c,0xcd5d,0xcd5e,0xcd5f,
+ 0xcd60,0xcd61,0xcd62,0xcd63,0xcd64,0xcd65,0xcd66,0xcd67,
+ 0xcd68,0xcd69,0xcd6a,0xcd6b,0xcd6c,0xcd6d,0xcd6e,0xcd6f,
+ 0xcd70,0xcd71,0xcd72,0xcd73,0xcd74,0xcd75,0xcd76,0xcd77,
+ 0xcd78,0xcd79,0xcd7a,0xcd7b,0xcd7c,0xcd7d,0xcd7e,0xcd7f,
+ 0xcd80,0xcd81,0xcd82,0xcd83,0xcd84,0xcd85,0xcd86,0xcd87,
+ 0xcd88,0xcd89,0xcd8a,0xcd8b,0xcd8c,0xcd8d,0xcd8e,0xcd8f,
+ 0xcd90,0xcd91,0xcd92,0xcd93,0xcd94,0xcd95,0xcd96,0xcd97,
+ 0xcd98,0xcd99,0xcd9a,0xcd9b,0xcd9c,0xcd9d,0xcd9e,0xcd9f,
+ 0xcda0,0xcda1,0xcda2,0xcda3,0xcda4,0xcda5,0xcda6,0xcda7,
+ 0xcda8,0xcda9,0xcdaa,0xcdab,0xcdac,0xcdad,0xcdae,0xcdaf,
+ 0xcdb0,0xcdb1,0xcdb2,0xcdb3,0xcdb4,0xcdb5,0xcdb6,0xcdb7,
+ 0xcdb8,0xcdb9,0xcdba,0xcdbb,0xcdbc,0xcdbd,0xcdbe,0xcdbf,
+ 0xcdc0,0xcdc1,0xcdc2,0xcdc3,0xcdc4,0xcdc5,0xcdc6,0xcdc7,
+ 0xcdc8,0xcdc9,0xcdca,0xcdcb,0xcdcc,0xcdcd,0xcdce,0xcdcf,
+ 0xcdd0,0xcdd1,0xcdd2,0xcdd3,0xcdd4,0xcdd5,0xcdd6,0xcdd7,
+ 0xcdd8,0xcdd9,0xcdda,0xcddb,0xcddc,0xcddd,0xcdde,0xcddf,
+ 0xcde0,0xcde1,0xcde2,0xcde3,0xcde4,0xcde5,0xcde6,0xcde7,
+ 0xcde8,0xcde9,0xcdea,0xcdeb,0xcdec,0xcded,0xcdee,0xcdef,
+ 0xcdf0,0xcdf1,0xcdf2,0xcdf3,0xcdf4,0xcdf5,0xcdf6,0xcdf7,
+ 0xcdf8,0xcdf9,0xcdfa,0xcdfb,0xcdfc,0xcdfd,0xcdfe,0xcdff,
+ 0xce00,0xce01,0xce02,0xce03,0xce04,0xce05,0xce06,0xce07,
+ 0xce08,0xce09,0xce0a,0xce0b,0xce0c,0xce0d,0xce0e,0xce0f,
+ 0xce10,0xce11,0xce12,0xce13,0xce14,0xce15,0xce16,0xce17,
+ 0xce18,0xce19,0xce1a,0xce1b,0xce1c,0xce1d,0xce1e,0xce1f,
+ 0xce20,0xce21,0xce22,0xce23,0xce24,0xce25,0xce26,0xce27,
+ 0xce28,0xce29,0xce2a,0xce2b,0xce2c,0xce2d,0xce2e,0xce2f,
+ 0xce30,0xce31,0xce32,0xce33,0xce34,0xce35,0xce36,0xce37,
+ 0xce38,0xce39,0xce3a,0xce3b,0xce3c,0xce3d,0xce3e,0xce3f,
+ 0xce40,0xce41,0xce42,0xce43,0xce44,0xce45,0xce46,0xce47,
+ 0xce48,0xce49,0xce4a,0xce4b,0xce4c,0xce4d,0xce4e,0xce4f,
+ 0xce50,0xce51,0xce52,0xce53,0xce54,0xce55,0xce56,0xce57,
+ 0xce58,0xce59,0xce5a,0xce5b,0xce5c,0xce5d,0xce5e,0xce5f,
+ 0xce60,0xce61,0xce62,0xce63,0xce64,0xce65,0xce66,0xce67,
+ 0xce68,0xce69,0xce6a,0xce6b,0xce6c,0xce6d,0xce6e,0xce6f,
+ 0xce70,0xce71,0xce72,0xce73,0xce74,0xce75,0xce76,0xce77,
+ 0xce78,0xce79,0xce7a,0xce7b,0xce7c,0xce7d,0xce7e,0xce7f,
+ 0xce80,0xce81,0xce82,0xce83,0xce84,0xce85,0xce86,0xce87,
+ 0xce88,0xce89,0xce8a,0xce8b,0xce8c,0xce8d,0xce8e,0xce8f,
+ 0xce90,0xce91,0xce92,0xce93,0xce94,0xce95,0xce96,0xce97,
+ 0xce98,0xce99,0xce9a,0xce9b,0xce9c,0xce9d,0xce9e,0xce9f,
+ 0xcea0,0xcea1,0xcea2,0xcea3,0xcea4,0xcea5,0xcea6,0xcea7,
+ 0xcea8,0xcea9,0xceaa,0xceab,0xceac,0xcead,0xceae,0xceaf,
+ 0xceb0,0xceb1,0xceb2,0xceb3,0xceb4,0xceb5,0xceb6,0xceb7,
+ 0xceb8,0xceb9,0xceba,0xcebb,0xcebc,0xcebd,0xcebe,0xcebf,
+ 0xcec0,0xcec1,0xcec2,0xcec3,0xcec4,0xcec5,0xcec6,0xcec7,
+ 0xcec8,0xcec9,0xceca,0xcecb,0xcecc,0xcecd,0xcece,0xcecf,
+ 0xced0,0xced1,0xced2,0xced3,0xced4,0xced5,0xced6,0xced7,
+ 0xced8,0xced9,0xceda,0xcedb,0xcedc,0xcedd,0xcede,0xcedf,
+ 0xcee0,0xcee1,0xcee2,0xcee3,0xcee4,0xcee5,0xcee6,0xcee7,
+ 0xcee8,0xcee9,0xceea,0xceeb,0xceec,0xceed,0xceee,0xceef,
+ 0xcef0,0xcef1,0xcef2,0xcef3,0xcef4,0xcef5,0xcef6,0xcef7,
+ 0xcef8,0xcef9,0xcefa,0xcefb,0xcefc,0xcefd,0xcefe,0xceff,
+ 0xcf00,0xcf01,0xcf02,0xcf03,0xcf04,0xcf05,0xcf06,0xcf07,
+ 0xcf08,0xcf09,0xcf0a,0xcf0b,0xcf0c,0xcf0d,0xcf0e,0xcf0f,
+ 0xcf10,0xcf11,0xcf12,0xcf13,0xcf14,0xcf15,0xcf16,0xcf17,
+ 0xcf18,0xcf19,0xcf1a,0xcf1b,0xcf1c,0xcf1d,0xcf1e,0xcf1f,
+ 0xcf20,0xcf21,0xcf22,0xcf23,0xcf24,0xcf25,0xcf26,0xcf27,
+ 0xcf28,0xcf29,0xcf2a,0xcf2b,0xcf2c,0xcf2d,0xcf2e,0xcf2f,
+ 0xcf30,0xcf31,0xcf32,0xcf33,0xcf34,0xcf35,0xcf36,0xcf37,
+ 0xcf38,0xcf39,0xcf3a,0xcf3b,0xcf3c,0xcf3d,0xcf3e,0xcf3f,
+ 0xcf40,0xcf41,0xcf42,0xcf43,0xcf44,0xcf45,0xcf46,0xcf47,
+ 0xcf48,0xcf49,0xcf4a,0xcf4b,0xcf4c,0xcf4d,0xcf4e,0xcf4f,
+ 0xcf50,0xcf51,0xcf52,0xcf53,0xcf54,0xcf55,0xcf56,0xcf57,
+ 0xcf58,0xcf59,0xcf5a,0xcf5b,0xcf5c,0xcf5d,0xcf5e,0xcf5f,
+ 0xcf60,0xcf61,0xcf62,0xcf63,0xcf64,0xcf65,0xcf66,0xcf67,
+ 0xcf68,0xcf69,0xcf6a,0xcf6b,0xcf6c,0xcf6d,0xcf6e,0xcf6f,
+ 0xcf70,0xcf71,0xcf72,0xcf73,0xcf74,0xcf75,0xcf76,0xcf77,
+ 0xcf78,0xcf79,0xcf7a,0xcf7b,0xcf7c,0xcf7d,0xcf7e,0xcf7f,
+ 0xcf80,0xcf81,0xcf82,0xcf83,0xcf84,0xcf85,0xcf86,0xcf87,
+ 0xcf88,0xcf89,0xcf8a,0xcf8b,0xcf8c,0xcf8d,0xcf8e,0xcf8f,
+ 0xcf90,0xcf91,0xcf92,0xcf93,0xcf94,0xcf95,0xcf96,0xcf97,
+ 0xcf98,0xcf99,0xcf9a,0xcf9b,0xcf9c,0xcf9d,0xcf9e,0xcf9f,
+ 0xcfa0,0xcfa1,0xcfa2,0xcfa3,0xcfa4,0xcfa5,0xcfa6,0xcfa7,
+ 0xcfa8,0xcfa9,0xcfaa,0xcfab,0xcfac,0xcfad,0xcfae,0xcfaf,
+ 0xcfb0,0xcfb1,0xcfb2,0xcfb3,0xcfb4,0xcfb5,0xcfb6,0xcfb7,
+ 0xcfb8,0xcfb9,0xcfba,0xcfbb,0xcfbc,0xcfbd,0xcfbe,0xcfbf,
+ 0xcfc0,0xcfc1,0xcfc2,0xcfc3,0xcfc4,0xcfc5,0xcfc6,0xcfc7,
+ 0xcfc8,0xcfc9,0xcfca,0xcfcb,0xcfcc,0xcfcd,0xcfce,0xcfcf,
+ 0xcfd0,0xcfd1,0xcfd2,0xcfd3,0xcfd4,0xcfd5,0xcfd6,0xcfd7,
+ 0xcfd8,0xcfd9,0xcfda,0xcfdb,0xcfdc,0xcfdd,0xcfde,0xcfdf,
+ 0xcfe0,0xcfe1,0xcfe2,0xcfe3,0xcfe4,0xcfe5,0xcfe6,0xcfe7,
+ 0xcfe8,0xcfe9,0xcfea,0xcfeb,0xcfec,0xcfed,0xcfee,0xcfef,
+ 0xcff0,0xcff1,0xcff2,0xcff3,0xcff4,0xcff5,0xcff6,0xcff7,
+ 0xcff8,0xcff9,0xcffa,0xcffb,0xcffc,0xcffd,0xcffe,0xcfff,
+ 0xd000,0xd001,0xd002,0xd003,0xd004,0xd005,0xd006,0xd007,
+ 0xd008,0xd009,0xd00a,0xd00b,0xd00c,0xd00d,0xd00e,0xd00f,
+ 0xd010,0xd011,0xd012,0xd013,0xd014,0xd015,0xd016,0xd017,
+ 0xd018,0xd019,0xd01a,0xd01b,0xd01c,0xd01d,0xd01e,0xd01f,
+ 0xd020,0xd021,0xd022,0xd023,0xd024,0xd025,0xd026,0xd027,
+ 0xd028,0xd029,0xd02a,0xd02b,0xd02c,0xd02d,0xd02e,0xd02f,
+ 0xd030,0xd031,0xd032,0xd033,0xd034,0xd035,0xd036,0xd037,
+ 0xd038,0xd039,0xd03a,0xd03b,0xd03c,0xd03d,0xd03e,0xd03f,
+ 0xd040,0xd041,0xd042,0xd043,0xd044,0xd045,0xd046,0xd047,
+ 0xd048,0xd049,0xd04a,0xd04b,0xd04c,0xd04d,0xd04e,0xd04f,
+ 0xd050,0xd051,0xd052,0xd053,0xd054,0xd055,0xd056,0xd057,
+ 0xd058,0xd059,0xd05a,0xd05b,0xd05c,0xd05d,0xd05e,0xd05f,
+ 0xd060,0xd061,0xd062,0xd063,0xd064,0xd065,0xd066,0xd067,
+ 0xd068,0xd069,0xd06a,0xd06b,0xd06c,0xd06d,0xd06e,0xd06f,
+ 0xd070,0xd071,0xd072,0xd073,0xd074,0xd075,0xd076,0xd077,
+ 0xd078,0xd079,0xd07a,0xd07b,0xd07c,0xd07d,0xd07e,0xd07f,
+ 0xd080,0xd081,0xd082,0xd083,0xd084,0xd085,0xd086,0xd087,
+ 0xd088,0xd089,0xd08a,0xd08b,0xd08c,0xd08d,0xd08e,0xd08f,
+ 0xd090,0xd091,0xd092,0xd093,0xd094,0xd095,0xd096,0xd097,
+ 0xd098,0xd099,0xd09a,0xd09b,0xd09c,0xd09d,0xd09e,0xd09f,
+ 0xd0a0,0xd0a1,0xd0a2,0xd0a3,0xd0a4,0xd0a5,0xd0a6,0xd0a7,
+ 0xd0a8,0xd0a9,0xd0aa,0xd0ab,0xd0ac,0xd0ad,0xd0ae,0xd0af,
+ 0xd0b0,0xd0b1,0xd0b2,0xd0b3,0xd0b4,0xd0b5,0xd0b6,0xd0b7,
+ 0xd0b8,0xd0b9,0xd0ba,0xd0bb,0xd0bc,0xd0bd,0xd0be,0xd0bf,
+ 0xd0c0,0xd0c1,0xd0c2,0xd0c3,0xd0c4,0xd0c5,0xd0c6,0xd0c7,
+ 0xd0c8,0xd0c9,0xd0ca,0xd0cb,0xd0cc,0xd0cd,0xd0ce,0xd0cf,
+ 0xd0d0,0xd0d1,0xd0d2,0xd0d3,0xd0d4,0xd0d5,0xd0d6,0xd0d7,
+ 0xd0d8,0xd0d9,0xd0da,0xd0db,0xd0dc,0xd0dd,0xd0de,0xd0df,
+ 0xd0e0,0xd0e1,0xd0e2,0xd0e3,0xd0e4,0xd0e5,0xd0e6,0xd0e7,
+ 0xd0e8,0xd0e9,0xd0ea,0xd0eb,0xd0ec,0xd0ed,0xd0ee,0xd0ef,
+ 0xd0f0,0xd0f1,0xd0f2,0xd0f3,0xd0f4,0xd0f5,0xd0f6,0xd0f7,
+ 0xd0f8,0xd0f9,0xd0fa,0xd0fb,0xd0fc,0xd0fd,0xd0fe,0xd0ff,
+ 0xd100,0xd101,0xd102,0xd103,0xd104,0xd105,0xd106,0xd107,
+ 0xd108,0xd109,0xd10a,0xd10b,0xd10c,0xd10d,0xd10e,0xd10f,
+ 0xd110,0xd111,0xd112,0xd113,0xd114,0xd115,0xd116,0xd117,
+ 0xd118,0xd119,0xd11a,0xd11b,0xd11c,0xd11d,0xd11e,0xd11f,
+ 0xd120,0xd121,0xd122,0xd123,0xd124,0xd125,0xd126,0xd127,
+ 0xd128,0xd129,0xd12a,0xd12b,0xd12c,0xd12d,0xd12e,0xd12f,
+ 0xd130,0xd131,0xd132,0xd133,0xd134,0xd135,0xd136,0xd137,
+ 0xd138,0xd139,0xd13a,0xd13b,0xd13c,0xd13d,0xd13e,0xd13f,
+ 0xd140,0xd141,0xd142,0xd143,0xd144,0xd145,0xd146,0xd147,
+ 0xd148,0xd149,0xd14a,0xd14b,0xd14c,0xd14d,0xd14e,0xd14f,
+ 0xd150,0xd151,0xd152,0xd153,0xd154,0xd155,0xd156,0xd157,
+ 0xd158,0xd159,0xd15a,0xd15b,0xd15c,0xd15d,0xd15e,0xd15f,
+ 0xd160,0xd161,0xd162,0xd163,0xd164,0xd165,0xd166,0xd167,
+ 0xd168,0xd169,0xd16a,0xd16b,0xd16c,0xd16d,0xd16e,0xd16f,
+ 0xd170,0xd171,0xd172,0xd173,0xd174,0xd175,0xd176,0xd177,
+ 0xd178,0xd179,0xd17a,0xd17b,0xd17c,0xd17d,0xd17e,0xd17f,
+ 0xd180,0xd181,0xd182,0xd183,0xd184,0xd185,0xd186,0xd187,
+ 0xd188,0xd189,0xd18a,0xd18b,0xd18c,0xd18d,0xd18e,0xd18f,
+ 0xd190,0xd191,0xd192,0xd193,0xd194,0xd195,0xd196,0xd197,
+ 0xd198,0xd199,0xd19a,0xd19b,0xd19c,0xd19d,0xd19e,0xd19f,
+ 0xd1a0,0xd1a1,0xd1a2,0xd1a3,0xd1a4,0xd1a5,0xd1a6,0xd1a7,
+ 0xd1a8,0xd1a9,0xd1aa,0xd1ab,0xd1ac,0xd1ad,0xd1ae,0xd1af,
+ 0xd1b0,0xd1b1,0xd1b2,0xd1b3,0xd1b4,0xd1b5,0xd1b6,0xd1b7,
+ 0xd1b8,0xd1b9,0xd1ba,0xd1bb,0xd1bc,0xd1bd,0xd1be,0xd1bf,
+ 0xd1c0,0xd1c1,0xd1c2,0xd1c3,0xd1c4,0xd1c5,0xd1c6,0xd1c7,
+ 0xd1c8,0xd1c9,0xd1ca,0xd1cb,0xd1cc,0xd1cd,0xd1ce,0xd1cf,
+ 0xd1d0,0xd1d1,0xd1d2,0xd1d3,0xd1d4,0xd1d5,0xd1d6,0xd1d7,
+ 0xd1d8,0xd1d9,0xd1da,0xd1db,0xd1dc,0xd1dd,0xd1de,0xd1df,
+ 0xd1e0,0xd1e1,0xd1e2,0xd1e3,0xd1e4,0xd1e5,0xd1e6,0xd1e7,
+ 0xd1e8,0xd1e9,0xd1ea,0xd1eb,0xd1ec,0xd1ed,0xd1ee,0xd1ef,
+ 0xd1f0,0xd1f1,0xd1f2,0xd1f3,0xd1f4,0xd1f5,0xd1f6,0xd1f7,
+ 0xd1f8,0xd1f9,0xd1fa,0xd1fb,0xd1fc,0xd1fd,0xd1fe,0xd1ff,
+ 0xd200,0xd201,0xd202,0xd203,0xd204,0xd205,0xd206,0xd207,
+ 0xd208,0xd209,0xd20a,0xd20b,0xd20c,0xd20d,0xd20e,0xd20f,
+ 0xd210,0xd211,0xd212,0xd213,0xd214,0xd215,0xd216,0xd217,
+ 0xd218,0xd219,0xd21a,0xd21b,0xd21c,0xd21d,0xd21e,0xd21f,
+ 0xd220,0xd221,0xd222,0xd223,0xd224,0xd225,0xd226,0xd227,
+ 0xd228,0xd229,0xd22a,0xd22b,0xd22c,0xd22d,0xd22e,0xd22f,
+ 0xd230,0xd231,0xd232,0xd233,0xd234,0xd235,0xd236,0xd237,
+ 0xd238,0xd239,0xd23a,0xd23b,0xd23c,0xd23d,0xd23e,0xd23f,
+ 0xd240,0xd241,0xd242,0xd243,0xd244,0xd245,0xd246,0xd247,
+ 0xd248,0xd249,0xd24a,0xd24b,0xd24c,0xd24d,0xd24e,0xd24f,
+ 0xd250,0xd251,0xd252,0xd253,0xd254,0xd255,0xd256,0xd257,
+ 0xd258,0xd259,0xd25a,0xd25b,0xd25c,0xd25d,0xd25e,0xd25f,
+ 0xd260,0xd261,0xd262,0xd263,0xd264,0xd265,0xd266,0xd267,
+ 0xd268,0xd269,0xd26a,0xd26b,0xd26c,0xd26d,0xd26e,0xd26f,
+ 0xd270,0xd271,0xd272,0xd273,0xd274,0xd275,0xd276,0xd277,
+ 0xd278,0xd279,0xd27a,0xd27b,0xd27c,0xd27d,0xd27e,0xd27f,
+ 0xd280,0xd281,0xd282,0xd283,0xd284,0xd285,0xd286,0xd287,
+ 0xd288,0xd289,0xd28a,0xd28b,0xd28c,0xd28d,0xd28e,0xd28f,
+ 0xd290,0xd291,0xd292,0xd293,0xd294,0xd295,0xd296,0xd297,
+ 0xd298,0xd299,0xd29a,0xd29b,0xd29c,0xd29d,0xd29e,0xd29f,
+ 0xd2a0,0xd2a1,0xd2a2,0xd2a3,0xd2a4,0xd2a5,0xd2a6,0xd2a7,
+ 0xd2a8,0xd2a9,0xd2aa,0xd2ab,0xd2ac,0xd2ad,0xd2ae,0xd2af,
+ 0xd2b0,0xd2b1,0xd2b2,0xd2b3,0xd2b4,0xd2b5,0xd2b6,0xd2b7,
+ 0xd2b8,0xd2b9,0xd2ba,0xd2bb,0xd2bc,0xd2bd,0xd2be,0xd2bf,
+ 0xd2c0,0xd2c1,0xd2c2,0xd2c3,0xd2c4,0xd2c5,0xd2c6,0xd2c7,
+ 0xd2c8,0xd2c9,0xd2ca,0xd2cb,0xd2cc,0xd2cd,0xd2ce,0xd2cf,
+ 0xd2d0,0xd2d1,0xd2d2,0xd2d3,0xd2d4,0xd2d5,0xd2d6,0xd2d7,
+ 0xd2d8,0xd2d9,0xd2da,0xd2db,0xd2dc,0xd2dd,0xd2de,0xd2df,
+ 0xd2e0,0xd2e1,0xd2e2,0xd2e3,0xd2e4,0xd2e5,0xd2e6,0xd2e7,
+ 0xd2e8,0xd2e9,0xd2ea,0xd2eb,0xd2ec,0xd2ed,0xd2ee,0xd2ef,
+ 0xd2f0,0xd2f1,0xd2f2,0xd2f3,0xd2f4,0xd2f5,0xd2f6,0xd2f7,
+ 0xd2f8,0xd2f9,0xd2fa,0xd2fb,0xd2fc,0xd2fd,0xd2fe,0xd2ff,
+ 0xd300,0xd301,0xd302,0xd303,0xd304,0xd305,0xd306,0xd307,
+ 0xd308,0xd309,0xd30a,0xd30b,0xd30c,0xd30d,0xd30e,0xd30f,
+ 0xd310,0xd311,0xd312,0xd313,0xd314,0xd315,0xd316,0xd317,
+ 0xd318,0xd319,0xd31a,0xd31b,0xd31c,0xd31d,0xd31e,0xd31f,
+ 0xd320,0xd321,0xd322,0xd323,0xd324,0xd325,0xd326,0xd327,
+ 0xd328,0xd329,0xd32a,0xd32b,0xd32c,0xd32d,0xd32e,0xd32f,
+ 0xd330,0xd331,0xd332,0xd333,0xd334,0xd335,0xd336,0xd337,
+ 0xd338,0xd339,0xd33a,0xd33b,0xd33c,0xd33d,0xd33e,0xd33f,
+ 0xd340,0xd341,0xd342,0xd343,0xd344,0xd345,0xd346,0xd347,
+ 0xd348,0xd349,0xd34a,0xd34b,0xd34c,0xd34d,0xd34e,0xd34f,
+ 0xd350,0xd351,0xd352,0xd353,0xd354,0xd355,0xd356,0xd357,
+ 0xd358,0xd359,0xd35a,0xd35b,0xd35c,0xd35d,0xd35e,0xd35f,
+ 0xd360,0xd361,0xd362,0xd363,0xd364,0xd365,0xd366,0xd367,
+ 0xd368,0xd369,0xd36a,0xd36b,0xd36c,0xd36d,0xd36e,0xd36f,
+ 0xd370,0xd371,0xd372,0xd373,0xd374,0xd375,0xd376,0xd377,
+ 0xd378,0xd379,0xd37a,0xd37b,0xd37c,0xd37d,0xd37e,0xd37f,
+ 0xd380,0xd381,0xd382,0xd383,0xd384,0xd385,0xd386,0xd387,
+ 0xd388,0xd389,0xd38a,0xd38b,0xd38c,0xd38d,0xd38e,0xd38f,
+ 0xd390,0xd391,0xd392,0xd393,0xd394,0xd395,0xd396,0xd397,
+ 0xd398,0xd399,0xd39a,0xd39b,0xd39c,0xd39d,0xd39e,0xd39f,
+ 0xd3a0,0xd3a1,0xd3a2,0xd3a3,0xd3a4,0xd3a5,0xd3a6,0xd3a7,
+ 0xd3a8,0xd3a9,0xd3aa,0xd3ab,0xd3ac,0xd3ad,0xd3ae,0xd3af,
+ 0xd3b0,0xd3b1,0xd3b2,0xd3b3,0xd3b4,0xd3b5,0xd3b6,0xd3b7,
+ 0xd3b8,0xd3b9,0xd3ba,0xd3bb,0xd3bc,0xd3bd,0xd3be,0xd3bf,
+ 0xd3c0,0xd3c1,0xd3c2,0xd3c3,0xd3c4,0xd3c5,0xd3c6,0xd3c7,
+ 0xd3c8,0xd3c9,0xd3ca,0xd3cb,0xd3cc,0xd3cd,0xd3ce,0xd3cf,
+ 0xd3d0,0xd3d1,0xd3d2,0xd3d3,0xd3d4,0xd3d5,0xd3d6,0xd3d7,
+ 0xd3d8,0xd3d9,0xd3da,0xd3db,0xd3dc,0xd3dd,0xd3de,0xd3df,
+ 0xd3e0,0xd3e1,0xd3e2,0xd3e3,0xd3e4,0xd3e5,0xd3e6,0xd3e7,
+ 0xd3e8,0xd3e9,0xd3ea,0xd3eb,0xd3ec,0xd3ed,0xd3ee,0xd3ef,
+ 0xd3f0,0xd3f1,0xd3f2,0xd3f3,0xd3f4,0xd3f5,0xd3f6,0xd3f7,
+ 0xd3f8,0xd3f9,0xd3fa,0xd3fb,0xd3fc,0xd3fd,0xd3fe,0xd3ff,
+ 0xd400,0xd401,0xd402,0xd403,0xd404,0xd405,0xd406,0xd407,
+ 0xd408,0xd409,0xd40a,0xd40b,0xd40c,0xd40d,0xd40e,0xd40f,
+ 0xd410,0xd411,0xd412,0xd413,0xd414,0xd415,0xd416,0xd417,
+ 0xd418,0xd419,0xd41a,0xd41b,0xd41c,0xd41d,0xd41e,0xd41f,
+ 0xd420,0xd421,0xd422,0xd423,0xd424,0xd425,0xd426,0xd427,
+ 0xd428,0xd429,0xd42a,0xd42b,0xd42c,0xd42d,0xd42e,0xd42f,
+ 0xd430,0xd431,0xd432,0xd433,0xd434,0xd435,0xd436,0xd437,
+ 0xd438,0xd439,0xd43a,0xd43b,0xd43c,0xd43d,0xd43e,0xd43f,
+ 0xd440,0xd441,0xd442,0xd443,0xd444,0xd445,0xd446,0xd447,
+ 0xd448,0xd449,0xd44a,0xd44b,0xd44c,0xd44d,0xd44e,0xd44f,
+ 0xd450,0xd451,0xd452,0xd453,0xd454,0xd455,0xd456,0xd457,
+ 0xd458,0xd459,0xd45a,0xd45b,0xd45c,0xd45d,0xd45e,0xd45f,
+ 0xd460,0xd461,0xd462,0xd463,0xd464,0xd465,0xd466,0xd467,
+ 0xd468,0xd469,0xd46a,0xd46b,0xd46c,0xd46d,0xd46e,0xd46f,
+ 0xd470,0xd471,0xd472,0xd473,0xd474,0xd475,0xd476,0xd477,
+ 0xd478,0xd479,0xd47a,0xd47b,0xd47c,0xd47d,0xd47e,0xd47f,
+ 0xd480,0xd481,0xd482,0xd483,0xd484,0xd485,0xd486,0xd487,
+ 0xd488,0xd489,0xd48a,0xd48b,0xd48c,0xd48d,0xd48e,0xd48f,
+ 0xd490,0xd491,0xd492,0xd493,0xd494,0xd495,0xd496,0xd497,
+ 0xd498,0xd499,0xd49a,0xd49b,0xd49c,0xd49d,0xd49e,0xd49f,
+ 0xd4a0,0xd4a1,0xd4a2,0xd4a3,0xd4a4,0xd4a5,0xd4a6,0xd4a7,
+ 0xd4a8,0xd4a9,0xd4aa,0xd4ab,0xd4ac,0xd4ad,0xd4ae,0xd4af,
+ 0xd4b0,0xd4b1,0xd4b2,0xd4b3,0xd4b4,0xd4b5,0xd4b6,0xd4b7,
+ 0xd4b8,0xd4b9,0xd4ba,0xd4bb,0xd4bc,0xd4bd,0xd4be,0xd4bf,
+ 0xd4c0,0xd4c1,0xd4c2,0xd4c3,0xd4c4,0xd4c5,0xd4c6,0xd4c7,
+ 0xd4c8,0xd4c9,0xd4ca,0xd4cb,0xd4cc,0xd4cd,0xd4ce,0xd4cf,
+ 0xd4d0,0xd4d1,0xd4d2,0xd4d3,0xd4d4,0xd4d5,0xd4d6,0xd4d7,
+ 0xd4d8,0xd4d9,0xd4da,0xd4db,0xd4dc,0xd4dd,0xd4de,0xd4df,
+ 0xd4e0,0xd4e1,0xd4e2,0xd4e3,0xd4e4,0xd4e5,0xd4e6,0xd4e7,
+ 0xd4e8,0xd4e9,0xd4ea,0xd4eb,0xd4ec,0xd4ed,0xd4ee,0xd4ef,
+ 0xd4f0,0xd4f1,0xd4f2,0xd4f3,0xd4f4,0xd4f5,0xd4f6,0xd4f7,
+ 0xd4f8,0xd4f9,0xd4fa,0xd4fb,0xd4fc,0xd4fd,0xd4fe,0xd4ff,
+ 0xd500,0xd501,0xd502,0xd503,0xd504,0xd505,0xd506,0xd507,
+ 0xd508,0xd509,0xd50a,0xd50b,0xd50c,0xd50d,0xd50e,0xd50f,
+ 0xd510,0xd511,0xd512,0xd513,0xd514,0xd515,0xd516,0xd517,
+ 0xd518,0xd519,0xd51a,0xd51b,0xd51c,0xd51d,0xd51e,0xd51f,
+ 0xd520,0xd521,0xd522,0xd523,0xd524,0xd525,0xd526,0xd527,
+ 0xd528,0xd529,0xd52a,0xd52b,0xd52c,0xd52d,0xd52e,0xd52f,
+ 0xd530,0xd531,0xd532,0xd533,0xd534,0xd535,0xd536,0xd537,
+ 0xd538,0xd539,0xd53a,0xd53b,0xd53c,0xd53d,0xd53e,0xd53f,
+ 0xd540,0xd541,0xd542,0xd543,0xd544,0xd545,0xd546,0xd547,
+ 0xd548,0xd549,0xd54a,0xd54b,0xd54c,0xd54d,0xd54e,0xd54f,
+ 0xd550,0xd551,0xd552,0xd553,0xd554,0xd555,0xd556,0xd557,
+ 0xd558,0xd559,0xd55a,0xd55b,0xd55c,0xd55d,0xd55e,0xd55f,
+ 0xd560,0xd561,0xd562,0xd563,0xd564,0xd565,0xd566,0xd567,
+ 0xd568,0xd569,0xd56a,0xd56b,0xd56c,0xd56d,0xd56e,0xd56f,
+ 0xd570,0xd571,0xd572,0xd573,0xd574,0xd575,0xd576,0xd577,
+ 0xd578,0xd579,0xd57a,0xd57b,0xd57c,0xd57d,0xd57e,0xd57f,
+ 0xd580,0xd581,0xd582,0xd583,0xd584,0xd585,0xd586,0xd587,
+ 0xd588,0xd589,0xd58a,0xd58b,0xd58c,0xd58d,0xd58e,0xd58f,
+ 0xd590,0xd591,0xd592,0xd593,0xd594,0xd595,0xd596,0xd597,
+ 0xd598,0xd599,0xd59a,0xd59b,0xd59c,0xd59d,0xd59e,0xd59f,
+ 0xd5a0,0xd5a1,0xd5a2,0xd5a3,0xd5a4,0xd5a5,0xd5a6,0xd5a7,
+ 0xd5a8,0xd5a9,0xd5aa,0xd5ab,0xd5ac,0xd5ad,0xd5ae,0xd5af,
+ 0xd5b0,0xd5b1,0xd5b2,0xd5b3,0xd5b4,0xd5b5,0xd5b6,0xd5b7,
+ 0xd5b8,0xd5b9,0xd5ba,0xd5bb,0xd5bc,0xd5bd,0xd5be,0xd5bf,
+ 0xd5c0,0xd5c1,0xd5c2,0xd5c3,0xd5c4,0xd5c5,0xd5c6,0xd5c7,
+ 0xd5c8,0xd5c9,0xd5ca,0xd5cb,0xd5cc,0xd5cd,0xd5ce,0xd5cf,
+ 0xd5d0,0xd5d1,0xd5d2,0xd5d3,0xd5d4,0xd5d5,0xd5d6,0xd5d7,
+ 0xd5d8,0xd5d9,0xd5da,0xd5db,0xd5dc,0xd5dd,0xd5de,0xd5df,
+ 0xd5e0,0xd5e1,0xd5e2,0xd5e3,0xd5e4,0xd5e5,0xd5e6,0xd5e7,
+ 0xd5e8,0xd5e9,0xd5ea,0xd5eb,0xd5ec,0xd5ed,0xd5ee,0xd5ef,
+ 0xd5f0,0xd5f1,0xd5f2,0xd5f3,0xd5f4,0xd5f5,0xd5f6,0xd5f7,
+ 0xd5f8,0xd5f9,0xd5fa,0xd5fb,0xd5fc,0xd5fd,0xd5fe,0xd5ff,
+ 0xd600,0xd601,0xd602,0xd603,0xd604,0xd605,0xd606,0xd607,
+ 0xd608,0xd609,0xd60a,0xd60b,0xd60c,0xd60d,0xd60e,0xd60f,
+ 0xd610,0xd611,0xd612,0xd613,0xd614,0xd615,0xd616,0xd617,
+ 0xd618,0xd619,0xd61a,0xd61b,0xd61c,0xd61d,0xd61e,0xd61f,
+ 0xd620,0xd621,0xd622,0xd623,0xd624,0xd625,0xd626,0xd627,
+ 0xd628,0xd629,0xd62a,0xd62b,0xd62c,0xd62d,0xd62e,0xd62f,
+ 0xd630,0xd631,0xd632,0xd633,0xd634,0xd635,0xd636,0xd637,
+ 0xd638,0xd639,0xd63a,0xd63b,0xd63c,0xd63d,0xd63e,0xd63f,
+ 0xd640,0xd641,0xd642,0xd643,0xd644,0xd645,0xd646,0xd647,
+ 0xd648,0xd649,0xd64a,0xd64b,0xd64c,0xd64d,0xd64e,0xd64f,
+ 0xd650,0xd651,0xd652,0xd653,0xd654,0xd655,0xd656,0xd657,
+ 0xd658,0xd659,0xd65a,0xd65b,0xd65c,0xd65d,0xd65e,0xd65f,
+ 0xd660,0xd661,0xd662,0xd663,0xd664,0xd665,0xd666,0xd667,
+ 0xd668,0xd669,0xd66a,0xd66b,0xd66c,0xd66d,0xd66e,0xd66f,
+ 0xd670,0xd671,0xd672,0xd673,0xd674,0xd675,0xd676,0xd677,
+ 0xd678,0xd679,0xd67a,0xd67b,0xd67c,0xd67d,0xd67e,0xd67f,
+ 0xd680,0xd681,0xd682,0xd683,0xd684,0xd685,0xd686,0xd687,
+ 0xd688,0xd689,0xd68a,0xd68b,0xd68c,0xd68d,0xd68e,0xd68f,
+ 0xd690,0xd691,0xd692,0xd693,0xd694,0xd695,0xd696,0xd697,
+ 0xd698,0xd699,0xd69a,0xd69b,0xd69c,0xd69d,0xd69e,0xd69f,
+ 0xd6a0,0xd6a1,0xd6a2,0xd6a3,0xd6a4,0xd6a5,0xd6a6,0xd6a7,
+ 0xd6a8,0xd6a9,0xd6aa,0xd6ab,0xd6ac,0xd6ad,0xd6ae,0xd6af,
+ 0xd6b0,0xd6b1,0xd6b2,0xd6b3,0xd6b4,0xd6b5,0xd6b6,0xd6b7,
+ 0xd6b8,0xd6b9,0xd6ba,0xd6bb,0xd6bc,0xd6bd,0xd6be,0xd6bf,
+ 0xd6c0,0xd6c1,0xd6c2,0xd6c3,0xd6c4,0xd6c5,0xd6c6,0xd6c7,
+ 0xd6c8,0xd6c9,0xd6ca,0xd6cb,0xd6cc,0xd6cd,0xd6ce,0xd6cf,
+ 0xd6d0,0xd6d1,0xd6d2,0xd6d3,0xd6d4,0xd6d5,0xd6d6,0xd6d7,
+ 0xd6d8,0xd6d9,0xd6da,0xd6db,0xd6dc,0xd6dd,0xd6de,0xd6df,
+ 0xd6e0,0xd6e1,0xd6e2,0xd6e3,0xd6e4,0xd6e5,0xd6e6,0xd6e7,
+ 0xd6e8,0xd6e9,0xd6ea,0xd6eb,0xd6ec,0xd6ed,0xd6ee,0xd6ef,
+ 0xd6f0,0xd6f1,0xd6f2,0xd6f3,0xd6f4,0xd6f5,0xd6f6,0xd6f7,
+ 0xd6f8,0xd6f9,0xd6fa,0xd6fb,0xd6fc,0xd6fd,0xd6fe,0xd6ff,
+ 0xd700,0xd701,0xd702,0xd703,0xd704,0xd705,0xd706,0xd707,
+ 0xd708,0xd709,0xd70a,0xd70b,0xd70c,0xd70d,0xd70e,0xd70f,
+ 0xd710,0xd711,0xd712,0xd713,0xd714,0xd715,0xd716,0xd717,
+ 0xd718,0xd719,0xd71a,0xd71b,0xd71c,0xd71d,0xd71e,0xd71f,
+ 0xd720,0xd721,0xd722,0xd723,0xd724,0xd725,0xd726,0xd727,
+ 0xd728,0xd729,0xd72a,0xd72b,0xd72c,0xd72d,0xd72e,0xd72f,
+ 0xd730,0xd731,0xd732,0xd733,0xd734,0xd735,0xd736,0xd737,
+ 0xd738,0xd739,0xd73a,0xd73b,0xd73c,0xd73d,0xd73e,0xd73f,
+ 0xd740,0xd741,0xd742,0xd743,0xd744,0xd745,0xd746,0xd747,
+ 0xd748,0xd749,0xd74a,0xd74b,0xd74c,0xd74d,0xd74e,0xd74f,
+ 0xd750,0xd751,0xd752,0xd753,0xd754,0xd755,0xd756,0xd757,
+ 0xd758,0xd759,0xd75a,0xd75b,0xd75c,0xd75d,0xd75e,0xd75f,
+ 0xd760,0xd761,0xd762,0xd763,0xd764,0xd765,0xd766,0xd767,
+ 0xd768,0xd769,0xd76a,0xd76b,0xd76c,0xd76d,0xd76e,0xd76f,
+ 0xd770,0xd771,0xd772,0xd773,0xd774,0xd775,0xd776,0xd777,
+ 0xd778,0xd779,0xd77a,0xd77b,0xd77c,0xd77d,0xd77e,0xd77f,
+ 0xd780,0xd781,0xd782,0xd783,0xd784,0xd785,0xd786,0xd787,
+ 0xd788,0xd789,0xd78a,0xd78b,0xd78c,0xd78d,0xd78e,0xd78f,
+ 0xd790,0xd791,0xd792,0xd793,0xd794,0xd795,0xd796,0xd797,
+ 0xd798,0xd799,0xd79a,0xd79b,0xd79c,0xd79d,0xd79e,0xd79f,
+ 0xd7a0,0xd7a1,0xd7a2,0xd7a3,0xd7a4,0xd7a5,0xd7a6,0xd7a7,
+ 0xd7a8,0xd7a9,0xd7aa,0xd7ab,0xd7ac,0xd7ad,0xd7ae,0xd7af,
+ 0xd7b0,0xd7b1,0xd7b2,0xd7b3,0xd7b4,0xd7b5,0xd7b6,0xd7b7,
+ 0xd7b8,0xd7b9,0xd7ba,0xd7bb,0xd7bc,0xd7bd,0xd7be,0xd7bf,
+ 0xd7c0,0xd7c1,0xd7c2,0xd7c3,0xd7c4,0xd7c5,0xd7c6,0xd7c7,
+ 0xd7c8,0xd7c9,0xd7ca,0xd7cb,0xd7cc,0xd7cd,0xd7ce,0xd7cf,
+ 0xd7d0,0xd7d1,0xd7d2,0xd7d3,0xd7d4,0xd7d5,0xd7d6,0xd7d7,
+ 0xd7d8,0xd7d9,0xd7da,0xd7db,0xd7dc,0xd7dd,0xd7de,0xd7df,
+ 0xd7e0,0xd7e1,0xd7e2,0xd7e3,0xd7e4,0xd7e5,0xd7e6,0xd7e7,
+ 0xd7e8,0xd7e9,0xd7ea,0xd7eb,0xd7ec,0xd7ed,0xd7ee,0xd7ef,
+ 0xd7f0,0xd7f1,0xd7f2,0xd7f3,0xd7f4,0xd7f5,0xd7f6,0xd7f7,
+ 0xd7f8,0xd7f9,0xd7fa,0xd7fb,0xd7fc,0xd7fd,0xd7fe,0xd7ff,
+ 0xd800,0xd801,0xd802,0xd803,0xd804,0xd805,0xd806,0xd807,
+ 0xd808,0xd809,0xd80a,0xd80b,0xd80c,0xd80d,0xd80e,0xd80f,
+ 0xd810,0xd811,0xd812,0xd813,0xd814,0xd815,0xd816,0xd817,
+ 0xd818,0xd819,0xd81a,0xd81b,0xd81c,0xd81d,0xd81e,0xd81f,
+ 0xd820,0xd821,0xd822,0xd823,0xd824,0xd825,0xd826,0xd827,
+ 0xd828,0xd829,0xd82a,0xd82b,0xd82c,0xd82d,0xd82e,0xd82f,
+ 0xd830,0xd831,0xd832,0xd833,0xd834,0xd835,0xd836,0xd837,
+ 0xd838,0xd839,0xd83a,0xd83b,0xd83c,0xd83d,0xd83e,0xd83f,
+ 0xd840,0xd841,0xd842,0xd843,0xd844,0xd845,0xd846,0xd847,
+ 0xd848,0xd849,0xd84a,0xd84b,0xd84c,0xd84d,0xd84e,0xd84f,
+ 0xd850,0xd851,0xd852,0xd853,0xd854,0xd855,0xd856,0xd857,
+ 0xd858,0xd859,0xd85a,0xd85b,0xd85c,0xd85d,0xd85e,0xd85f,
+ 0xd860,0xd861,0xd862,0xd863,0xd864,0xd865,0xd866,0xd867,
+ 0xd868,0xd869,0xd86a,0xd86b,0xd86c,0xd86d,0xd86e,0xd86f,
+ 0xd870,0xd871,0xd872,0xd873,0xd874,0xd875,0xd876,0xd877,
+ 0xd878,0xd879,0xd87a,0xd87b,0xd87c,0xd87d,0xd87e,0xd87f,
+ 0xd880,0xd881,0xd882,0xd883,0xd884,0xd885,0xd886,0xd887,
+ 0xd888,0xd889,0xd88a,0xd88b,0xd88c,0xd88d,0xd88e,0xd88f,
+ 0xd890,0xd891,0xd892,0xd893,0xd894,0xd895,0xd896,0xd897,
+ 0xd898,0xd899,0xd89a,0xd89b,0xd89c,0xd89d,0xd89e,0xd89f,
+ 0xd8a0,0xd8a1,0xd8a2,0xd8a3,0xd8a4,0xd8a5,0xd8a6,0xd8a7,
+ 0xd8a8,0xd8a9,0xd8aa,0xd8ab,0xd8ac,0xd8ad,0xd8ae,0xd8af,
+ 0xd8b0,0xd8b1,0xd8b2,0xd8b3,0xd8b4,0xd8b5,0xd8b6,0xd8b7,
+ 0xd8b8,0xd8b9,0xd8ba,0xd8bb,0xd8bc,0xd8bd,0xd8be,0xd8bf,
+ 0xd8c0,0xd8c1,0xd8c2,0xd8c3,0xd8c4,0xd8c5,0xd8c6,0xd8c7,
+ 0xd8c8,0xd8c9,0xd8ca,0xd8cb,0xd8cc,0xd8cd,0xd8ce,0xd8cf,
+ 0xd8d0,0xd8d1,0xd8d2,0xd8d3,0xd8d4,0xd8d5,0xd8d6,0xd8d7,
+ 0xd8d8,0xd8d9,0xd8da,0xd8db,0xd8dc,0xd8dd,0xd8de,0xd8df,
+ 0xd8e0,0xd8e1,0xd8e2,0xd8e3,0xd8e4,0xd8e5,0xd8e6,0xd8e7,
+ 0xd8e8,0xd8e9,0xd8ea,0xd8eb,0xd8ec,0xd8ed,0xd8ee,0xd8ef,
+ 0xd8f0,0xd8f1,0xd8f2,0xd8f3,0xd8f4,0xd8f5,0xd8f6,0xd8f7,
+ 0xd8f8,0xd8f9,0xd8fa,0xd8fb,0xd8fc,0xd8fd,0xd8fe,0xd8ff,
+ 0xd900,0xd901,0xd902,0xd903,0xd904,0xd905,0xd906,0xd907,
+ 0xd908,0xd909,0xd90a,0xd90b,0xd90c,0xd90d,0xd90e,0xd90f,
+ 0xd910,0xd911,0xd912,0xd913,0xd914,0xd915,0xd916,0xd917,
+ 0xd918,0xd919,0xd91a,0xd91b,0xd91c,0xd91d,0xd91e,0xd91f,
+ 0xd920,0xd921,0xd922,0xd923,0xd924,0xd925,0xd926,0xd927,
+ 0xd928,0xd929,0xd92a,0xd92b,0xd92c,0xd92d,0xd92e,0xd92f,
+ 0xd930,0xd931,0xd932,0xd933,0xd934,0xd935,0xd936,0xd937,
+ 0xd938,0xd939,0xd93a,0xd93b,0xd93c,0xd93d,0xd93e,0xd93f,
+ 0xd940,0xd941,0xd942,0xd943,0xd944,0xd945,0xd946,0xd947,
+ 0xd948,0xd949,0xd94a,0xd94b,0xd94c,0xd94d,0xd94e,0xd94f,
+ 0xd950,0xd951,0xd952,0xd953,0xd954,0xd955,0xd956,0xd957,
+ 0xd958,0xd959,0xd95a,0xd95b,0xd95c,0xd95d,0xd95e,0xd95f,
+ 0xd960,0xd961,0xd962,0xd963,0xd964,0xd965,0xd966,0xd967,
+ 0xd968,0xd969,0xd96a,0xd96b,0xd96c,0xd96d,0xd96e,0xd96f,
+ 0xd970,0xd971,0xd972,0xd973,0xd974,0xd975,0xd976,0xd977,
+ 0xd978,0xd979,0xd97a,0xd97b,0xd97c,0xd97d,0xd97e,0xd97f,
+ 0xd980,0xd981,0xd982,0xd983,0xd984,0xd985,0xd986,0xd987,
+ 0xd988,0xd989,0xd98a,0xd98b,0xd98c,0xd98d,0xd98e,0xd98f,
+ 0xd990,0xd991,0xd992,0xd993,0xd994,0xd995,0xd996,0xd997,
+ 0xd998,0xd999,0xd99a,0xd99b,0xd99c,0xd99d,0xd99e,0xd99f,
+ 0xd9a0,0xd9a1,0xd9a2,0xd9a3,0xd9a4,0xd9a5,0xd9a6,0xd9a7,
+ 0xd9a8,0xd9a9,0xd9aa,0xd9ab,0xd9ac,0xd9ad,0xd9ae,0xd9af,
+ 0xd9b0,0xd9b1,0xd9b2,0xd9b3,0xd9b4,0xd9b5,0xd9b6,0xd9b7,
+ 0xd9b8,0xd9b9,0xd9ba,0xd9bb,0xd9bc,0xd9bd,0xd9be,0xd9bf,
+ 0xd9c0,0xd9c1,0xd9c2,0xd9c3,0xd9c4,0xd9c5,0xd9c6,0xd9c7,
+ 0xd9c8,0xd9c9,0xd9ca,0xd9cb,0xd9cc,0xd9cd,0xd9ce,0xd9cf,
+ 0xd9d0,0xd9d1,0xd9d2,0xd9d3,0xd9d4,0xd9d5,0xd9d6,0xd9d7,
+ 0xd9d8,0xd9d9,0xd9da,0xd9db,0xd9dc,0xd9dd,0xd9de,0xd9df,
+ 0xd9e0,0xd9e1,0xd9e2,0xd9e3,0xd9e4,0xd9e5,0xd9e6,0xd9e7,
+ 0xd9e8,0xd9e9,0xd9ea,0xd9eb,0xd9ec,0xd9ed,0xd9ee,0xd9ef,
+ 0xd9f0,0xd9f1,0xd9f2,0xd9f3,0xd9f4,0xd9f5,0xd9f6,0xd9f7,
+ 0xd9f8,0xd9f9,0xd9fa,0xd9fb,0xd9fc,0xd9fd,0xd9fe,0xd9ff,
+ 0xda00,0xda01,0xda02,0xda03,0xda04,0xda05,0xda06,0xda07,
+ 0xda08,0xda09,0xda0a,0xda0b,0xda0c,0xda0d,0xda0e,0xda0f,
+ 0xda10,0xda11,0xda12,0xda13,0xda14,0xda15,0xda16,0xda17,
+ 0xda18,0xda19,0xda1a,0xda1b,0xda1c,0xda1d,0xda1e,0xda1f,
+ 0xda20,0xda21,0xda22,0xda23,0xda24,0xda25,0xda26,0xda27,
+ 0xda28,0xda29,0xda2a,0xda2b,0xda2c,0xda2d,0xda2e,0xda2f,
+ 0xda30,0xda31,0xda32,0xda33,0xda34,0xda35,0xda36,0xda37,
+ 0xda38,0xda39,0xda3a,0xda3b,0xda3c,0xda3d,0xda3e,0xda3f,
+ 0xda40,0xda41,0xda42,0xda43,0xda44,0xda45,0xda46,0xda47,
+ 0xda48,0xda49,0xda4a,0xda4b,0xda4c,0xda4d,0xda4e,0xda4f,
+ 0xda50,0xda51,0xda52,0xda53,0xda54,0xda55,0xda56,0xda57,
+ 0xda58,0xda59,0xda5a,0xda5b,0xda5c,0xda5d,0xda5e,0xda5f,
+ 0xda60,0xda61,0xda62,0xda63,0xda64,0xda65,0xda66,0xda67,
+ 0xda68,0xda69,0xda6a,0xda6b,0xda6c,0xda6d,0xda6e,0xda6f,
+ 0xda70,0xda71,0xda72,0xda73,0xda74,0xda75,0xda76,0xda77,
+ 0xda78,0xda79,0xda7a,0xda7b,0xda7c,0xda7d,0xda7e,0xda7f,
+ 0xda80,0xda81,0xda82,0xda83,0xda84,0xda85,0xda86,0xda87,
+ 0xda88,0xda89,0xda8a,0xda8b,0xda8c,0xda8d,0xda8e,0xda8f,
+ 0xda90,0xda91,0xda92,0xda93,0xda94,0xda95,0xda96,0xda97,
+ 0xda98,0xda99,0xda9a,0xda9b,0xda9c,0xda9d,0xda9e,0xda9f,
+ 0xdaa0,0xdaa1,0xdaa2,0xdaa3,0xdaa4,0xdaa5,0xdaa6,0xdaa7,
+ 0xdaa8,0xdaa9,0xdaaa,0xdaab,0xdaac,0xdaad,0xdaae,0xdaaf,
+ 0xdab0,0xdab1,0xdab2,0xdab3,0xdab4,0xdab5,0xdab6,0xdab7,
+ 0xdab8,0xdab9,0xdaba,0xdabb,0xdabc,0xdabd,0xdabe,0xdabf,
+ 0xdac0,0xdac1,0xdac2,0xdac3,0xdac4,0xdac5,0xdac6,0xdac7,
+ 0xdac8,0xdac9,0xdaca,0xdacb,0xdacc,0xdacd,0xdace,0xdacf,
+ 0xdad0,0xdad1,0xdad2,0xdad3,0xdad4,0xdad5,0xdad6,0xdad7,
+ 0xdad8,0xdad9,0xdada,0xdadb,0xdadc,0xdadd,0xdade,0xdadf,
+ 0xdae0,0xdae1,0xdae2,0xdae3,0xdae4,0xdae5,0xdae6,0xdae7,
+ 0xdae8,0xdae9,0xdaea,0xdaeb,0xdaec,0xdaed,0xdaee,0xdaef,
+ 0xdaf0,0xdaf1,0xdaf2,0xdaf3,0xdaf4,0xdaf5,0xdaf6,0xdaf7,
+ 0xdaf8,0xdaf9,0xdafa,0xdafb,0xdafc,0xdafd,0xdafe,0xdaff,
+ 0xdb00,0xdb01,0xdb02,0xdb03,0xdb04,0xdb05,0xdb06,0xdb07,
+ 0xdb08,0xdb09,0xdb0a,0xdb0b,0xdb0c,0xdb0d,0xdb0e,0xdb0f,
+ 0xdb10,0xdb11,0xdb12,0xdb13,0xdb14,0xdb15,0xdb16,0xdb17,
+ 0xdb18,0xdb19,0xdb1a,0xdb1b,0xdb1c,0xdb1d,0xdb1e,0xdb1f,
+ 0xdb20,0xdb21,0xdb22,0xdb23,0xdb24,0xdb25,0xdb26,0xdb27,
+ 0xdb28,0xdb29,0xdb2a,0xdb2b,0xdb2c,0xdb2d,0xdb2e,0xdb2f,
+ 0xdb30,0xdb31,0xdb32,0xdb33,0xdb34,0xdb35,0xdb36,0xdb37,
+ 0xdb38,0xdb39,0xdb3a,0xdb3b,0xdb3c,0xdb3d,0xdb3e,0xdb3f,
+ 0xdb40,0xdb41,0xdb42,0xdb43,0xdb44,0xdb45,0xdb46,0xdb47,
+ 0xdb48,0xdb49,0xdb4a,0xdb4b,0xdb4c,0xdb4d,0xdb4e,0xdb4f,
+ 0xdb50,0xdb51,0xdb52,0xdb53,0xdb54,0xdb55,0xdb56,0xdb57,
+ 0xdb58,0xdb59,0xdb5a,0xdb5b,0xdb5c,0xdb5d,0xdb5e,0xdb5f,
+ 0xdb60,0xdb61,0xdb62,0xdb63,0xdb64,0xdb65,0xdb66,0xdb67,
+ 0xdb68,0xdb69,0xdb6a,0xdb6b,0xdb6c,0xdb6d,0xdb6e,0xdb6f,
+ 0xdb70,0xdb71,0xdb72,0xdb73,0xdb74,0xdb75,0xdb76,0xdb77,
+ 0xdb78,0xdb79,0xdb7a,0xdb7b,0xdb7c,0xdb7d,0xdb7e,0xdb7f,
+ 0xdb80,0xdb81,0xdb82,0xdb83,0xdb84,0xdb85,0xdb86,0xdb87,
+ 0xdb88,0xdb89,0xdb8a,0xdb8b,0xdb8c,0xdb8d,0xdb8e,0xdb8f,
+ 0xdb90,0xdb91,0xdb92,0xdb93,0xdb94,0xdb95,0xdb96,0xdb97,
+ 0xdb98,0xdb99,0xdb9a,0xdb9b,0xdb9c,0xdb9d,0xdb9e,0xdb9f,
+ 0xdba0,0xdba1,0xdba2,0xdba3,0xdba4,0xdba5,0xdba6,0xdba7,
+ 0xdba8,0xdba9,0xdbaa,0xdbab,0xdbac,0xdbad,0xdbae,0xdbaf,
+ 0xdbb0,0xdbb1,0xdbb2,0xdbb3,0xdbb4,0xdbb5,0xdbb6,0xdbb7,
+ 0xdbb8,0xdbb9,0xdbba,0xdbbb,0xdbbc,0xdbbd,0xdbbe,0xdbbf,
+ 0xdbc0,0xdbc1,0xdbc2,0xdbc3,0xdbc4,0xdbc5,0xdbc6,0xdbc7,
+ 0xdbc8,0xdbc9,0xdbca,0xdbcb,0xdbcc,0xdbcd,0xdbce,0xdbcf,
+ 0xdbd0,0xdbd1,0xdbd2,0xdbd3,0xdbd4,0xdbd5,0xdbd6,0xdbd7,
+ 0xdbd8,0xdbd9,0xdbda,0xdbdb,0xdbdc,0xdbdd,0xdbde,0xdbdf,
+ 0xdbe0,0xdbe1,0xdbe2,0xdbe3,0xdbe4,0xdbe5,0xdbe6,0xdbe7,
+ 0xdbe8,0xdbe9,0xdbea,0xdbeb,0xdbec,0xdbed,0xdbee,0xdbef,
+ 0xdbf0,0xdbf1,0xdbf2,0xdbf3,0xdbf4,0xdbf5,0xdbf6,0xdbf7,
+ 0xdbf8,0xdbf9,0xdbfa,0xdbfb,0xdbfc,0xdbfd,0xdbfe,0xdbff,
+ 0xdc00,0xdc01,0xdc02,0xdc03,0xdc04,0xdc05,0xdc06,0xdc07,
+ 0xdc08,0xdc09,0xdc0a,0xdc0b,0xdc0c,0xdc0d,0xdc0e,0xdc0f,
+ 0xdc10,0xdc11,0xdc12,0xdc13,0xdc14,0xdc15,0xdc16,0xdc17,
+ 0xdc18,0xdc19,0xdc1a,0xdc1b,0xdc1c,0xdc1d,0xdc1e,0xdc1f,
+ 0xdc20,0xdc21,0xdc22,0xdc23,0xdc24,0xdc25,0xdc26,0xdc27,
+ 0xdc28,0xdc29,0xdc2a,0xdc2b,0xdc2c,0xdc2d,0xdc2e,0xdc2f,
+ 0xdc30,0xdc31,0xdc32,0xdc33,0xdc34,0xdc35,0xdc36,0xdc37,
+ 0xdc38,0xdc39,0xdc3a,0xdc3b,0xdc3c,0xdc3d,0xdc3e,0xdc3f,
+ 0xdc40,0xdc41,0xdc42,0xdc43,0xdc44,0xdc45,0xdc46,0xdc47,
+ 0xdc48,0xdc49,0xdc4a,0xdc4b,0xdc4c,0xdc4d,0xdc4e,0xdc4f,
+ 0xdc50,0xdc51,0xdc52,0xdc53,0xdc54,0xdc55,0xdc56,0xdc57,
+ 0xdc58,0xdc59,0xdc5a,0xdc5b,0xdc5c,0xdc5d,0xdc5e,0xdc5f,
+ 0xdc60,0xdc61,0xdc62,0xdc63,0xdc64,0xdc65,0xdc66,0xdc67,
+ 0xdc68,0xdc69,0xdc6a,0xdc6b,0xdc6c,0xdc6d,0xdc6e,0xdc6f,
+ 0xdc70,0xdc71,0xdc72,0xdc73,0xdc74,0xdc75,0xdc76,0xdc77,
+ 0xdc78,0xdc79,0xdc7a,0xdc7b,0xdc7c,0xdc7d,0xdc7e,0xdc7f,
+ 0xdc80,0xdc81,0xdc82,0xdc83,0xdc84,0xdc85,0xdc86,0xdc87,
+ 0xdc88,0xdc89,0xdc8a,0xdc8b,0xdc8c,0xdc8d,0xdc8e,0xdc8f,
+ 0xdc90,0xdc91,0xdc92,0xdc93,0xdc94,0xdc95,0xdc96,0xdc97,
+ 0xdc98,0xdc99,0xdc9a,0xdc9b,0xdc9c,0xdc9d,0xdc9e,0xdc9f,
+ 0xdca0,0xdca1,0xdca2,0xdca3,0xdca4,0xdca5,0xdca6,0xdca7,
+ 0xdca8,0xdca9,0xdcaa,0xdcab,0xdcac,0xdcad,0xdcae,0xdcaf,
+ 0xdcb0,0xdcb1,0xdcb2,0xdcb3,0xdcb4,0xdcb5,0xdcb6,0xdcb7,
+ 0xdcb8,0xdcb9,0xdcba,0xdcbb,0xdcbc,0xdcbd,0xdcbe,0xdcbf,
+ 0xdcc0,0xdcc1,0xdcc2,0xdcc3,0xdcc4,0xdcc5,0xdcc6,0xdcc7,
+ 0xdcc8,0xdcc9,0xdcca,0xdccb,0xdccc,0xdccd,0xdcce,0xdccf,
+ 0xdcd0,0xdcd1,0xdcd2,0xdcd3,0xdcd4,0xdcd5,0xdcd6,0xdcd7,
+ 0xdcd8,0xdcd9,0xdcda,0xdcdb,0xdcdc,0xdcdd,0xdcde,0xdcdf,
+ 0xdce0,0xdce1,0xdce2,0xdce3,0xdce4,0xdce5,0xdce6,0xdce7,
+ 0xdce8,0xdce9,0xdcea,0xdceb,0xdcec,0xdced,0xdcee,0xdcef,
+ 0xdcf0,0xdcf1,0xdcf2,0xdcf3,0xdcf4,0xdcf5,0xdcf6,0xdcf7,
+ 0xdcf8,0xdcf9,0xdcfa,0xdcfb,0xdcfc,0xdcfd,0xdcfe,0xdcff,
+ 0xdd00,0xdd01,0xdd02,0xdd03,0xdd04,0xdd05,0xdd06,0xdd07,
+ 0xdd08,0xdd09,0xdd0a,0xdd0b,0xdd0c,0xdd0d,0xdd0e,0xdd0f,
+ 0xdd10,0xdd11,0xdd12,0xdd13,0xdd14,0xdd15,0xdd16,0xdd17,
+ 0xdd18,0xdd19,0xdd1a,0xdd1b,0xdd1c,0xdd1d,0xdd1e,0xdd1f,
+ 0xdd20,0xdd21,0xdd22,0xdd23,0xdd24,0xdd25,0xdd26,0xdd27,
+ 0xdd28,0xdd29,0xdd2a,0xdd2b,0xdd2c,0xdd2d,0xdd2e,0xdd2f,
+ 0xdd30,0xdd31,0xdd32,0xdd33,0xdd34,0xdd35,0xdd36,0xdd37,
+ 0xdd38,0xdd39,0xdd3a,0xdd3b,0xdd3c,0xdd3d,0xdd3e,0xdd3f,
+ 0xdd40,0xdd41,0xdd42,0xdd43,0xdd44,0xdd45,0xdd46,0xdd47,
+ 0xdd48,0xdd49,0xdd4a,0xdd4b,0xdd4c,0xdd4d,0xdd4e,0xdd4f,
+ 0xdd50,0xdd51,0xdd52,0xdd53,0xdd54,0xdd55,0xdd56,0xdd57,
+ 0xdd58,0xdd59,0xdd5a,0xdd5b,0xdd5c,0xdd5d,0xdd5e,0xdd5f,
+ 0xdd60,0xdd61,0xdd62,0xdd63,0xdd64,0xdd65,0xdd66,0xdd67,
+ 0xdd68,0xdd69,0xdd6a,0xdd6b,0xdd6c,0xdd6d,0xdd6e,0xdd6f,
+ 0xdd70,0xdd71,0xdd72,0xdd73,0xdd74,0xdd75,0xdd76,0xdd77,
+ 0xdd78,0xdd79,0xdd7a,0xdd7b,0xdd7c,0xdd7d,0xdd7e,0xdd7f,
+ 0xdd80,0xdd81,0xdd82,0xdd83,0xdd84,0xdd85,0xdd86,0xdd87,
+ 0xdd88,0xdd89,0xdd8a,0xdd8b,0xdd8c,0xdd8d,0xdd8e,0xdd8f,
+ 0xdd90,0xdd91,0xdd92,0xdd93,0xdd94,0xdd95,0xdd96,0xdd97,
+ 0xdd98,0xdd99,0xdd9a,0xdd9b,0xdd9c,0xdd9d,0xdd9e,0xdd9f,
+ 0xdda0,0xdda1,0xdda2,0xdda3,0xdda4,0xdda5,0xdda6,0xdda7,
+ 0xdda8,0xdda9,0xddaa,0xddab,0xddac,0xddad,0xddae,0xddaf,
+ 0xddb0,0xddb1,0xddb2,0xddb3,0xddb4,0xddb5,0xddb6,0xddb7,
+ 0xddb8,0xddb9,0xddba,0xddbb,0xddbc,0xddbd,0xddbe,0xddbf,
+ 0xddc0,0xddc1,0xddc2,0xddc3,0xddc4,0xddc5,0xddc6,0xddc7,
+ 0xddc8,0xddc9,0xddca,0xddcb,0xddcc,0xddcd,0xddce,0xddcf,
+ 0xddd0,0xddd1,0xddd2,0xddd3,0xddd4,0xddd5,0xddd6,0xddd7,
+ 0xddd8,0xddd9,0xddda,0xdddb,0xdddc,0xdddd,0xddde,0xdddf,
+ 0xdde0,0xdde1,0xdde2,0xdde3,0xdde4,0xdde5,0xdde6,0xdde7,
+ 0xdde8,0xdde9,0xddea,0xddeb,0xddec,0xdded,0xddee,0xddef,
+ 0xddf0,0xddf1,0xddf2,0xddf3,0xddf4,0xddf5,0xddf6,0xddf7,
+ 0xddf8,0xddf9,0xddfa,0xddfb,0xddfc,0xddfd,0xddfe,0xddff,
+ 0xde00,0xde01,0xde02,0xde03,0xde04,0xde05,0xde06,0xde07,
+ 0xde08,0xde09,0xde0a,0xde0b,0xde0c,0xde0d,0xde0e,0xde0f,
+ 0xde10,0xde11,0xde12,0xde13,0xde14,0xde15,0xde16,0xde17,
+ 0xde18,0xde19,0xde1a,0xde1b,0xde1c,0xde1d,0xde1e,0xde1f,
+ 0xde20,0xde21,0xde22,0xde23,0xde24,0xde25,0xde26,0xde27,
+ 0xde28,0xde29,0xde2a,0xde2b,0xde2c,0xde2d,0xde2e,0xde2f,
+ 0xde30,0xde31,0xde32,0xde33,0xde34,0xde35,0xde36,0xde37,
+ 0xde38,0xde39,0xde3a,0xde3b,0xde3c,0xde3d,0xde3e,0xde3f,
+ 0xde40,0xde41,0xde42,0xde43,0xde44,0xde45,0xde46,0xde47,
+ 0xde48,0xde49,0xde4a,0xde4b,0xde4c,0xde4d,0xde4e,0xde4f,
+ 0xde50,0xde51,0xde52,0xde53,0xde54,0xde55,0xde56,0xde57,
+ 0xde58,0xde59,0xde5a,0xde5b,0xde5c,0xde5d,0xde5e,0xde5f,
+ 0xde60,0xde61,0xde62,0xde63,0xde64,0xde65,0xde66,0xde67,
+ 0xde68,0xde69,0xde6a,0xde6b,0xde6c,0xde6d,0xde6e,0xde6f,
+ 0xde70,0xde71,0xde72,0xde73,0xde74,0xde75,0xde76,0xde77,
+ 0xde78,0xde79,0xde7a,0xde7b,0xde7c,0xde7d,0xde7e,0xde7f,
+ 0xde80,0xde81,0xde82,0xde83,0xde84,0xde85,0xde86,0xde87,
+ 0xde88,0xde89,0xde8a,0xde8b,0xde8c,0xde8d,0xde8e,0xde8f,
+ 0xde90,0xde91,0xde92,0xde93,0xde94,0xde95,0xde96,0xde97,
+ 0xde98,0xde99,0xde9a,0xde9b,0xde9c,0xde9d,0xde9e,0xde9f,
+ 0xdea0,0xdea1,0xdea2,0xdea3,0xdea4,0xdea5,0xdea6,0xdea7,
+ 0xdea8,0xdea9,0xdeaa,0xdeab,0xdeac,0xdead,0xdeae,0xdeaf,
+ 0xdeb0,0xdeb1,0xdeb2,0xdeb3,0xdeb4,0xdeb5,0xdeb6,0xdeb7,
+ 0xdeb8,0xdeb9,0xdeba,0xdebb,0xdebc,0xdebd,0xdebe,0xdebf,
+ 0xdec0,0xdec1,0xdec2,0xdec3,0xdec4,0xdec5,0xdec6,0xdec7,
+ 0xdec8,0xdec9,0xdeca,0xdecb,0xdecc,0xdecd,0xdece,0xdecf,
+ 0xded0,0xded1,0xded2,0xded3,0xded4,0xded5,0xded6,0xded7,
+ 0xded8,0xded9,0xdeda,0xdedb,0xdedc,0xdedd,0xdede,0xdedf,
+ 0xdee0,0xdee1,0xdee2,0xdee3,0xdee4,0xdee5,0xdee6,0xdee7,
+ 0xdee8,0xdee9,0xdeea,0xdeeb,0xdeec,0xdeed,0xdeee,0xdeef,
+ 0xdef0,0xdef1,0xdef2,0xdef3,0xdef4,0xdef5,0xdef6,0xdef7,
+ 0xdef8,0xdef9,0xdefa,0xdefb,0xdefc,0xdefd,0xdefe,0xdeff,
+ 0xdf00,0xdf01,0xdf02,0xdf03,0xdf04,0xdf05,0xdf06,0xdf07,
+ 0xdf08,0xdf09,0xdf0a,0xdf0b,0xdf0c,0xdf0d,0xdf0e,0xdf0f,
+ 0xdf10,0xdf11,0xdf12,0xdf13,0xdf14,0xdf15,0xdf16,0xdf17,
+ 0xdf18,0xdf19,0xdf1a,0xdf1b,0xdf1c,0xdf1d,0xdf1e,0xdf1f,
+ 0xdf20,0xdf21,0xdf22,0xdf23,0xdf24,0xdf25,0xdf26,0xdf27,
+ 0xdf28,0xdf29,0xdf2a,0xdf2b,0xdf2c,0xdf2d,0xdf2e,0xdf2f,
+ 0xdf30,0xdf31,0xdf32,0xdf33,0xdf34,0xdf35,0xdf36,0xdf37,
+ 0xdf38,0xdf39,0xdf3a,0xdf3b,0xdf3c,0xdf3d,0xdf3e,0xdf3f,
+ 0xdf40,0xdf41,0xdf42,0xdf43,0xdf44,0xdf45,0xdf46,0xdf47,
+ 0xdf48,0xdf49,0xdf4a,0xdf4b,0xdf4c,0xdf4d,0xdf4e,0xdf4f,
+ 0xdf50,0xdf51,0xdf52,0xdf53,0xdf54,0xdf55,0xdf56,0xdf57,
+ 0xdf58,0xdf59,0xdf5a,0xdf5b,0xdf5c,0xdf5d,0xdf5e,0xdf5f,
+ 0xdf60,0xdf61,0xdf62,0xdf63,0xdf64,0xdf65,0xdf66,0xdf67,
+ 0xdf68,0xdf69,0xdf6a,0xdf6b,0xdf6c,0xdf6d,0xdf6e,0xdf6f,
+ 0xdf70,0xdf71,0xdf72,0xdf73,0xdf74,0xdf75,0xdf76,0xdf77,
+ 0xdf78,0xdf79,0xdf7a,0xdf7b,0xdf7c,0xdf7d,0xdf7e,0xdf7f,
+ 0xdf80,0xdf81,0xdf82,0xdf83,0xdf84,0xdf85,0xdf86,0xdf87,
+ 0xdf88,0xdf89,0xdf8a,0xdf8b,0xdf8c,0xdf8d,0xdf8e,0xdf8f,
+ 0xdf90,0xdf91,0xdf92,0xdf93,0xdf94,0xdf95,0xdf96,0xdf97,
+ 0xdf98,0xdf99,0xdf9a,0xdf9b,0xdf9c,0xdf9d,0xdf9e,0xdf9f,
+ 0xdfa0,0xdfa1,0xdfa2,0xdfa3,0xdfa4,0xdfa5,0xdfa6,0xdfa7,
+ 0xdfa8,0xdfa9,0xdfaa,0xdfab,0xdfac,0xdfad,0xdfae,0xdfaf,
+ 0xdfb0,0xdfb1,0xdfb2,0xdfb3,0xdfb4,0xdfb5,0xdfb6,0xdfb7,
+ 0xdfb8,0xdfb9,0xdfba,0xdfbb,0xdfbc,0xdfbd,0xdfbe,0xdfbf,
+ 0xdfc0,0xdfc1,0xdfc2,0xdfc3,0xdfc4,0xdfc5,0xdfc6,0xdfc7,
+ 0xdfc8,0xdfc9,0xdfca,0xdfcb,0xdfcc,0xdfcd,0xdfce,0xdfcf,
+ 0xdfd0,0xdfd1,0xdfd2,0xdfd3,0xdfd4,0xdfd5,0xdfd6,0xdfd7,
+ 0xdfd8,0xdfd9,0xdfda,0xdfdb,0xdfdc,0xdfdd,0xdfde,0xdfdf,
+ 0xdfe0,0xdfe1,0xdfe2,0xdfe3,0xdfe4,0xdfe5,0xdfe6,0xdfe7,
+ 0xdfe8,0xdfe9,0xdfea,0xdfeb,0xdfec,0xdfed,0xdfee,0xdfef,
+ 0xdff0,0xdff1,0xdff2,0xdff3,0xdff4,0xdff5,0xdff6,0xdff7,
+ 0xdff8,0xdff9,0xdffa,0xdffb,0xdffc,0xdffd,0xdffe,0xdfff,
+ 0xe000,0xe001,0xe002,0xe003,0xe004,0xe005,0xe006,0xe007,
+ 0xe008,0xe009,0xe00a,0xe00b,0xe00c,0xe00d,0xe00e,0xe00f,
+ 0xe010,0xe011,0xe012,0xe013,0xe014,0xe015,0xe016,0xe017,
+ 0xe018,0xe019,0xe01a,0xe01b,0xe01c,0xe01d,0xe01e,0xe01f,
+ 0xe020,0xe021,0xe022,0xe023,0xe024,0xe025,0xe026,0xe027,
+ 0xe028,0xe029,0xe02a,0xe02b,0xe02c,0xe02d,0xe02e,0xe02f,
+ 0xe030,0xe031,0xe032,0xe033,0xe034,0xe035,0xe036,0xe037,
+ 0xe038,0xe039,0xe03a,0xe03b,0xe03c,0xe03d,0xe03e,0xe03f,
+ 0xe040,0xe041,0xe042,0xe043,0xe044,0xe045,0xe046,0xe047,
+ 0xe048,0xe049,0xe04a,0xe04b,0xe04c,0xe04d,0xe04e,0xe04f,
+ 0xe050,0xe051,0xe052,0xe053,0xe054,0xe055,0xe056,0xe057,
+ 0xe058,0xe059,0xe05a,0xe05b,0xe05c,0xe05d,0xe05e,0xe05f,
+ 0xe060,0xe061,0xe062,0xe063,0xe064,0xe065,0xe066,0xe067,
+ 0xe068,0xe069,0xe06a,0xe06b,0xe06c,0xe06d,0xe06e,0xe06f,
+ 0xe070,0xe071,0xe072,0xe073,0xe074,0xe075,0xe076,0xe077,
+ 0xe078,0xe079,0xe07a,0xe07b,0xe07c,0xe07d,0xe07e,0xe07f,
+ 0xe080,0xe081,0xe082,0xe083,0xe084,0xe085,0xe086,0xe087,
+ 0xe088,0xe089,0xe08a,0xe08b,0xe08c,0xe08d,0xe08e,0xe08f,
+ 0xe090,0xe091,0xe092,0xe093,0xe094,0xe095,0xe096,0xe097,
+ 0xe098,0xe099,0xe09a,0xe09b,0xe09c,0xe09d,0xe09e,0xe09f,
+ 0xe0a0,0xe0a1,0xe0a2,0xe0a3,0xe0a4,0xe0a5,0xe0a6,0xe0a7,
+ 0xe0a8,0xe0a9,0xe0aa,0xe0ab,0xe0ac,0xe0ad,0xe0ae,0xe0af,
+ 0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xe0b4,0xe0b5,0xe0b6,0xe0b7,
+ 0xe0b8,0xe0b9,0xe0ba,0xe0bb,0xe0bc,0xe0bd,0xe0be,0xe0bf,
+ 0xe0c0,0xe0c1,0xe0c2,0xe0c3,0xe0c4,0xe0c5,0xe0c6,0xe0c7,
+ 0xe0c8,0xe0c9,0xe0ca,0xe0cb,0xe0cc,0xe0cd,0xe0ce,0xe0cf,
+ 0xe0d0,0xe0d1,0xe0d2,0xe0d3,0xe0d4,0xe0d5,0xe0d6,0xe0d7,
+ 0xe0d8,0xe0d9,0xe0da,0xe0db,0xe0dc,0xe0dd,0xe0de,0xe0df,
+ 0xe0e0,0xe0e1,0xe0e2,0xe0e3,0xe0e4,0xe0e5,0xe0e6,0xe0e7,
+ 0xe0e8,0xe0e9,0xe0ea,0xe0eb,0xe0ec,0xe0ed,0xe0ee,0xe0ef,
+ 0xe0f0,0xe0f1,0xe0f2,0xe0f3,0xe0f4,0xe0f5,0xe0f6,0xe0f7,
+ 0xe0f8,0xe0f9,0xe0fa,0xe0fb,0xe0fc,0xe0fd,0xe0fe,0xe0ff,
+ 0xe100,0xe101,0xe102,0xe103,0xe104,0xe105,0xe106,0xe107,
+ 0xe108,0xe109,0xe10a,0xe10b,0xe10c,0xe10d,0xe10e,0xe10f,
+ 0xe110,0xe111,0xe112,0xe113,0xe114,0xe115,0xe116,0xe117,
+ 0xe118,0xe119,0xe11a,0xe11b,0xe11c,0xe11d,0xe11e,0xe11f,
+ 0xe120,0xe121,0xe122,0xe123,0xe124,0xe125,0xe126,0xe127,
+ 0xe128,0xe129,0xe12a,0xe12b,0xe12c,0xe12d,0xe12e,0xe12f,
+ 0xe130,0xe131,0xe132,0xe133,0xe134,0xe135,0xe136,0xe137,
+ 0xe138,0xe139,0xe13a,0xe13b,0xe13c,0xe13d,0xe13e,0xe13f,
+ 0xe140,0xe141,0xe142,0xe143,0xe144,0xe145,0xe146,0xe147,
+ 0xe148,0xe149,0xe14a,0xe14b,0xe14c,0xe14d,0xe14e,0xe14f,
+ 0xe150,0xe151,0xe152,0xe153,0xe154,0xe155,0xe156,0xe157,
+ 0xe158,0xe159,0xe15a,0xe15b,0xe15c,0xe15d,0xe15e,0xe15f,
+ 0xe160,0xe161,0xe162,0xe163,0xe164,0xe165,0xe166,0xe167,
+ 0xe168,0xe169,0xe16a,0xe16b,0xe16c,0xe16d,0xe16e,0xe16f,
+ 0xe170,0xe171,0xe172,0xe173,0xe174,0xe175,0xe176,0xe177,
+ 0xe178,0xe179,0xe17a,0xe17b,0xe17c,0xe17d,0xe17e,0xe17f,
+ 0xe180,0xe181,0xe182,0xe183,0xe184,0xe185,0xe186,0xe187,
+ 0xe188,0xe189,0xe18a,0xe18b,0xe18c,0xe18d,0xe18e,0xe18f,
+ 0xe190,0xe191,0xe192,0xe193,0xe194,0xe195,0xe196,0xe197,
+ 0xe198,0xe199,0xe19a,0xe19b,0xe19c,0xe19d,0xe19e,0xe19f,
+ 0xe1a0,0xe1a1,0xe1a2,0xe1a3,0xe1a4,0xe1a5,0xe1a6,0xe1a7,
+ 0xe1a8,0xe1a9,0xe1aa,0xe1ab,0xe1ac,0xe1ad,0xe1ae,0xe1af,
+ 0xe1b0,0xe1b1,0xe1b2,0xe1b3,0xe1b4,0xe1b5,0xe1b6,0xe1b7,
+ 0xe1b8,0xe1b9,0xe1ba,0xe1bb,0xe1bc,0xe1bd,0xe1be,0xe1bf,
+ 0xe1c0,0xe1c1,0xe1c2,0xe1c3,0xe1c4,0xe1c5,0xe1c6,0xe1c7,
+ 0xe1c8,0xe1c9,0xe1ca,0xe1cb,0xe1cc,0xe1cd,0xe1ce,0xe1cf,
+ 0xe1d0,0xe1d1,0xe1d2,0xe1d3,0xe1d4,0xe1d5,0xe1d6,0xe1d7,
+ 0xe1d8,0xe1d9,0xe1da,0xe1db,0xe1dc,0xe1dd,0xe1de,0xe1df,
+ 0xe1e0,0xe1e1,0xe1e2,0xe1e3,0xe1e4,0xe1e5,0xe1e6,0xe1e7,
+ 0xe1e8,0xe1e9,0xe1ea,0xe1eb,0xe1ec,0xe1ed,0xe1ee,0xe1ef,
+ 0xe1f0,0xe1f1,0xe1f2,0xe1f3,0xe1f4,0xe1f5,0xe1f6,0xe1f7,
+ 0xe1f8,0xe1f9,0xe1fa,0xe1fb,0xe1fc,0xe1fd,0xe1fe,0xe1ff,
+ 0xe200,0xe201,0xe202,0xe203,0xe204,0xe205,0xe206,0xe207,
+ 0xe208,0xe209,0xe20a,0xe20b,0xe20c,0xe20d,0xe20e,0xe20f,
+ 0xe210,0xe211,0xe212,0xe213,0xe214,0xe215,0xe216,0xe217,
+ 0xe218,0xe219,0xe21a,0xe21b,0xe21c,0xe21d,0xe21e,0xe21f,
+ 0xe220,0xe221,0xe222,0xe223,0xe224,0xe225,0xe226,0xe227,
+ 0xe228,0xe229,0xe22a,0xe22b,0xe22c,0xe22d,0xe22e,0xe22f,
+ 0xe230,0xe231,0xe232,0xe233,0xe234,0xe235,0xe236,0xe237,
+ 0xe238,0xe239,0xe23a,0xe23b,0xe23c,0xe23d,0xe23e,0xe23f,
+ 0xe240,0xe241,0xe242,0xe243,0xe244,0xe245,0xe246,0xe247,
+ 0xe248,0xe249,0xe24a,0xe24b,0xe24c,0xe24d,0xe24e,0xe24f,
+ 0xe250,0xe251,0xe252,0xe253,0xe254,0xe255,0xe256,0xe257,
+ 0xe258,0xe259,0xe25a,0xe25b,0xe25c,0xe25d,0xe25e,0xe25f,
+ 0xe260,0xe261,0xe262,0xe263,0xe264,0xe265,0xe266,0xe267,
+ 0xe268,0xe269,0xe26a,0xe26b,0xe26c,0xe26d,0xe26e,0xe26f,
+ 0xe270,0xe271,0xe272,0xe273,0xe274,0xe275,0xe276,0xe277,
+ 0xe278,0xe279,0xe27a,0xe27b,0xe27c,0xe27d,0xe27e,0xe27f,
+ 0xe280,0xe281,0xe282,0xe283,0xe284,0xe285,0xe286,0xe287,
+ 0xe288,0xe289,0xe28a,0xe28b,0xe28c,0xe28d,0xe28e,0xe28f,
+ 0xe290,0xe291,0xe292,0xe293,0xe294,0xe295,0xe296,0xe297,
+ 0xe298,0xe299,0xe29a,0xe29b,0xe29c,0xe29d,0xe29e,0xe29f,
+ 0xe2a0,0xe2a1,0xe2a2,0xe2a3,0xe2a4,0xe2a5,0xe2a6,0xe2a7,
+ 0xe2a8,0xe2a9,0xe2aa,0xe2ab,0xe2ac,0xe2ad,0xe2ae,0xe2af,
+ 0xe2b0,0xe2b1,0xe2b2,0xe2b3,0xe2b4,0xe2b5,0xe2b6,0xe2b7,
+ 0xe2b8,0xe2b9,0xe2ba,0xe2bb,0xe2bc,0xe2bd,0xe2be,0xe2bf,
+ 0xe2c0,0xe2c1,0xe2c2,0xe2c3,0xe2c4,0xe2c5,0xe2c6,0xe2c7,
+ 0xe2c8,0xe2c9,0xe2ca,0xe2cb,0xe2cc,0xe2cd,0xe2ce,0xe2cf,
+ 0xe2d0,0xe2d1,0xe2d2,0xe2d3,0xe2d4,0xe2d5,0xe2d6,0xe2d7,
+ 0xe2d8,0xe2d9,0xe2da,0xe2db,0xe2dc,0xe2dd,0xe2de,0xe2df,
+ 0xe2e0,0xe2e1,0xe2e2,0xe2e3,0xe2e4,0xe2e5,0xe2e6,0xe2e7,
+ 0xe2e8,0xe2e9,0xe2ea,0xe2eb,0xe2ec,0xe2ed,0xe2ee,0xe2ef,
+ 0xe2f0,0xe2f1,0xe2f2,0xe2f3,0xe2f4,0xe2f5,0xe2f6,0xe2f7,
+ 0xe2f8,0xe2f9,0xe2fa,0xe2fb,0xe2fc,0xe2fd,0xe2fe,0xe2ff,
+ 0xe300,0xe301,0xe302,0xe303,0xe304,0xe305,0xe306,0xe307,
+ 0xe308,0xe309,0xe30a,0xe30b,0xe30c,0xe30d,0xe30e,0xe30f,
+ 0xe310,0xe311,0xe312,0xe313,0xe314,0xe315,0xe316,0xe317,
+ 0xe318,0xe319,0xe31a,0xe31b,0xe31c,0xe31d,0xe31e,0xe31f,
+ 0xe320,0xe321,0xe322,0xe323,0xe324,0xe325,0xe326,0xe327,
+ 0xe328,0xe329,0xe32a,0xe32b,0xe32c,0xe32d,0xe32e,0xe32f,
+ 0xe330,0xe331,0xe332,0xe333,0xe334,0xe335,0xe336,0xe337,
+ 0xe338,0xe339,0xe33a,0xe33b,0xe33c,0xe33d,0xe33e,0xe33f,
+ 0xe340,0xe341,0xe342,0xe343,0xe344,0xe345,0xe346,0xe347,
+ 0xe348,0xe349,0xe34a,0xe34b,0xe34c,0xe34d,0xe34e,0xe34f,
+ 0xe350,0xe351,0xe352,0xe353,0xe354,0xe355,0xe356,0xe357,
+ 0xe358,0xe359,0xe35a,0xe35b,0xe35c,0xe35d,0xe35e,0xe35f,
+ 0xe360,0xe361,0xe362,0xe363,0xe364,0xe365,0xe366,0xe367,
+ 0xe368,0xe369,0xe36a,0xe36b,0xe36c,0xe36d,0xe36e,0xe36f,
+ 0xe370,0xe371,0xe372,0xe373,0xe374,0xe375,0xe376,0xe377,
+ 0xe378,0xe379,0xe37a,0xe37b,0xe37c,0xe37d,0xe37e,0xe37f,
+ 0xe380,0xe381,0xe382,0xe383,0xe384,0xe385,0xe386,0xe387,
+ 0xe388,0xe389,0xe38a,0xe38b,0xe38c,0xe38d,0xe38e,0xe38f,
+ 0xe390,0xe391,0xe392,0xe393,0xe394,0xe395,0xe396,0xe397,
+ 0xe398,0xe399,0xe39a,0xe39b,0xe39c,0xe39d,0xe39e,0xe39f,
+ 0xe3a0,0xe3a1,0xe3a2,0xe3a3,0xe3a4,0xe3a5,0xe3a6,0xe3a7,
+ 0xe3a8,0xe3a9,0xe3aa,0xe3ab,0xe3ac,0xe3ad,0xe3ae,0xe3af,
+ 0xe3b0,0xe3b1,0xe3b2,0xe3b3,0xe3b4,0xe3b5,0xe3b6,0xe3b7,
+ 0xe3b8,0xe3b9,0xe3ba,0xe3bb,0xe3bc,0xe3bd,0xe3be,0xe3bf,
+ 0xe3c0,0xe3c1,0xe3c2,0xe3c3,0xe3c4,0xe3c5,0xe3c6,0xe3c7,
+ 0xe3c8,0xe3c9,0xe3ca,0xe3cb,0xe3cc,0xe3cd,0xe3ce,0xe3cf,
+ 0xe3d0,0xe3d1,0xe3d2,0xe3d3,0xe3d4,0xe3d5,0xe3d6,0xe3d7,
+ 0xe3d8,0xe3d9,0xe3da,0xe3db,0xe3dc,0xe3dd,0xe3de,0xe3df,
+ 0xe3e0,0xe3e1,0xe3e2,0xe3e3,0xe3e4,0xe3e5,0xe3e6,0xe3e7,
+ 0xe3e8,0xe3e9,0xe3ea,0xe3eb,0xe3ec,0xe3ed,0xe3ee,0xe3ef,
+ 0xe3f0,0xe3f1,0xe3f2,0xe3f3,0xe3f4,0xe3f5,0xe3f6,0xe3f7,
+ 0xe3f8,0xe3f9,0xe3fa,0xe3fb,0xe3fc,0xe3fd,0xe3fe,0xe3ff,
+ 0xe400,0xe401,0xe402,0xe403,0xe404,0xe405,0xe406,0xe407,
+ 0xe408,0xe409,0xe40a,0xe40b,0xe40c,0xe40d,0xe40e,0xe40f,
+ 0xe410,0xe411,0xe412,0xe413,0xe414,0xe415,0xe416,0xe417,
+ 0xe418,0xe419,0xe41a,0xe41b,0xe41c,0xe41d,0xe41e,0xe41f,
+ 0xe420,0xe421,0xe422,0xe423,0xe424,0xe425,0xe426,0xe427,
+ 0xe428,0xe429,0xe42a,0xe42b,0xe42c,0xe42d,0xe42e,0xe42f,
+ 0xe430,0xe431,0xe432,0xe433,0xe434,0xe435,0xe436,0xe437,
+ 0xe438,0xe439,0xe43a,0xe43b,0xe43c,0xe43d,0xe43e,0xe43f,
+ 0xe440,0xe441,0xe442,0xe443,0xe444,0xe445,0xe446,0xe447,
+ 0xe448,0xe449,0xe44a,0xe44b,0xe44c,0xe44d,0xe44e,0xe44f,
+ 0xe450,0xe451,0xe452,0xe453,0xe454,0xe455,0xe456,0xe457,
+ 0xe458,0xe459,0xe45a,0xe45b,0xe45c,0xe45d,0xe45e,0xe45f,
+ 0xe460,0xe461,0xe462,0xe463,0xe464,0xe465,0xe466,0xe467,
+ 0xe468,0xe469,0xe46a,0xe46b,0xe46c,0xe46d,0xe46e,0xe46f,
+ 0xe470,0xe471,0xe472,0xe473,0xe474,0xe475,0xe476,0xe477,
+ 0xe478,0xe479,0xe47a,0xe47b,0xe47c,0xe47d,0xe47e,0xe47f,
+ 0xe480,0xe481,0xe482,0xe483,0xe484,0xe485,0xe486,0xe487,
+ 0xe488,0xe489,0xe48a,0xe48b,0xe48c,0xe48d,0xe48e,0xe48f,
+ 0xe490,0xe491,0xe492,0xe493,0xe494,0xe495,0xe496,0xe497,
+ 0xe498,0xe499,0xe49a,0xe49b,0xe49c,0xe49d,0xe49e,0xe49f,
+ 0xe4a0,0xe4a1,0xe4a2,0xe4a3,0xe4a4,0xe4a5,0xe4a6,0xe4a7,
+ 0xe4a8,0xe4a9,0xe4aa,0xe4ab,0xe4ac,0xe4ad,0xe4ae,0xe4af,
+ 0xe4b0,0xe4b1,0xe4b2,0xe4b3,0xe4b4,0xe4b5,0xe4b6,0xe4b7,
+ 0xe4b8,0xe4b9,0xe4ba,0xe4bb,0xe4bc,0xe4bd,0xe4be,0xe4bf,
+ 0xe4c0,0xe4c1,0xe4c2,0xe4c3,0xe4c4,0xe4c5,0xe4c6,0xe4c7,
+ 0xe4c8,0xe4c9,0xe4ca,0xe4cb,0xe4cc,0xe4cd,0xe4ce,0xe4cf,
+ 0xe4d0,0xe4d1,0xe4d2,0xe4d3,0xe4d4,0xe4d5,0xe4d6,0xe4d7,
+ 0xe4d8,0xe4d9,0xe4da,0xe4db,0xe4dc,0xe4dd,0xe4de,0xe4df,
+ 0xe4e0,0xe4e1,0xe4e2,0xe4e3,0xe4e4,0xe4e5,0xe4e6,0xe4e7,
+ 0xe4e8,0xe4e9,0xe4ea,0xe4eb,0xe4ec,0xe4ed,0xe4ee,0xe4ef,
+ 0xe4f0,0xe4f1,0xe4f2,0xe4f3,0xe4f4,0xe4f5,0xe4f6,0xe4f7,
+ 0xe4f8,0xe4f9,0xe4fa,0xe4fb,0xe4fc,0xe4fd,0xe4fe,0xe4ff,
+ 0xe500,0xe501,0xe502,0xe503,0xe504,0xe505,0xe506,0xe507,
+ 0xe508,0xe509,0xe50a,0xe50b,0xe50c,0xe50d,0xe50e,0xe50f,
+ 0xe510,0xe511,0xe512,0xe513,0xe514,0xe515,0xe516,0xe517,
+ 0xe518,0xe519,0xe51a,0xe51b,0xe51c,0xe51d,0xe51e,0xe51f,
+ 0xe520,0xe521,0xe522,0xe523,0xe524,0xe525,0xe526,0xe527,
+ 0xe528,0xe529,0xe52a,0xe52b,0xe52c,0xe52d,0xe52e,0xe52f,
+ 0xe530,0xe531,0xe532,0xe533,0xe534,0xe535,0xe536,0xe537,
+ 0xe538,0xe539,0xe53a,0xe53b,0xe53c,0xe53d,0xe53e,0xe53f,
+ 0xe540,0xe541,0xe542,0xe543,0xe544,0xe545,0xe546,0xe547,
+ 0xe548,0xe549,0xe54a,0xe54b,0xe54c,0xe54d,0xe54e,0xe54f,
+ 0xe550,0xe551,0xe552,0xe553,0xe554,0xe555,0xe556,0xe557,
+ 0xe558,0xe559,0xe55a,0xe55b,0xe55c,0xe55d,0xe55e,0xe55f,
+ 0xe560,0xe561,0xe562,0xe563,0xe564,0xe565,0xe566,0xe567,
+ 0xe568,0xe569,0xe56a,0xe56b,0xe56c,0xe56d,0xe56e,0xe56f,
+ 0xe570,0xe571,0xe572,0xe573,0xe574,0xe575,0xe576,0xe577,
+ 0xe578,0xe579,0xe57a,0xe57b,0xe57c,0xe57d,0xe57e,0xe57f,
+ 0xe580,0xe581,0xe582,0xe583,0xe584,0xe585,0xe586,0xe587,
+ 0xe588,0xe589,0xe58a,0xe58b,0xe58c,0xe58d,0xe58e,0xe58f,
+ 0xe590,0xe591,0xe592,0xe593,0xe594,0xe595,0xe596,0xe597,
+ 0xe598,0xe599,0xe59a,0xe59b,0xe59c,0xe59d,0xe59e,0xe59f,
+ 0xe5a0,0xe5a1,0xe5a2,0xe5a3,0xe5a4,0xe5a5,0xe5a6,0xe5a7,
+ 0xe5a8,0xe5a9,0xe5aa,0xe5ab,0xe5ac,0xe5ad,0xe5ae,0xe5af,
+ 0xe5b0,0xe5b1,0xe5b2,0xe5b3,0xe5b4,0xe5b5,0xe5b6,0xe5b7,
+ 0xe5b8,0xe5b9,0xe5ba,0xe5bb,0xe5bc,0xe5bd,0xe5be,0xe5bf,
+ 0xe5c0,0xe5c1,0xe5c2,0xe5c3,0xe5c4,0xe5c5,0xe5c6,0xe5c7,
+ 0xe5c8,0xe5c9,0xe5ca,0xe5cb,0xe5cc,0xe5cd,0xe5ce,0xe5cf,
+ 0xe5d0,0xe5d1,0xe5d2,0xe5d3,0xe5d4,0xe5d5,0xe5d6,0xe5d7,
+ 0xe5d8,0xe5d9,0xe5da,0xe5db,0xe5dc,0xe5dd,0xe5de,0xe5df,
+ 0xe5e0,0xe5e1,0xe5e2,0xe5e3,0xe5e4,0xe5e5,0xe5e6,0xe5e7,
+ 0xe5e8,0xe5e9,0xe5ea,0xe5eb,0xe5ec,0xe5ed,0xe5ee,0xe5ef,
+ 0xe5f0,0xe5f1,0xe5f2,0xe5f3,0xe5f4,0xe5f5,0xe5f6,0xe5f7,
+ 0xe5f8,0xe5f9,0xe5fa,0xe5fb,0xe5fc,0xe5fd,0xe5fe,0xe5ff,
+ 0xe600,0xe601,0xe602,0xe603,0xe604,0xe605,0xe606,0xe607,
+ 0xe608,0xe609,0xe60a,0xe60b,0xe60c,0xe60d,0xe60e,0xe60f,
+ 0xe610,0xe611,0xe612,0xe613,0xe614,0xe615,0xe616,0xe617,
+ 0xe618,0xe619,0xe61a,0xe61b,0xe61c,0xe61d,0xe61e,0xe61f,
+ 0xe620,0xe621,0xe622,0xe623,0xe624,0xe625,0xe626,0xe627,
+ 0xe628,0xe629,0xe62a,0xe62b,0xe62c,0xe62d,0xe62e,0xe62f,
+ 0xe630,0xe631,0xe632,0xe633,0xe634,0xe635,0xe636,0xe637,
+ 0xe638,0xe639,0xe63a,0xe63b,0xe63c,0xe63d,0xe63e,0xe63f,
+ 0xe640,0xe641,0xe642,0xe643,0xe644,0xe645,0xe646,0xe647,
+ 0xe648,0xe649,0xe64a,0xe64b,0xe64c,0xe64d,0xe64e,0xe64f,
+ 0xe650,0xe651,0xe652,0xe653,0xe654,0xe655,0xe656,0xe657,
+ 0xe658,0xe659,0xe65a,0xe65b,0xe65c,0xe65d,0xe65e,0xe65f,
+ 0xe660,0xe661,0xe662,0xe663,0xe664,0xe665,0xe666,0xe667,
+ 0xe668,0xe669,0xe66a,0xe66b,0xe66c,0xe66d,0xe66e,0xe66f,
+ 0xe670,0xe671,0xe672,0xe673,0xe674,0xe675,0xe676,0xe677,
+ 0xe678,0xe679,0xe67a,0xe67b,0xe67c,0xe67d,0xe67e,0xe67f,
+ 0xe680,0xe681,0xe682,0xe683,0xe684,0xe685,0xe686,0xe687,
+ 0xe688,0xe689,0xe68a,0xe68b,0xe68c,0xe68d,0xe68e,0xe68f,
+ 0xe690,0xe691,0xe692,0xe693,0xe694,0xe695,0xe696,0xe697,
+ 0xe698,0xe699,0xe69a,0xe69b,0xe69c,0xe69d,0xe69e,0xe69f,
+ 0xe6a0,0xe6a1,0xe6a2,0xe6a3,0xe6a4,0xe6a5,0xe6a6,0xe6a7,
+ 0xe6a8,0xe6a9,0xe6aa,0xe6ab,0xe6ac,0xe6ad,0xe6ae,0xe6af,
+ 0xe6b0,0xe6b1,0xe6b2,0xe6b3,0xe6b4,0xe6b5,0xe6b6,0xe6b7,
+ 0xe6b8,0xe6b9,0xe6ba,0xe6bb,0xe6bc,0xe6bd,0xe6be,0xe6bf,
+ 0xe6c0,0xe6c1,0xe6c2,0xe6c3,0xe6c4,0xe6c5,0xe6c6,0xe6c7,
+ 0xe6c8,0xe6c9,0xe6ca,0xe6cb,0xe6cc,0xe6cd,0xe6ce,0xe6cf,
+ 0xe6d0,0xe6d1,0xe6d2,0xe6d3,0xe6d4,0xe6d5,0xe6d6,0xe6d7,
+ 0xe6d8,0xe6d9,0xe6da,0xe6db,0xe6dc,0xe6dd,0xe6de,0xe6df,
+ 0xe6e0,0xe6e1,0xe6e2,0xe6e3,0xe6e4,0xe6e5,0xe6e6,0xe6e7,
+ 0xe6e8,0xe6e9,0xe6ea,0xe6eb,0xe6ec,0xe6ed,0xe6ee,0xe6ef,
+ 0xe6f0,0xe6f1,0xe6f2,0xe6f3,0xe6f4,0xe6f5,0xe6f6,0xe6f7,
+ 0xe6f8,0xe6f9,0xe6fa,0xe6fb,0xe6fc,0xe6fd,0xe6fe,0xe6ff,
+ 0xe700,0xe701,0xe702,0xe703,0xe704,0xe705,0xe706,0xe707,
+ 0xe708,0xe709,0xe70a,0xe70b,0xe70c,0xe70d,0xe70e,0xe70f,
+ 0xe710,0xe711,0xe712,0xe713,0xe714,0xe715,0xe716,0xe717,
+ 0xe718,0xe719,0xe71a,0xe71b,0xe71c,0xe71d,0xe71e,0xe71f,
+ 0xe720,0xe721,0xe722,0xe723,0xe724,0xe725,0xe726,0xe727,
+ 0xe728,0xe729,0xe72a,0xe72b,0xe72c,0xe72d,0xe72e,0xe72f,
+ 0xe730,0xe731,0xe732,0xe733,0xe734,0xe735,0xe736,0xe737,
+ 0xe738,0xe739,0xe73a,0xe73b,0xe73c,0xe73d,0xe73e,0xe73f,
+ 0xe740,0xe741,0xe742,0xe743,0xe744,0xe745,0xe746,0xe747,
+ 0xe748,0xe749,0xe74a,0xe74b,0xe74c,0xe74d,0xe74e,0xe74f,
+ 0xe750,0xe751,0xe752,0xe753,0xe754,0xe755,0xe756,0xe757,
+ 0xe758,0xe759,0xe75a,0xe75b,0xe75c,0xe75d,0xe75e,0xe75f,
+ 0xe760,0xe761,0xe762,0xe763,0xe764,0xe765,0xe766,0xe767,
+ 0xe768,0xe769,0xe76a,0xe76b,0xe76c,0xe76d,0xe76e,0xe76f,
+ 0xe770,0xe771,0xe772,0xe773,0xe774,0xe775,0xe776,0xe777,
+ 0xe778,0xe779,0xe77a,0xe77b,0xe77c,0xe77d,0xe77e,0xe77f,
+ 0xe780,0xe781,0xe782,0xe783,0xe784,0xe785,0xe786,0xe787,
+ 0xe788,0xe789,0xe78a,0xe78b,0xe78c,0xe78d,0xe78e,0xe78f,
+ 0xe790,0xe791,0xe792,0xe793,0xe794,0xe795,0xe796,0xe797,
+ 0xe798,0xe799,0xe79a,0xe79b,0xe79c,0xe79d,0xe79e,0xe79f,
+ 0xe7a0,0xe7a1,0xe7a2,0xe7a3,0xe7a4,0xe7a5,0xe7a6,0xe7a7,
+ 0xe7a8,0xe7a9,0xe7aa,0xe7ab,0xe7ac,0xe7ad,0xe7ae,0xe7af,
+ 0xe7b0,0xe7b1,0xe7b2,0xe7b3,0xe7b4,0xe7b5,0xe7b6,0xe7b7,
+ 0xe7b8,0xe7b9,0xe7ba,0xe7bb,0xe7bc,0xe7bd,0xe7be,0xe7bf,
+ 0xe7c0,0xe7c1,0xe7c2,0xe7c3,0xe7c4,0xe7c5,0xe7c6,0xe7c7,
+ 0xe7c8,0xe7c9,0xe7ca,0xe7cb,0xe7cc,0xe7cd,0xe7ce,0xe7cf,
+ 0xe7d0,0xe7d1,0xe7d2,0xe7d3,0xe7d4,0xe7d5,0xe7d6,0xe7d7,
+ 0xe7d8,0xe7d9,0xe7da,0xe7db,0xe7dc,0xe7dd,0xe7de,0xe7df,
+ 0xe7e0,0xe7e1,0xe7e2,0xe7e3,0xe7e4,0xe7e5,0xe7e6,0xe7e7,
+ 0xe7e8,0xe7e9,0xe7ea,0xe7eb,0xe7ec,0xe7ed,0xe7ee,0xe7ef,
+ 0xe7f0,0xe7f1,0xe7f2,0xe7f3,0xe7f4,0xe7f5,0xe7f6,0xe7f7,
+ 0xe7f8,0xe7f9,0xe7fa,0xe7fb,0xe7fc,0xe7fd,0xe7fe,0xe7ff,
+ 0xe800,0xe801,0xe802,0xe803,0xe804,0xe805,0xe806,0xe807,
+ 0xe808,0xe809,0xe80a,0xe80b,0xe80c,0xe80d,0xe80e,0xe80f,
+ 0xe810,0xe811,0xe812,0xe813,0xe814,0xe815,0xe816,0xe817,
+ 0xe818,0xe819,0xe81a,0xe81b,0xe81c,0xe81d,0xe81e,0xe81f,
+ 0xe820,0xe821,0xe822,0xe823,0xe824,0xe825,0xe826,0xe827,
+ 0xe828,0xe829,0xe82a,0xe82b,0xe82c,0xe82d,0xe82e,0xe82f,
+ 0xe830,0xe831,0xe832,0xe833,0xe834,0xe835,0xe836,0xe837,
+ 0xe838,0xe839,0xe83a,0xe83b,0xe83c,0xe83d,0xe83e,0xe83f,
+ 0xe840,0xe841,0xe842,0xe843,0xe844,0xe845,0xe846,0xe847,
+ 0xe848,0xe849,0xe84a,0xe84b,0xe84c,0xe84d,0xe84e,0xe84f,
+ 0xe850,0xe851,0xe852,0xe853,0xe854,0xe855,0xe856,0xe857,
+ 0xe858,0xe859,0xe85a,0xe85b,0xe85c,0xe85d,0xe85e,0xe85f,
+ 0xe860,0xe861,0xe862,0xe863,0xe864,0xe865,0xe866,0xe867,
+ 0xe868,0xe869,0xe86a,0xe86b,0xe86c,0xe86d,0xe86e,0xe86f,
+ 0xe870,0xe871,0xe872,0xe873,0xe874,0xe875,0xe876,0xe877,
+ 0xe878,0xe879,0xe87a,0xe87b,0xe87c,0xe87d,0xe87e,0xe87f,
+ 0xe880,0xe881,0xe882,0xe883,0xe884,0xe885,0xe886,0xe887,
+ 0xe888,0xe889,0xe88a,0xe88b,0xe88c,0xe88d,0xe88e,0xe88f,
+ 0xe890,0xe891,0xe892,0xe893,0xe894,0xe895,0xe896,0xe897,
+ 0xe898,0xe899,0xe89a,0xe89b,0xe89c,0xe89d,0xe89e,0xe89f,
+ 0xe8a0,0xe8a1,0xe8a2,0xe8a3,0xe8a4,0xe8a5,0xe8a6,0xe8a7,
+ 0xe8a8,0xe8a9,0xe8aa,0xe8ab,0xe8ac,0xe8ad,0xe8ae,0xe8af,
+ 0xe8b0,0xe8b1,0xe8b2,0xe8b3,0xe8b4,0xe8b5,0xe8b6,0xe8b7,
+ 0xe8b8,0xe8b9,0xe8ba,0xe8bb,0xe8bc,0xe8bd,0xe8be,0xe8bf,
+ 0xe8c0,0xe8c1,0xe8c2,0xe8c3,0xe8c4,0xe8c5,0xe8c6,0xe8c7,
+ 0xe8c8,0xe8c9,0xe8ca,0xe8cb,0xe8cc,0xe8cd,0xe8ce,0xe8cf,
+ 0xe8d0,0xe8d1,0xe8d2,0xe8d3,0xe8d4,0xe8d5,0xe8d6,0xe8d7,
+ 0xe8d8,0xe8d9,0xe8da,0xe8db,0xe8dc,0xe8dd,0xe8de,0xe8df,
+ 0xe8e0,0xe8e1,0xe8e2,0xe8e3,0xe8e4,0xe8e5,0xe8e6,0xe8e7,
+ 0xe8e8,0xe8e9,0xe8ea,0xe8eb,0xe8ec,0xe8ed,0xe8ee,0xe8ef,
+ 0xe8f0,0xe8f1,0xe8f2,0xe8f3,0xe8f4,0xe8f5,0xe8f6,0xe8f7,
+ 0xe8f8,0xe8f9,0xe8fa,0xe8fb,0xe8fc,0xe8fd,0xe8fe,0xe8ff,
+ 0xe900,0xe901,0xe902,0xe903,0xe904,0xe905,0xe906,0xe907,
+ 0xe908,0xe909,0xe90a,0xe90b,0xe90c,0xe90d,0xe90e,0xe90f,
+ 0xe910,0xe911,0xe912,0xe913,0xe914,0xe915,0xe916,0xe917,
+ 0xe918,0xe919,0xe91a,0xe91b,0xe91c,0xe91d,0xe91e,0xe91f,
+ 0xe920,0xe921,0xe922,0xe923,0xe924,0xe925,0xe926,0xe927,
+ 0xe928,0xe929,0xe92a,0xe92b,0xe92c,0xe92d,0xe92e,0xe92f,
+ 0xe930,0xe931,0xe932,0xe933,0xe934,0xe935,0xe936,0xe937,
+ 0xe938,0xe939,0xe93a,0xe93b,0xe93c,0xe93d,0xe93e,0xe93f,
+ 0xe940,0xe941,0xe942,0xe943,0xe944,0xe945,0xe946,0xe947,
+ 0xe948,0xe949,0xe94a,0xe94b,0xe94c,0xe94d,0xe94e,0xe94f,
+ 0xe950,0xe951,0xe952,0xe953,0xe954,0xe955,0xe956,0xe957,
+ 0xe958,0xe959,0xe95a,0xe95b,0xe95c,0xe95d,0xe95e,0xe95f,
+ 0xe960,0xe961,0xe962,0xe963,0xe964,0xe965,0xe966,0xe967,
+ 0xe968,0xe969,0xe96a,0xe96b,0xe96c,0xe96d,0xe96e,0xe96f,
+ 0xe970,0xe971,0xe972,0xe973,0xe974,0xe975,0xe976,0xe977,
+ 0xe978,0xe979,0xe97a,0xe97b,0xe97c,0xe97d,0xe97e,0xe97f,
+ 0xe980,0xe981,0xe982,0xe983,0xe984,0xe985,0xe986,0xe987,
+ 0xe988,0xe989,0xe98a,0xe98b,0xe98c,0xe98d,0xe98e,0xe98f,
+ 0xe990,0xe991,0xe992,0xe993,0xe994,0xe995,0xe996,0xe997,
+ 0xe998,0xe999,0xe99a,0xe99b,0xe99c,0xe99d,0xe99e,0xe99f,
+ 0xe9a0,0xe9a1,0xe9a2,0xe9a3,0xe9a4,0xe9a5,0xe9a6,0xe9a7,
+ 0xe9a8,0xe9a9,0xe9aa,0xe9ab,0xe9ac,0xe9ad,0xe9ae,0xe9af,
+ 0xe9b0,0xe9b1,0xe9b2,0xe9b3,0xe9b4,0xe9b5,0xe9b6,0xe9b7,
+ 0xe9b8,0xe9b9,0xe9ba,0xe9bb,0xe9bc,0xe9bd,0xe9be,0xe9bf,
+ 0xe9c0,0xe9c1,0xe9c2,0xe9c3,0xe9c4,0xe9c5,0xe9c6,0xe9c7,
+ 0xe9c8,0xe9c9,0xe9ca,0xe9cb,0xe9cc,0xe9cd,0xe9ce,0xe9cf,
+ 0xe9d0,0xe9d1,0xe9d2,0xe9d3,0xe9d4,0xe9d5,0xe9d6,0xe9d7,
+ 0xe9d8,0xe9d9,0xe9da,0xe9db,0xe9dc,0xe9dd,0xe9de,0xe9df,
+ 0xe9e0,0xe9e1,0xe9e2,0xe9e3,0xe9e4,0xe9e5,0xe9e6,0xe9e7,
+ 0xe9e8,0xe9e9,0xe9ea,0xe9eb,0xe9ec,0xe9ed,0xe9ee,0xe9ef,
+ 0xe9f0,0xe9f1,0xe9f2,0xe9f3,0xe9f4,0xe9f5,0xe9f6,0xe9f7,
+ 0xe9f8,0xe9f9,0xe9fa,0xe9fb,0xe9fc,0xe9fd,0xe9fe,0xe9ff,
+ 0xea00,0xea01,0xea02,0xea03,0xea04,0xea05,0xea06,0xea07,
+ 0xea08,0xea09,0xea0a,0xea0b,0xea0c,0xea0d,0xea0e,0xea0f,
+ 0xea10,0xea11,0xea12,0xea13,0xea14,0xea15,0xea16,0xea17,
+ 0xea18,0xea19,0xea1a,0xea1b,0xea1c,0xea1d,0xea1e,0xea1f,
+ 0xea20,0xea21,0xea22,0xea23,0xea24,0xea25,0xea26,0xea27,
+ 0xea28,0xea29,0xea2a,0xea2b,0xea2c,0xea2d,0xea2e,0xea2f,
+ 0xea30,0xea31,0xea32,0xea33,0xea34,0xea35,0xea36,0xea37,
+ 0xea38,0xea39,0xea3a,0xea3b,0xea3c,0xea3d,0xea3e,0xea3f,
+ 0xea40,0xea41,0xea42,0xea43,0xea44,0xea45,0xea46,0xea47,
+ 0xea48,0xea49,0xea4a,0xea4b,0xea4c,0xea4d,0xea4e,0xea4f,
+ 0xea50,0xea51,0xea52,0xea53,0xea54,0xea55,0xea56,0xea57,
+ 0xea58,0xea59,0xea5a,0xea5b,0xea5c,0xea5d,0xea5e,0xea5f,
+ 0xea60,0xea61,0xea62,0xea63,0xea64,0xea65,0xea66,0xea67,
+ 0xea68,0xea69,0xea6a,0xea6b,0xea6c,0xea6d,0xea6e,0xea6f,
+ 0xea70,0xea71,0xea72,0xea73,0xea74,0xea75,0xea76,0xea77,
+ 0xea78,0xea79,0xea7a,0xea7b,0xea7c,0xea7d,0xea7e,0xea7f,
+ 0xea80,0xea81,0xea82,0xea83,0xea84,0xea85,0xea86,0xea87,
+ 0xea88,0xea89,0xea8a,0xea8b,0xea8c,0xea8d,0xea8e,0xea8f,
+ 0xea90,0xea91,0xea92,0xea93,0xea94,0xea95,0xea96,0xea97,
+ 0xea98,0xea99,0xea9a,0xea9b,0xea9c,0xea9d,0xea9e,0xea9f,
+ 0xeaa0,0xeaa1,0xeaa2,0xeaa3,0xeaa4,0xeaa5,0xeaa6,0xeaa7,
+ 0xeaa8,0xeaa9,0xeaaa,0xeaab,0xeaac,0xeaad,0xeaae,0xeaaf,
+ 0xeab0,0xeab1,0xeab2,0xeab3,0xeab4,0xeab5,0xeab6,0xeab7,
+ 0xeab8,0xeab9,0xeaba,0xeabb,0xeabc,0xeabd,0xeabe,0xeabf,
+ 0xeac0,0xeac1,0xeac2,0xeac3,0xeac4,0xeac5,0xeac6,0xeac7,
+ 0xeac8,0xeac9,0xeaca,0xeacb,0xeacc,0xeacd,0xeace,0xeacf,
+ 0xead0,0xead1,0xead2,0xead3,0xead4,0xead5,0xead6,0xead7,
+ 0xead8,0xead9,0xeada,0xeadb,0xeadc,0xeadd,0xeade,0xeadf,
+ 0xeae0,0xeae1,0xeae2,0xeae3,0xeae4,0xeae5,0xeae6,0xeae7,
+ 0xeae8,0xeae9,0xeaea,0xeaeb,0xeaec,0xeaed,0xeaee,0xeaef,
+ 0xeaf0,0xeaf1,0xeaf2,0xeaf3,0xeaf4,0xeaf5,0xeaf6,0xeaf7,
+ 0xeaf8,0xeaf9,0xeafa,0xeafb,0xeafc,0xeafd,0xeafe,0xeaff,
+ 0xeb00,0xeb01,0xeb02,0xeb03,0xeb04,0xeb05,0xeb06,0xeb07,
+ 0xeb08,0xeb09,0xeb0a,0xeb0b,0xeb0c,0xeb0d,0xeb0e,0xeb0f,
+ 0xeb10,0xeb11,0xeb12,0xeb13,0xeb14,0xeb15,0xeb16,0xeb17,
+ 0xeb18,0xeb19,0xeb1a,0xeb1b,0xeb1c,0xeb1d,0xeb1e,0xeb1f,
+ 0xeb20,0xeb21,0xeb22,0xeb23,0xeb24,0xeb25,0xeb26,0xeb27,
+ 0xeb28,0xeb29,0xeb2a,0xeb2b,0xeb2c,0xeb2d,0xeb2e,0xeb2f,
+ 0xeb30,0xeb31,0xeb32,0xeb33,0xeb34,0xeb35,0xeb36,0xeb37,
+ 0xeb38,0xeb39,0xeb3a,0xeb3b,0xeb3c,0xeb3d,0xeb3e,0xeb3f,
+ 0xeb40,0xeb41,0xeb42,0xeb43,0xeb44,0xeb45,0xeb46,0xeb47,
+ 0xeb48,0xeb49,0xeb4a,0xeb4b,0xeb4c,0xeb4d,0xeb4e,0xeb4f,
+ 0xeb50,0xeb51,0xeb52,0xeb53,0xeb54,0xeb55,0xeb56,0xeb57,
+ 0xeb58,0xeb59,0xeb5a,0xeb5b,0xeb5c,0xeb5d,0xeb5e,0xeb5f,
+ 0xeb60,0xeb61,0xeb62,0xeb63,0xeb64,0xeb65,0xeb66,0xeb67,
+ 0xeb68,0xeb69,0xeb6a,0xeb6b,0xeb6c,0xeb6d,0xeb6e,0xeb6f,
+ 0xeb70,0xeb71,0xeb72,0xeb73,0xeb74,0xeb75,0xeb76,0xeb77,
+ 0xeb78,0xeb79,0xeb7a,0xeb7b,0xeb7c,0xeb7d,0xeb7e,0xeb7f,
+ 0xeb80,0xeb81,0xeb82,0xeb83,0xeb84,0xeb85,0xeb86,0xeb87,
+ 0xeb88,0xeb89,0xeb8a,0xeb8b,0xeb8c,0xeb8d,0xeb8e,0xeb8f,
+ 0xeb90,0xeb91,0xeb92,0xeb93,0xeb94,0xeb95,0xeb96,0xeb97,
+ 0xeb98,0xeb99,0xeb9a,0xeb9b,0xeb9c,0xeb9d,0xeb9e,0xeb9f,
+ 0xeba0,0xeba1,0xeba2,0xeba3,0xeba4,0xeba5,0xeba6,0xeba7,
+ 0xeba8,0xeba9,0xebaa,0xebab,0xebac,0xebad,0xebae,0xebaf,
+ 0xebb0,0xebb1,0xebb2,0xebb3,0xebb4,0xebb5,0xebb6,0xebb7,
+ 0xebb8,0xebb9,0xebba,0xebbb,0xebbc,0xebbd,0xebbe,0xebbf,
+ 0xebc0,0xebc1,0xebc2,0xebc3,0xebc4,0xebc5,0xebc6,0xebc7,
+ 0xebc8,0xebc9,0xebca,0xebcb,0xebcc,0xebcd,0xebce,0xebcf,
+ 0xebd0,0xebd1,0xebd2,0xebd3,0xebd4,0xebd5,0xebd6,0xebd7,
+ 0xebd8,0xebd9,0xebda,0xebdb,0xebdc,0xebdd,0xebde,0xebdf,
+ 0xebe0,0xebe1,0xebe2,0xebe3,0xebe4,0xebe5,0xebe6,0xebe7,
+ 0xebe8,0xebe9,0xebea,0xebeb,0xebec,0xebed,0xebee,0xebef,
+ 0xebf0,0xebf1,0xebf2,0xebf3,0xebf4,0xebf5,0xebf6,0xebf7,
+ 0xebf8,0xebf9,0xebfa,0xebfb,0xebfc,0xebfd,0xebfe,0xebff,
+ 0xec00,0xec01,0xec02,0xec03,0xec04,0xec05,0xec06,0xec07,
+ 0xec08,0xec09,0xec0a,0xec0b,0xec0c,0xec0d,0xec0e,0xec0f,
+ 0xec10,0xec11,0xec12,0xec13,0xec14,0xec15,0xec16,0xec17,
+ 0xec18,0xec19,0xec1a,0xec1b,0xec1c,0xec1d,0xec1e,0xec1f,
+ 0xec20,0xec21,0xec22,0xec23,0xec24,0xec25,0xec26,0xec27,
+ 0xec28,0xec29,0xec2a,0xec2b,0xec2c,0xec2d,0xec2e,0xec2f,
+ 0xec30,0xec31,0xec32,0xec33,0xec34,0xec35,0xec36,0xec37,
+ 0xec38,0xec39,0xec3a,0xec3b,0xec3c,0xec3d,0xec3e,0xec3f,
+ 0xec40,0xec41,0xec42,0xec43,0xec44,0xec45,0xec46,0xec47,
+ 0xec48,0xec49,0xec4a,0xec4b,0xec4c,0xec4d,0xec4e,0xec4f,
+ 0xec50,0xec51,0xec52,0xec53,0xec54,0xec55,0xec56,0xec57,
+ 0xec58,0xec59,0xec5a,0xec5b,0xec5c,0xec5d,0xec5e,0xec5f,
+ 0xec60,0xec61,0xec62,0xec63,0xec64,0xec65,0xec66,0xec67,
+ 0xec68,0xec69,0xec6a,0xec6b,0xec6c,0xec6d,0xec6e,0xec6f,
+ 0xec70,0xec71,0xec72,0xec73,0xec74,0xec75,0xec76,0xec77,
+ 0xec78,0xec79,0xec7a,0xec7b,0xec7c,0xec7d,0xec7e,0xec7f,
+ 0xec80,0xec81,0xec82,0xec83,0xec84,0xec85,0xec86,0xec87,
+ 0xec88,0xec89,0xec8a,0xec8b,0xec8c,0xec8d,0xec8e,0xec8f,
+ 0xec90,0xec91,0xec92,0xec93,0xec94,0xec95,0xec96,0xec97,
+ 0xec98,0xec99,0xec9a,0xec9b,0xec9c,0xec9d,0xec9e,0xec9f,
+ 0xeca0,0xeca1,0xeca2,0xeca3,0xeca4,0xeca5,0xeca6,0xeca7,
+ 0xeca8,0xeca9,0xecaa,0xecab,0xecac,0xecad,0xecae,0xecaf,
+ 0xecb0,0xecb1,0xecb2,0xecb3,0xecb4,0xecb5,0xecb6,0xecb7,
+ 0xecb8,0xecb9,0xecba,0xecbb,0xecbc,0xecbd,0xecbe,0xecbf,
+ 0xecc0,0xecc1,0xecc2,0xecc3,0xecc4,0xecc5,0xecc6,0xecc7,
+ 0xecc8,0xecc9,0xecca,0xeccb,0xeccc,0xeccd,0xecce,0xeccf,
+ 0xecd0,0xecd1,0xecd2,0xecd3,0xecd4,0xecd5,0xecd6,0xecd7,
+ 0xecd8,0xecd9,0xecda,0xecdb,0xecdc,0xecdd,0xecde,0xecdf,
+ 0xece0,0xece1,0xece2,0xece3,0xece4,0xece5,0xece6,0xece7,
+ 0xece8,0xece9,0xecea,0xeceb,0xecec,0xeced,0xecee,0xecef,
+ 0xecf0,0xecf1,0xecf2,0xecf3,0xecf4,0xecf5,0xecf6,0xecf7,
+ 0xecf8,0xecf9,0xecfa,0xecfb,0xecfc,0xecfd,0xecfe,0xecff,
+ 0xed00,0xed01,0xed02,0xed03,0xed04,0xed05,0xed06,0xed07,
+ 0xed08,0xed09,0xed0a,0xed0b,0xed0c,0xed0d,0xed0e,0xed0f,
+ 0xed10,0xed11,0xed12,0xed13,0xed14,0xed15,0xed16,0xed17,
+ 0xed18,0xed19,0xed1a,0xed1b,0xed1c,0xed1d,0xed1e,0xed1f,
+ 0xed20,0xed21,0xed22,0xed23,0xed24,0xed25,0xed26,0xed27,
+ 0xed28,0xed29,0xed2a,0xed2b,0xed2c,0xed2d,0xed2e,0xed2f,
+ 0xed30,0xed31,0xed32,0xed33,0xed34,0xed35,0xed36,0xed37,
+ 0xed38,0xed39,0xed3a,0xed3b,0xed3c,0xed3d,0xed3e,0xed3f,
+ 0xed40,0xed41,0xed42,0xed43,0xed44,0xed45,0xed46,0xed47,
+ 0xed48,0xed49,0xed4a,0xed4b,0xed4c,0xed4d,0xed4e,0xed4f,
+ 0xed50,0xed51,0xed52,0xed53,0xed54,0xed55,0xed56,0xed57,
+ 0xed58,0xed59,0xed5a,0xed5b,0xed5c,0xed5d,0xed5e,0xed5f,
+ 0xed60,0xed61,0xed62,0xed63,0xed64,0xed65,0xed66,0xed67,
+ 0xed68,0xed69,0xed6a,0xed6b,0xed6c,0xed6d,0xed6e,0xed6f,
+ 0xed70,0xed71,0xed72,0xed73,0xed74,0xed75,0xed76,0xed77,
+ 0xed78,0xed79,0xed7a,0xed7b,0xed7c,0xed7d,0xed7e,0xed7f,
+ 0xed80,0xed81,0xed82,0xed83,0xed84,0xed85,0xed86,0xed87,
+ 0xed88,0xed89,0xed8a,0xed8b,0xed8c,0xed8d,0xed8e,0xed8f,
+ 0xed90,0xed91,0xed92,0xed93,0xed94,0xed95,0xed96,0xed97,
+ 0xed98,0xed99,0xed9a,0xed9b,0xed9c,0xed9d,0xed9e,0xed9f,
+ 0xeda0,0xeda1,0xeda2,0xeda3,0xeda4,0xeda5,0xeda6,0xeda7,
+ 0xeda8,0xeda9,0xedaa,0xedab,0xedac,0xedad,0xedae,0xedaf,
+ 0xedb0,0xedb1,0xedb2,0xedb3,0xedb4,0xedb5,0xedb6,0xedb7,
+ 0xedb8,0xedb9,0xedba,0xedbb,0xedbc,0xedbd,0xedbe,0xedbf,
+ 0xedc0,0xedc1,0xedc2,0xedc3,0xedc4,0xedc5,0xedc6,0xedc7,
+ 0xedc8,0xedc9,0xedca,0xedcb,0xedcc,0xedcd,0xedce,0xedcf,
+ 0xedd0,0xedd1,0xedd2,0xedd3,0xedd4,0xedd5,0xedd6,0xedd7,
+ 0xedd8,0xedd9,0xedda,0xeddb,0xeddc,0xeddd,0xedde,0xeddf,
+ 0xede0,0xede1,0xede2,0xede3,0xede4,0xede5,0xede6,0xede7,
+ 0xede8,0xede9,0xedea,0xedeb,0xedec,0xeded,0xedee,0xedef,
+ 0xedf0,0xedf1,0xedf2,0xedf3,0xedf4,0xedf5,0xedf6,0xedf7,
+ 0xedf8,0xedf9,0xedfa,0xedfb,0xedfc,0xedfd,0xedfe,0xedff,
+ 0xee00,0xee01,0xee02,0xee03,0xee04,0xee05,0xee06,0xee07,
+ 0xee08,0xee09,0xee0a,0xee0b,0xee0c,0xee0d,0xee0e,0xee0f,
+ 0xee10,0xee11,0xee12,0xee13,0xee14,0xee15,0xee16,0xee17,
+ 0xee18,0xee19,0xee1a,0xee1b,0xee1c,0xee1d,0xee1e,0xee1f,
+ 0xee20,0xee21,0xee22,0xee23,0xee24,0xee25,0xee26,0xee27,
+ 0xee28,0xee29,0xee2a,0xee2b,0xee2c,0xee2d,0xee2e,0xee2f,
+ 0xee30,0xee31,0xee32,0xee33,0xee34,0xee35,0xee36,0xee37,
+ 0xee38,0xee39,0xee3a,0xee3b,0xee3c,0xee3d,0xee3e,0xee3f,
+ 0xee40,0xee41,0xee42,0xee43,0xee44,0xee45,0xee46,0xee47,
+ 0xee48,0xee49,0xee4a,0xee4b,0xee4c,0xee4d,0xee4e,0xee4f,
+ 0xee50,0xee51,0xee52,0xee53,0xee54,0xee55,0xee56,0xee57,
+ 0xee58,0xee59,0xee5a,0xee5b,0xee5c,0xee5d,0xee5e,0xee5f,
+ 0xee60,0xee61,0xee62,0xee63,0xee64,0xee65,0xee66,0xee67,
+ 0xee68,0xee69,0xee6a,0xee6b,0xee6c,0xee6d,0xee6e,0xee6f,
+ 0xee70,0xee71,0xee72,0xee73,0xee74,0xee75,0xee76,0xee77,
+ 0xee78,0xee79,0xee7a,0xee7b,0xee7c,0xee7d,0xee7e,0xee7f,
+ 0xee80,0xee81,0xee82,0xee83,0xee84,0xee85,0xee86,0xee87,
+ 0xee88,0xee89,0xee8a,0xee8b,0xee8c,0xee8d,0xee8e,0xee8f,
+ 0xee90,0xee91,0xee92,0xee93,0xee94,0xee95,0xee96,0xee97,
+ 0xee98,0xee99,0xee9a,0xee9b,0xee9c,0xee9d,0xee9e,0xee9f,
+ 0xeea0,0xeea1,0xeea2,0xeea3,0xeea4,0xeea5,0xeea6,0xeea7,
+ 0xeea8,0xeea9,0xeeaa,0xeeab,0xeeac,0xeead,0xeeae,0xeeaf,
+ 0xeeb0,0xeeb1,0xeeb2,0xeeb3,0xeeb4,0xeeb5,0xeeb6,0xeeb7,
+ 0xeeb8,0xeeb9,0xeeba,0xeebb,0xeebc,0xeebd,0xeebe,0xeebf,
+ 0xeec0,0xeec1,0xeec2,0xeec3,0xeec4,0xeec5,0xeec6,0xeec7,
+ 0xeec8,0xeec9,0xeeca,0xeecb,0xeecc,0xeecd,0xeece,0xeecf,
+ 0xeed0,0xeed1,0xeed2,0xeed3,0xeed4,0xeed5,0xeed6,0xeed7,
+ 0xeed8,0xeed9,0xeeda,0xeedb,0xeedc,0xeedd,0xeede,0xeedf,
+ 0xeee0,0xeee1,0xeee2,0xeee3,0xeee4,0xeee5,0xeee6,0xeee7,
+ 0xeee8,0xeee9,0xeeea,0xeeeb,0xeeec,0xeeed,0xeeee,0xeeef,
+ 0xeef0,0xeef1,0xeef2,0xeef3,0xeef4,0xeef5,0xeef6,0xeef7,
+ 0xeef8,0xeef9,0xeefa,0xeefb,0xeefc,0xeefd,0xeefe,0xeeff,
+ 0xef00,0xef01,0xef02,0xef03,0xef04,0xef05,0xef06,0xef07,
+ 0xef08,0xef09,0xef0a,0xef0b,0xef0c,0xef0d,0xef0e,0xef0f,
+ 0xef10,0xef11,0xef12,0xef13,0xef14,0xef15,0xef16,0xef17,
+ 0xef18,0xef19,0xef1a,0xef1b,0xef1c,0xef1d,0xef1e,0xef1f,
+ 0xef20,0xef21,0xef22,0xef23,0xef24,0xef25,0xef26,0xef27,
+ 0xef28,0xef29,0xef2a,0xef2b,0xef2c,0xef2d,0xef2e,0xef2f,
+ 0xef30,0xef31,0xef32,0xef33,0xef34,0xef35,0xef36,0xef37,
+ 0xef38,0xef39,0xef3a,0xef3b,0xef3c,0xef3d,0xef3e,0xef3f,
+ 0xef40,0xef41,0xef42,0xef43,0xef44,0xef45,0xef46,0xef47,
+ 0xef48,0xef49,0xef4a,0xef4b,0xef4c,0xef4d,0xef4e,0xef4f,
+ 0xef50,0xef51,0xef52,0xef53,0xef54,0xef55,0xef56,0xef57,
+ 0xef58,0xef59,0xef5a,0xef5b,0xef5c,0xef5d,0xef5e,0xef5f,
+ 0xef60,0xef61,0xef62,0xef63,0xef64,0xef65,0xef66,0xef67,
+ 0xef68,0xef69,0xef6a,0xef6b,0xef6c,0xef6d,0xef6e,0xef6f,
+ 0xef70,0xef71,0xef72,0xef73,0xef74,0xef75,0xef76,0xef77,
+ 0xef78,0xef79,0xef7a,0xef7b,0xef7c,0xef7d,0xef7e,0xef7f,
+ 0xef80,0xef81,0xef82,0xef83,0xef84,0xef85,0xef86,0xef87,
+ 0xef88,0xef89,0xef8a,0xef8b,0xef8c,0xef8d,0xef8e,0xef8f,
+ 0xef90,0xef91,0xef92,0xef93,0xef94,0xef95,0xef96,0xef97,
+ 0xef98,0xef99,0xef9a,0xef9b,0xef9c,0xef9d,0xef9e,0xef9f,
+ 0xefa0,0xefa1,0xefa2,0xefa3,0xefa4,0xefa5,0xefa6,0xefa7,
+ 0xefa8,0xefa9,0xefaa,0xefab,0xefac,0xefad,0xefae,0xefaf,
+ 0xefb0,0xefb1,0xefb2,0xefb3,0xefb4,0xefb5,0xefb6,0xefb7,
+ 0xefb8,0xefb9,0xefba,0xefbb,0xefbc,0xefbd,0xefbe,0xefbf,
+ 0xefc0,0xefc1,0xefc2,0xefc3,0xefc4,0xefc5,0xefc6,0xefc7,
+ 0xefc8,0xefc9,0xefca,0xefcb,0xefcc,0xefcd,0xefce,0xefcf,
+ 0xefd0,0xefd1,0xefd2,0xefd3,0xefd4,0xefd5,0xefd6,0xefd7,
+ 0xefd8,0xefd9,0xefda,0xefdb,0xefdc,0xefdd,0xefde,0xefdf,
+ 0xefe0,0xefe1,0xefe2,0xefe3,0xefe4,0xefe5,0xefe6,0xefe7,
+ 0xefe8,0xefe9,0xefea,0xefeb,0xefec,0xefed,0xefee,0xefef,
+ 0xeff0,0xeff1,0xeff2,0xeff3,0xeff4,0xeff5,0xeff6,0xeff7,
+ 0xeff8,0xeff9,0xeffa,0xeffb,0xeffc,0xeffd,0xeffe,0xefff,
+ 0xf000,0xf001,0xf002,0xf003,0xf004,0xf005,0xf006,0xf007,
+ 0xf008,0xf009,0xf00a,0xf00b,0xf00c,0xf00d,0xf00e,0xf00f,
+ 0xf010,0xf011,0xf012,0xf013,0xf014,0xf015,0xf016,0xf017,
+ 0xf018,0xf019,0xf01a,0xf01b,0xf01c,0xf01d,0xf01e,0xf01f,
+ 0xf020,0xf021,0xf022,0xf023,0xf024,0xf025,0xf026,0xf027,
+ 0xf028,0xf029,0xf02a,0xf02b,0xf02c,0xf02d,0xf02e,0xf02f,
+ 0xf030,0xf031,0xf032,0xf033,0xf034,0xf035,0xf036,0xf037,
+ 0xf038,0xf039,0xf03a,0xf03b,0xf03c,0xf03d,0xf03e,0xf03f,
+ 0xf040,0xf041,0xf042,0xf043,0xf044,0xf045,0xf046,0xf047,
+ 0xf048,0xf049,0xf04a,0xf04b,0xf04c,0xf04d,0xf04e,0xf04f,
+ 0xf050,0xf051,0xf052,0xf053,0xf054,0xf055,0xf056,0xf057,
+ 0xf058,0xf059,0xf05a,0xf05b,0xf05c,0xf05d,0xf05e,0xf05f,
+ 0xf060,0xf061,0xf062,0xf063,0xf064,0xf065,0xf066,0xf067,
+ 0xf068,0xf069,0xf06a,0xf06b,0xf06c,0xf06d,0xf06e,0xf06f,
+ 0xf070,0xf071,0xf072,0xf073,0xf074,0xf075,0xf076,0xf077,
+ 0xf078,0xf079,0xf07a,0xf07b,0xf07c,0xf07d,0xf07e,0xf07f,
+ 0xf080,0xf081,0xf082,0xf083,0xf084,0xf085,0xf086,0xf087,
+ 0xf088,0xf089,0xf08a,0xf08b,0xf08c,0xf08d,0xf08e,0xf08f,
+ 0xf090,0xf091,0xf092,0xf093,0xf094,0xf095,0xf096,0xf097,
+ 0xf098,0xf099,0xf09a,0xf09b,0xf09c,0xf09d,0xf09e,0xf09f,
+ 0xf0a0,0xf0a1,0xf0a2,0xf0a3,0xf0a4,0xf0a5,0xf0a6,0xf0a7,
+ 0xf0a8,0xf0a9,0xf0aa,0xf0ab,0xf0ac,0xf0ad,0xf0ae,0xf0af,
+ 0xf0b0,0xf0b1,0xf0b2,0xf0b3,0xf0b4,0xf0b5,0xf0b6,0xf0b7,
+ 0xf0b8,0xf0b9,0xf0ba,0xf0bb,0xf0bc,0xf0bd,0xf0be,0xf0bf,
+ 0xf0c0,0xf0c1,0xf0c2,0xf0c3,0xf0c4,0xf0c5,0xf0c6,0xf0c7,
+ 0xf0c8,0xf0c9,0xf0ca,0xf0cb,0xf0cc,0xf0cd,0xf0ce,0xf0cf,
+ 0xf0d0,0xf0d1,0xf0d2,0xf0d3,0xf0d4,0xf0d5,0xf0d6,0xf0d7,
+ 0xf0d8,0xf0d9,0xf0da,0xf0db,0xf0dc,0xf0dd,0xf0de,0xf0df,
+ 0xf0e0,0xf0e1,0xf0e2,0xf0e3,0xf0e4,0xf0e5,0xf0e6,0xf0e7,
+ 0xf0e8,0xf0e9,0xf0ea,0xf0eb,0xf0ec,0xf0ed,0xf0ee,0xf0ef,
+ 0xf0f0,0xf0f1,0xf0f2,0xf0f3,0xf0f4,0xf0f5,0xf0f6,0xf0f7,
+ 0xf0f8,0xf0f9,0xf0fa,0xf0fb,0xf0fc,0xf0fd,0xf0fe,0xf0ff,
+ 0xf100,0xf101,0xf102,0xf103,0xf104,0xf105,0xf106,0xf107,
+ 0xf108,0xf109,0xf10a,0xf10b,0xf10c,0xf10d,0xf10e,0xf10f,
+ 0xf110,0xf111,0xf112,0xf113,0xf114,0xf115,0xf116,0xf117,
+ 0xf118,0xf119,0xf11a,0xf11b,0xf11c,0xf11d,0xf11e,0xf11f,
+ 0xf120,0xf121,0xf122,0xf123,0xf124,0xf125,0xf126,0xf127,
+ 0xf128,0xf129,0xf12a,0xf12b,0xf12c,0xf12d,0xf12e,0xf12f,
+ 0xf130,0xf131,0xf132,0xf133,0xf134,0xf135,0xf136,0xf137,
+ 0xf138,0xf139,0xf13a,0xf13b,0xf13c,0xf13d,0xf13e,0xf13f,
+ 0xf140,0xf141,0xf142,0xf143,0xf144,0xf145,0xf146,0xf147,
+ 0xf148,0xf149,0xf14a,0xf14b,0xf14c,0xf14d,0xf14e,0xf14f,
+ 0xf150,0xf151,0xf152,0xf153,0xf154,0xf155,0xf156,0xf157,
+ 0xf158,0xf159,0xf15a,0xf15b,0xf15c,0xf15d,0xf15e,0xf15f,
+ 0xf160,0xf161,0xf162,0xf163,0xf164,0xf165,0xf166,0xf167,
+ 0xf168,0xf169,0xf16a,0xf16b,0xf16c,0xf16d,0xf16e,0xf16f,
+ 0xf170,0xf171,0xf172,0xf173,0xf174,0xf175,0xf176,0xf177,
+ 0xf178,0xf179,0xf17a,0xf17b,0xf17c,0xf17d,0xf17e,0xf17f,
+ 0xf180,0xf181,0xf182,0xf183,0xf184,0xf185,0xf186,0xf187,
+ 0xf188,0xf189,0xf18a,0xf18b,0xf18c,0xf18d,0xf18e,0xf18f,
+ 0xf190,0xf191,0xf192,0xf193,0xf194,0xf195,0xf196,0xf197,
+ 0xf198,0xf199,0xf19a,0xf19b,0xf19c,0xf19d,0xf19e,0xf19f,
+ 0xf1a0,0xf1a1,0xf1a2,0xf1a3,0xf1a4,0xf1a5,0xf1a6,0xf1a7,
+ 0xf1a8,0xf1a9,0xf1aa,0xf1ab,0xf1ac,0xf1ad,0xf1ae,0xf1af,
+ 0xf1b0,0xf1b1,0xf1b2,0xf1b3,0xf1b4,0xf1b5,0xf1b6,0xf1b7,
+ 0xf1b8,0xf1b9,0xf1ba,0xf1bb,0xf1bc,0xf1bd,0xf1be,0xf1bf,
+ 0xf1c0,0xf1c1,0xf1c2,0xf1c3,0xf1c4,0xf1c5,0xf1c6,0xf1c7,
+ 0xf1c8,0xf1c9,0xf1ca,0xf1cb,0xf1cc,0xf1cd,0xf1ce,0xf1cf,
+ 0xf1d0,0xf1d1,0xf1d2,0xf1d3,0xf1d4,0xf1d5,0xf1d6,0xf1d7,
+ 0xf1d8,0xf1d9,0xf1da,0xf1db,0xf1dc,0xf1dd,0xf1de,0xf1df,
+ 0xf1e0,0xf1e1,0xf1e2,0xf1e3,0xf1e4,0xf1e5,0xf1e6,0xf1e7,
+ 0xf1e8,0xf1e9,0xf1ea,0xf1eb,0xf1ec,0xf1ed,0xf1ee,0xf1ef,
+ 0xf1f0,0xf1f1,0xf1f2,0xf1f3,0xf1f4,0xf1f5,0xf1f6,0xf1f7,
+ 0xf1f8,0xf1f9,0xf1fa,0xf1fb,0xf1fc,0xf1fd,0xf1fe,0xf1ff,
+ 0xf200,0xf201,0xf202,0xf203,0xf204,0xf205,0xf206,0xf207,
+ 0xf208,0xf209,0xf20a,0xf20b,0xf20c,0xf20d,0xf20e,0xf20f,
+ 0xf210,0xf211,0xf212,0xf213,0xf214,0xf215,0xf216,0xf217,
+ 0xf218,0xf219,0xf21a,0xf21b,0xf21c,0xf21d,0xf21e,0xf21f,
+ 0xf220,0xf221,0xf222,0xf223,0xf224,0xf225,0xf226,0xf227,
+ 0xf228,0xf229,0xf22a,0xf22b,0xf22c,0xf22d,0xf22e,0xf22f,
+ 0xf230,0xf231,0xf232,0xf233,0xf234,0xf235,0xf236,0xf237,
+ 0xf238,0xf239,0xf23a,0xf23b,0xf23c,0xf23d,0xf23e,0xf23f,
+ 0xf240,0xf241,0xf242,0xf243,0xf244,0xf245,0xf246,0xf247,
+ 0xf248,0xf249,0xf24a,0xf24b,0xf24c,0xf24d,0xf24e,0xf24f,
+ 0xf250,0xf251,0xf252,0xf253,0xf254,0xf255,0xf256,0xf257,
+ 0xf258,0xf259,0xf25a,0xf25b,0xf25c,0xf25d,0xf25e,0xf25f,
+ 0xf260,0xf261,0xf262,0xf263,0xf264,0xf265,0xf266,0xf267,
+ 0xf268,0xf269,0xf26a,0xf26b,0xf26c,0xf26d,0xf26e,0xf26f,
+ 0xf270,0xf271,0xf272,0xf273,0xf274,0xf275,0xf276,0xf277,
+ 0xf278,0xf279,0xf27a,0xf27b,0xf27c,0xf27d,0xf27e,0xf27f,
+ 0xf280,0xf281,0xf282,0xf283,0xf284,0xf285,0xf286,0xf287,
+ 0xf288,0xf289,0xf28a,0xf28b,0xf28c,0xf28d,0xf28e,0xf28f,
+ 0xf290,0xf291,0xf292,0xf293,0xf294,0xf295,0xf296,0xf297,
+ 0xf298,0xf299,0xf29a,0xf29b,0xf29c,0xf29d,0xf29e,0xf29f,
+ 0xf2a0,0xf2a1,0xf2a2,0xf2a3,0xf2a4,0xf2a5,0xf2a6,0xf2a7,
+ 0xf2a8,0xf2a9,0xf2aa,0xf2ab,0xf2ac,0xf2ad,0xf2ae,0xf2af,
+ 0xf2b0,0xf2b1,0xf2b2,0xf2b3,0xf2b4,0xf2b5,0xf2b6,0xf2b7,
+ 0xf2b8,0xf2b9,0xf2ba,0xf2bb,0xf2bc,0xf2bd,0xf2be,0xf2bf,
+ 0xf2c0,0xf2c1,0xf2c2,0xf2c3,0xf2c4,0xf2c5,0xf2c6,0xf2c7,
+ 0xf2c8,0xf2c9,0xf2ca,0xf2cb,0xf2cc,0xf2cd,0xf2ce,0xf2cf,
+ 0xf2d0,0xf2d1,0xf2d2,0xf2d3,0xf2d4,0xf2d5,0xf2d6,0xf2d7,
+ 0xf2d8,0xf2d9,0xf2da,0xf2db,0xf2dc,0xf2dd,0xf2de,0xf2df,
+ 0xf2e0,0xf2e1,0xf2e2,0xf2e3,0xf2e4,0xf2e5,0xf2e6,0xf2e7,
+ 0xf2e8,0xf2e9,0xf2ea,0xf2eb,0xf2ec,0xf2ed,0xf2ee,0xf2ef,
+ 0xf2f0,0xf2f1,0xf2f2,0xf2f3,0xf2f4,0xf2f5,0xf2f6,0xf2f7,
+ 0xf2f8,0xf2f9,0xf2fa,0xf2fb,0xf2fc,0xf2fd,0xf2fe,0xf2ff,
+ 0xf300,0xf301,0xf302,0xf303,0xf304,0xf305,0xf306,0xf307,
+ 0xf308,0xf309,0xf30a,0xf30b,0xf30c,0xf30d,0xf30e,0xf30f,
+ 0xf310,0xf311,0xf312,0xf313,0xf314,0xf315,0xf316,0xf317,
+ 0xf318,0xf319,0xf31a,0xf31b,0xf31c,0xf31d,0xf31e,0xf31f,
+ 0xf320,0xf321,0xf322,0xf323,0xf324,0xf325,0xf326,0xf327,
+ 0xf328,0xf329,0xf32a,0xf32b,0xf32c,0xf32d,0xf32e,0xf32f,
+ 0xf330,0xf331,0xf332,0xf333,0xf334,0xf335,0xf336,0xf337,
+ 0xf338,0xf339,0xf33a,0xf33b,0xf33c,0xf33d,0xf33e,0xf33f,
+ 0xf340,0xf341,0xf342,0xf343,0xf344,0xf345,0xf346,0xf347,
+ 0xf348,0xf349,0xf34a,0xf34b,0xf34c,0xf34d,0xf34e,0xf34f,
+ 0xf350,0xf351,0xf352,0xf353,0xf354,0xf355,0xf356,0xf357,
+ 0xf358,0xf359,0xf35a,0xf35b,0xf35c,0xf35d,0xf35e,0xf35f,
+ 0xf360,0xf361,0xf362,0xf363,0xf364,0xf365,0xf366,0xf367,
+ 0xf368,0xf369,0xf36a,0xf36b,0xf36c,0xf36d,0xf36e,0xf36f,
+ 0xf370,0xf371,0xf372,0xf373,0xf374,0xf375,0xf376,0xf377,
+ 0xf378,0xf379,0xf37a,0xf37b,0xf37c,0xf37d,0xf37e,0xf37f,
+ 0xf380,0xf381,0xf382,0xf383,0xf384,0xf385,0xf386,0xf387,
+ 0xf388,0xf389,0xf38a,0xf38b,0xf38c,0xf38d,0xf38e,0xf38f,
+ 0xf390,0xf391,0xf392,0xf393,0xf394,0xf395,0xf396,0xf397,
+ 0xf398,0xf399,0xf39a,0xf39b,0xf39c,0xf39d,0xf39e,0xf39f,
+ 0xf3a0,0xf3a1,0xf3a2,0xf3a3,0xf3a4,0xf3a5,0xf3a6,0xf3a7,
+ 0xf3a8,0xf3a9,0xf3aa,0xf3ab,0xf3ac,0xf3ad,0xf3ae,0xf3af,
+ 0xf3b0,0xf3b1,0xf3b2,0xf3b3,0xf3b4,0xf3b5,0xf3b6,0xf3b7,
+ 0xf3b8,0xf3b9,0xf3ba,0xf3bb,0xf3bc,0xf3bd,0xf3be,0xf3bf,
+ 0xf3c0,0xf3c1,0xf3c2,0xf3c3,0xf3c4,0xf3c5,0xf3c6,0xf3c7,
+ 0xf3c8,0xf3c9,0xf3ca,0xf3cb,0xf3cc,0xf3cd,0xf3ce,0xf3cf,
+ 0xf3d0,0xf3d1,0xf3d2,0xf3d3,0xf3d4,0xf3d5,0xf3d6,0xf3d7,
+ 0xf3d8,0xf3d9,0xf3da,0xf3db,0xf3dc,0xf3dd,0xf3de,0xf3df,
+ 0xf3e0,0xf3e1,0xf3e2,0xf3e3,0xf3e4,0xf3e5,0xf3e6,0xf3e7,
+ 0xf3e8,0xf3e9,0xf3ea,0xf3eb,0xf3ec,0xf3ed,0xf3ee,0xf3ef,
+ 0xf3f0,0xf3f1,0xf3f2,0xf3f3,0xf3f4,0xf3f5,0xf3f6,0xf3f7,
+ 0xf3f8,0xf3f9,0xf3fa,0xf3fb,0xf3fc,0xf3fd,0xf3fe,0xf3ff,
+ 0xf400,0xf401,0xf402,0xf403,0xf404,0xf405,0xf406,0xf407,
+ 0xf408,0xf409,0xf40a,0xf40b,0xf40c,0xf40d,0xf40e,0xf40f,
+ 0xf410,0xf411,0xf412,0xf413,0xf414,0xf415,0xf416,0xf417,
+ 0xf418,0xf419,0xf41a,0xf41b,0xf41c,0xf41d,0xf41e,0xf41f,
+ 0xf420,0xf421,0xf422,0xf423,0xf424,0xf425,0xf426,0xf427,
+ 0xf428,0xf429,0xf42a,0xf42b,0xf42c,0xf42d,0xf42e,0xf42f,
+ 0xf430,0xf431,0xf432,0xf433,0xf434,0xf435,0xf436,0xf437,
+ 0xf438,0xf439,0xf43a,0xf43b,0xf43c,0xf43d,0xf43e,0xf43f,
+ 0xf440,0xf441,0xf442,0xf443,0xf444,0xf445,0xf446,0xf447,
+ 0xf448,0xf449,0xf44a,0xf44b,0xf44c,0xf44d,0xf44e,0xf44f,
+ 0xf450,0xf451,0xf452,0xf453,0xf454,0xf455,0xf456,0xf457,
+ 0xf458,0xf459,0xf45a,0xf45b,0xf45c,0xf45d,0xf45e,0xf45f,
+ 0xf460,0xf461,0xf462,0xf463,0xf464,0xf465,0xf466,0xf467,
+ 0xf468,0xf469,0xf46a,0xf46b,0xf46c,0xf46d,0xf46e,0xf46f,
+ 0xf470,0xf471,0xf472,0xf473,0xf474,0xf475,0xf476,0xf477,
+ 0xf478,0xf479,0xf47a,0xf47b,0xf47c,0xf47d,0xf47e,0xf47f,
+ 0xf480,0xf481,0xf482,0xf483,0xf484,0xf485,0xf486,0xf487,
+ 0xf488,0xf489,0xf48a,0xf48b,0xf48c,0xf48d,0xf48e,0xf48f,
+ 0xf490,0xf491,0xf492,0xf493,0xf494,0xf495,0xf496,0xf497,
+ 0xf498,0xf499,0xf49a,0xf49b,0xf49c,0xf49d,0xf49e,0xf49f,
+ 0xf4a0,0xf4a1,0xf4a2,0xf4a3,0xf4a4,0xf4a5,0xf4a6,0xf4a7,
+ 0xf4a8,0xf4a9,0xf4aa,0xf4ab,0xf4ac,0xf4ad,0xf4ae,0xf4af,
+ 0xf4b0,0xf4b1,0xf4b2,0xf4b3,0xf4b4,0xf4b5,0xf4b6,0xf4b7,
+ 0xf4b8,0xf4b9,0xf4ba,0xf4bb,0xf4bc,0xf4bd,0xf4be,0xf4bf,
+ 0xf4c0,0xf4c1,0xf4c2,0xf4c3,0xf4c4,0xf4c5,0xf4c6,0xf4c7,
+ 0xf4c8,0xf4c9,0xf4ca,0xf4cb,0xf4cc,0xf4cd,0xf4ce,0xf4cf,
+ 0xf4d0,0xf4d1,0xf4d2,0xf4d3,0xf4d4,0xf4d5,0xf4d6,0xf4d7,
+ 0xf4d8,0xf4d9,0xf4da,0xf4db,0xf4dc,0xf4dd,0xf4de,0xf4df,
+ 0xf4e0,0xf4e1,0xf4e2,0xf4e3,0xf4e4,0xf4e5,0xf4e6,0xf4e7,
+ 0xf4e8,0xf4e9,0xf4ea,0xf4eb,0xf4ec,0xf4ed,0xf4ee,0xf4ef,
+ 0xf4f0,0xf4f1,0xf4f2,0xf4f3,0xf4f4,0xf4f5,0xf4f6,0xf4f7,
+ 0xf4f8,0xf4f9,0xf4fa,0xf4fb,0xf4fc,0xf4fd,0xf4fe,0xf4ff,
+ 0xf500,0xf501,0xf502,0xf503,0xf504,0xf505,0xf506,0xf507,
+ 0xf508,0xf509,0xf50a,0xf50b,0xf50c,0xf50d,0xf50e,0xf50f,
+ 0xf510,0xf511,0xf512,0xf513,0xf514,0xf515,0xf516,0xf517,
+ 0xf518,0xf519,0xf51a,0xf51b,0xf51c,0xf51d,0xf51e,0xf51f,
+ 0xf520,0xf521,0xf522,0xf523,0xf524,0xf525,0xf526,0xf527,
+ 0xf528,0xf529,0xf52a,0xf52b,0xf52c,0xf52d,0xf52e,0xf52f,
+ 0xf530,0xf531,0xf532,0xf533,0xf534,0xf535,0xf536,0xf537,
+ 0xf538,0xf539,0xf53a,0xf53b,0xf53c,0xf53d,0xf53e,0xf53f,
+ 0xf540,0xf541,0xf542,0xf543,0xf544,0xf545,0xf546,0xf547,
+ 0xf548,0xf549,0xf54a,0xf54b,0xf54c,0xf54d,0xf54e,0xf54f,
+ 0xf550,0xf551,0xf552,0xf553,0xf554,0xf555,0xf556,0xf557,
+ 0xf558,0xf559,0xf55a,0xf55b,0xf55c,0xf55d,0xf55e,0xf55f,
+ 0xf560,0xf561,0xf562,0xf563,0xf564,0xf565,0xf566,0xf567,
+ 0xf568,0xf569,0xf56a,0xf56b,0xf56c,0xf56d,0xf56e,0xf56f,
+ 0xf570,0xf571,0xf572,0xf573,0xf574,0xf575,0xf576,0xf577,
+ 0xf578,0xf579,0xf57a,0xf57b,0xf57c,0xf57d,0xf57e,0xf57f,
+ 0xf580,0xf581,0xf582,0xf583,0xf584,0xf585,0xf586,0xf587,
+ 0xf588,0xf589,0xf58a,0xf58b,0xf58c,0xf58d,0xf58e,0xf58f,
+ 0xf590,0xf591,0xf592,0xf593,0xf594,0xf595,0xf596,0xf597,
+ 0xf598,0xf599,0xf59a,0xf59b,0xf59c,0xf59d,0xf59e,0xf59f,
+ 0xf5a0,0xf5a1,0xf5a2,0xf5a3,0xf5a4,0xf5a5,0xf5a6,0xf5a7,
+ 0xf5a8,0xf5a9,0xf5aa,0xf5ab,0xf5ac,0xf5ad,0xf5ae,0xf5af,
+ 0xf5b0,0xf5b1,0xf5b2,0xf5b3,0xf5b4,0xf5b5,0xf5b6,0xf5b7,
+ 0xf5b8,0xf5b9,0xf5ba,0xf5bb,0xf5bc,0xf5bd,0xf5be,0xf5bf,
+ 0xf5c0,0xf5c1,0xf5c2,0xf5c3,0xf5c4,0xf5c5,0xf5c6,0xf5c7,
+ 0xf5c8,0xf5c9,0xf5ca,0xf5cb,0xf5cc,0xf5cd,0xf5ce,0xf5cf,
+ 0xf5d0,0xf5d1,0xf5d2,0xf5d3,0xf5d4,0xf5d5,0xf5d6,0xf5d7,
+ 0xf5d8,0xf5d9,0xf5da,0xf5db,0xf5dc,0xf5dd,0xf5de,0xf5df,
+ 0xf5e0,0xf5e1,0xf5e2,0xf5e3,0xf5e4,0xf5e5,0xf5e6,0xf5e7,
+ 0xf5e8,0xf5e9,0xf5ea,0xf5eb,0xf5ec,0xf5ed,0xf5ee,0xf5ef,
+ 0xf5f0,0xf5f1,0xf5f2,0xf5f3,0xf5f4,0xf5f5,0xf5f6,0xf5f7,
+ 0xf5f8,0xf5f9,0xf5fa,0xf5fb,0xf5fc,0xf5fd,0xf5fe,0xf5ff,
+ 0xf600,0xf601,0xf602,0xf603,0xf604,0xf605,0xf606,0xf607,
+ 0xf608,0xf609,0xf60a,0xf60b,0xf60c,0xf60d,0xf60e,0xf60f,
+ 0xf610,0xf611,0xf612,0xf613,0xf614,0xf615,0xf616,0xf617,
+ 0xf618,0xf619,0xf61a,0xf61b,0xf61c,0xf61d,0xf61e,0xf61f,
+ 0xf620,0xf621,0xf622,0xf623,0xf624,0xf625,0xf626,0xf627,
+ 0xf628,0xf629,0xf62a,0xf62b,0xf62c,0xf62d,0xf62e,0xf62f,
+ 0xf630,0xf631,0xf632,0xf633,0xf634,0xf635,0xf636,0xf637,
+ 0xf638,0xf639,0xf63a,0xf63b,0xf63c,0xf63d,0xf63e,0xf63f,
+ 0xf640,0xf641,0xf642,0xf643,0xf644,0xf645,0xf646,0xf647,
+ 0xf648,0xf649,0xf64a,0xf64b,0xf64c,0xf64d,0xf64e,0xf64f,
+ 0xf650,0xf651,0xf652,0xf653,0xf654,0xf655,0xf656,0xf657,
+ 0xf658,0xf659,0xf65a,0xf65b,0xf65c,0xf65d,0xf65e,0xf65f,
+ 0xf660,0xf661,0xf662,0xf663,0xf664,0xf665,0xf666,0xf667,
+ 0xf668,0xf669,0xf66a,0xf66b,0xf66c,0xf66d,0xf66e,0xf66f,
+ 0xf670,0xf671,0xf672,0xf673,0xf674,0xf675,0xf676,0xf677,
+ 0xf678,0xf679,0xf67a,0xf67b,0xf67c,0xf67d,0xf67e,0xf67f,
+ 0xf680,0xf681,0xf682,0xf683,0xf684,0xf685,0xf686,0xf687,
+ 0xf688,0xf689,0xf68a,0xf68b,0xf68c,0xf68d,0xf68e,0xf68f,
+ 0xf690,0xf691,0xf692,0xf693,0xf694,0xf695,0xf696,0xf697,
+ 0xf698,0xf699,0xf69a,0xf69b,0xf69c,0xf69d,0xf69e,0xf69f,
+ 0xf6a0,0xf6a1,0xf6a2,0xf6a3,0xf6a4,0xf6a5,0xf6a6,0xf6a7,
+ 0xf6a8,0xf6a9,0xf6aa,0xf6ab,0xf6ac,0xf6ad,0xf6ae,0xf6af,
+ 0xf6b0,0xf6b1,0xf6b2,0xf6b3,0xf6b4,0xf6b5,0xf6b6,0xf6b7,
+ 0xf6b8,0xf6b9,0xf6ba,0xf6bb,0xf6bc,0xf6bd,0xf6be,0xf6bf,
+ 0xf6c0,0xf6c1,0xf6c2,0xf6c3,0xf6c4,0xf6c5,0xf6c6,0xf6c7,
+ 0xf6c8,0xf6c9,0xf6ca,0xf6cb,0xf6cc,0xf6cd,0xf6ce,0xf6cf,
+ 0xf6d0,0xf6d1,0xf6d2,0xf6d3,0xf6d4,0xf6d5,0xf6d6,0xf6d7,
+ 0xf6d8,0xf6d9,0xf6da,0xf6db,0xf6dc,0xf6dd,0xf6de,0xf6df,
+ 0xf6e0,0xf6e1,0xf6e2,0xf6e3,0xf6e4,0xf6e5,0xf6e6,0xf6e7,
+ 0xf6e8,0xf6e9,0xf6ea,0xf6eb,0xf6ec,0xf6ed,0xf6ee,0xf6ef,
+ 0xf6f0,0xf6f1,0xf6f2,0xf6f3,0xf6f4,0xf6f5,0xf6f6,0xf6f7,
+ 0xf6f8,0xf6f9,0xf6fa,0xf6fb,0xf6fc,0xf6fd,0xf6fe,0xf6ff,
+ 0xf700,0xf701,0xf702,0xf703,0xf704,0xf705,0xf706,0xf707,
+ 0xf708,0xf709,0xf70a,0xf70b,0xf70c,0xf70d,0xf70e,0xf70f,
+ 0xf710,0xf711,0xf712,0xf713,0xf714,0xf715,0xf716,0xf717,
+ 0xf718,0xf719,0xf71a,0xf71b,0xf71c,0xf71d,0xf71e,0xf71f,
+ 0xf720,0xf721,0xf722,0xf723,0xf724,0xf725,0xf726,0xf727,
+ 0xf728,0xf729,0xf72a,0xf72b,0xf72c,0xf72d,0xf72e,0xf72f,
+ 0xf730,0xf731,0xf732,0xf733,0xf734,0xf735,0xf736,0xf737,
+ 0xf738,0xf739,0xf73a,0xf73b,0xf73c,0xf73d,0xf73e,0xf73f,
+ 0xf740,0xf741,0xf742,0xf743,0xf744,0xf745,0xf746,0xf747,
+ 0xf748,0xf749,0xf74a,0xf74b,0xf74c,0xf74d,0xf74e,0xf74f,
+ 0xf750,0xf751,0xf752,0xf753,0xf754,0xf755,0xf756,0xf757,
+ 0xf758,0xf759,0xf75a,0xf75b,0xf75c,0xf75d,0xf75e,0xf75f,
+ 0xf760,0xf761,0xf762,0xf763,0xf764,0xf765,0xf766,0xf767,
+ 0xf768,0xf769,0xf76a,0xf76b,0xf76c,0xf76d,0xf76e,0xf76f,
+ 0xf770,0xf771,0xf772,0xf773,0xf774,0xf775,0xf776,0xf777,
+ 0xf778,0xf779,0xf77a,0xf77b,0xf77c,0xf77d,0xf77e,0xf77f,
+ 0xf780,0xf781,0xf782,0xf783,0xf784,0xf785,0xf786,0xf787,
+ 0xf788,0xf789,0xf78a,0xf78b,0xf78c,0xf78d,0xf78e,0xf78f,
+ 0xf790,0xf791,0xf792,0xf793,0xf794,0xf795,0xf796,0xf797,
+ 0xf798,0xf799,0xf79a,0xf79b,0xf79c,0xf79d,0xf79e,0xf79f,
+ 0xf7a0,0xf7a1,0xf7a2,0xf7a3,0xf7a4,0xf7a5,0xf7a6,0xf7a7,
+ 0xf7a8,0xf7a9,0xf7aa,0xf7ab,0xf7ac,0xf7ad,0xf7ae,0xf7af,
+ 0xf7b0,0xf7b1,0xf7b2,0xf7b3,0xf7b4,0xf7b5,0xf7b6,0xf7b7,
+ 0xf7b8,0xf7b9,0xf7ba,0xf7bb,0xf7bc,0xf7bd,0xf7be,0xf7bf,
+ 0xf7c0,0xf7c1,0xf7c2,0xf7c3,0xf7c4,0xf7c5,0xf7c6,0xf7c7,
+ 0xf7c8,0xf7c9,0xf7ca,0xf7cb,0xf7cc,0xf7cd,0xf7ce,0xf7cf,
+ 0xf7d0,0xf7d1,0xf7d2,0xf7d3,0xf7d4,0xf7d5,0xf7d6,0xf7d7,
+ 0xf7d8,0xf7d9,0xf7da,0xf7db,0xf7dc,0xf7dd,0xf7de,0xf7df,
+ 0xf7e0,0xf7e1,0xf7e2,0xf7e3,0xf7e4,0xf7e5,0xf7e6,0xf7e7,
+ 0xf7e8,0xf7e9,0xf7ea,0xf7eb,0xf7ec,0xf7ed,0xf7ee,0xf7ef,
+ 0xf7f0,0xf7f1,0xf7f2,0xf7f3,0xf7f4,0xf7f5,0xf7f6,0xf7f7,
+ 0xf7f8,0xf7f9,0xf7fa,0xf7fb,0xf7fc,0xf7fd,0xf7fe,0xf7ff,
+ 0xf800,0xf801,0xf802,0xf803,0xf804,0xf805,0xf806,0xf807,
+ 0xf808,0xf809,0xf80a,0xf80b,0xf80c,0xf80d,0xf80e,0xf80f,
+ 0xf810,0xf811,0xf812,0xf813,0xf814,0xf815,0xf816,0xf817,
+ 0xf818,0xf819,0xf81a,0xf81b,0xf81c,0xf81d,0xf81e,0xf81f,
+ 0xf820,0xf821,0xf822,0xf823,0xf824,0xf825,0xf826,0xf827,
+ 0xf828,0xf829,0xf82a,0xf82b,0xf82c,0xf82d,0xf82e,0xf82f,
+ 0xf830,0xf831,0xf832,0xf833,0xf834,0xf835,0xf836,0xf837,
+ 0xf838,0xf839,0xf83a,0xf83b,0xf83c,0xf83d,0xf83e,0xf83f,
+ 0xf840,0xf841,0xf842,0xf843,0xf844,0xf845,0xf846,0xf847,
+ 0xf848,0xf849,0xf84a,0xf84b,0xf84c,0xf84d,0xf84e,0xf84f,
+ 0xf850,0xf851,0xf852,0xf853,0xf854,0xf855,0xf856,0xf857,
+ 0xf858,0xf859,0xf85a,0xf85b,0xf85c,0xf85d,0xf85e,0xf85f,
+ 0xf860,0xf861,0xf862,0xf863,0xf864,0xf865,0xf866,0xf867,
+ 0xf868,0xf869,0xf86a,0xf86b,0xf86c,0xf86d,0xf86e,0xf86f,
+ 0xf870,0xf871,0xf872,0xf873,0xf874,0xf875,0xf876,0xf877,
+ 0xf878,0xf879,0xf87a,0xf87b,0xf87c,0xf87d,0xf87e,0xf87f,
+ 0xf880,0xf881,0xf882,0xf883,0xf884,0xf885,0xf886,0xf887,
+ 0xf888,0xf889,0xf88a,0xf88b,0xf88c,0xf88d,0xf88e,0xf88f,
+ 0xf890,0xf891,0xf892,0xf893,0xf894,0xf895,0xf896,0xf897,
+ 0xf898,0xf899,0xf89a,0xf89b,0xf89c,0xf89d,0xf89e,0xf89f,
+ 0xf8a0,0xf8a1,0xf8a2,0xf8a3,0xf8a4,0xf8a5,0xf8a6,0xf8a7,
+ 0xf8a8,0xf8a9,0xf8aa,0xf8ab,0xf8ac,0xf8ad,0xf8ae,0xf8af,
+ 0xf8b0,0xf8b1,0xf8b2,0xf8b3,0xf8b4,0xf8b5,0xf8b6,0xf8b7,
+ 0xf8b8,0xf8b9,0xf8ba,0xf8bb,0xf8bc,0xf8bd,0xf8be,0xf8bf,
+ 0xf8c0,0xf8c1,0xf8c2,0xf8c3,0xf8c4,0xf8c5,0xf8c6,0xf8c7,
+ 0xf8c8,0xf8c9,0xf8ca,0xf8cb,0xf8cc,0xf8cd,0xf8ce,0xf8cf,
+ 0xf8d0,0xf8d1,0xf8d2,0xf8d3,0xf8d4,0xf8d5,0xf8d6,0xf8d7,
+ 0xf8d8,0xf8d9,0xf8da,0xf8db,0xf8dc,0xf8dd,0xf8de,0xf8df,
+ 0xf8e0,0xf8e1,0xf8e2,0xf8e3,0xf8e4,0xf8e5,0xf8e6,0xf8e7,
+ 0xf8e8,0xf8e9,0xf8ea,0xf8eb,0xf8ec,0xf8ed,0xf8ee,0xf8ef,
+ 0xf8f0,0xf8f1,0xf8f2,0xf8f3,0xf8f4,0xf8f5,0xf8f6,0xf8f7,
+ 0xf8f8,0xf8f9,0xf8fa,0xf8fb,0xf8fc,0xf8fd,0xf8fe,0xf8ff,
+ 0xf900,0xf901,0xf902,0xf903,0xf904,0xf905,0xf906,0xf907,
+ 0xf908,0xf909,0xf90a,0xf90b,0xf90c,0xf90d,0xf90e,0xf90f,
+ 0xf910,0xf911,0xf912,0xf913,0xf914,0xf915,0xf916,0xf917,
+ 0xf918,0xf919,0xf91a,0xf91b,0xf91c,0xf91d,0xf91e,0xf91f,
+ 0xf920,0xf921,0xf922,0xf923,0xf924,0xf925,0xf926,0xf927,
+ 0xf928,0xf929,0xf92a,0xf92b,0xf92c,0xf92d,0xf92e,0xf92f,
+ 0xf930,0xf931,0xf932,0xf933,0xf934,0xf935,0xf936,0xf937,
+ 0xf938,0xf939,0xf93a,0xf93b,0xf93c,0xf93d,0xf93e,0xf93f,
+ 0xf940,0xf941,0xf942,0xf943,0xf944,0xf945,0xf946,0xf947,
+ 0xf948,0xf949,0xf94a,0xf94b,0xf94c,0xf94d,0xf94e,0xf94f,
+ 0xf950,0xf951,0xf952,0xf953,0xf954,0xf955,0xf956,0xf957,
+ 0xf958,0xf959,0xf95a,0xf95b,0xf95c,0xf95d,0xf95e,0xf95f,
+ 0xf960,0xf961,0xf962,0xf963,0xf964,0xf965,0xf966,0xf967,
+ 0xf968,0xf969,0xf96a,0xf96b,0xf96c,0xf96d,0xf96e,0xf96f,
+ 0xf970,0xf971,0xf972,0xf973,0xf974,0xf975,0xf976,0xf977,
+ 0xf978,0xf979,0xf97a,0xf97b,0xf97c,0xf97d,0xf97e,0xf97f,
+ 0xf980,0xf981,0xf982,0xf983,0xf984,0xf985,0xf986,0xf987,
+ 0xf988,0xf989,0xf98a,0xf98b,0xf98c,0xf98d,0xf98e,0xf98f,
+ 0xf990,0xf991,0xf992,0xf993,0xf994,0xf995,0xf996,0xf997,
+ 0xf998,0xf999,0xf99a,0xf99b,0xf99c,0xf99d,0xf99e,0xf99f,
+ 0xf9a0,0xf9a1,0xf9a2,0xf9a3,0xf9a4,0xf9a5,0xf9a6,0xf9a7,
+ 0xf9a8,0xf9a9,0xf9aa,0xf9ab,0xf9ac,0xf9ad,0xf9ae,0xf9af,
+ 0xf9b0,0xf9b1,0xf9b2,0xf9b3,0xf9b4,0xf9b5,0xf9b6,0xf9b7,
+ 0xf9b8,0xf9b9,0xf9ba,0xf9bb,0xf9bc,0xf9bd,0xf9be,0xf9bf,
+ 0xf9c0,0xf9c1,0xf9c2,0xf9c3,0xf9c4,0xf9c5,0xf9c6,0xf9c7,
+ 0xf9c8,0xf9c9,0xf9ca,0xf9cb,0xf9cc,0xf9cd,0xf9ce,0xf9cf,
+ 0xf9d0,0xf9d1,0xf9d2,0xf9d3,0xf9d4,0xf9d5,0xf9d6,0xf9d7,
+ 0xf9d8,0xf9d9,0xf9da,0xf9db,0xf9dc,0xf9dd,0xf9de,0xf9df,
+ 0xf9e0,0xf9e1,0xf9e2,0xf9e3,0xf9e4,0xf9e5,0xf9e6,0xf9e7,
+ 0xf9e8,0xf9e9,0xf9ea,0xf9eb,0xf9ec,0xf9ed,0xf9ee,0xf9ef,
+ 0xf9f0,0xf9f1,0xf9f2,0xf9f3,0xf9f4,0xf9f5,0xf9f6,0xf9f7,
+ 0xf9f8,0xf9f9,0xf9fa,0xf9fb,0xf9fc,0xf9fd,0xf9fe,0xf9ff,
+ 0xfa00,0xfa01,0xfa02,0xfa03,0xfa04,0xfa05,0xfa06,0xfa07,
+ 0xfa08,0xfa09,0xfa0a,0xfa0b,0xfa0c,0xfa0d,0xfa0e,0xfa0f,
+ 0xfa10,0xfa11,0xfa12,0xfa13,0xfa14,0xfa15,0xfa16,0xfa17,
+ 0xfa18,0xfa19,0xfa1a,0xfa1b,0xfa1c,0xfa1d,0xfa1e,0xfa1f,
+ 0xfa20,0xfa21,0xfa22,0xfa23,0xfa24,0xfa25,0xfa26,0xfa27,
+ 0xfa28,0xfa29,0xfa2a,0xfa2b,0xfa2c,0xfa2d,0xfa2e,0xfa2f,
+ 0xfa30,0xfa31,0xfa32,0xfa33,0xfa34,0xfa35,0xfa36,0xfa37,
+ 0xfa38,0xfa39,0xfa3a,0xfa3b,0xfa3c,0xfa3d,0xfa3e,0xfa3f,
+ 0xfa40,0xfa41,0xfa42,0xfa43,0xfa44,0xfa45,0xfa46,0xfa47,
+ 0xfa48,0xfa49,0xfa4a,0xfa4b,0xfa4c,0xfa4d,0xfa4e,0xfa4f,
+ 0xfa50,0xfa51,0xfa52,0xfa53,0xfa54,0xfa55,0xfa56,0xfa57,
+ 0xfa58,0xfa59,0xfa5a,0xfa5b,0xfa5c,0xfa5d,0xfa5e,0xfa5f,
+ 0xfa60,0xfa61,0xfa62,0xfa63,0xfa64,0xfa65,0xfa66,0xfa67,
+ 0xfa68,0xfa69,0xfa6a,0xfa6b,0xfa6c,0xfa6d,0xfa6e,0xfa6f,
+ 0xfa70,0xfa71,0xfa72,0xfa73,0xfa74,0xfa75,0xfa76,0xfa77,
+ 0xfa78,0xfa79,0xfa7a,0xfa7b,0xfa7c,0xfa7d,0xfa7e,0xfa7f,
+ 0xfa80,0xfa81,0xfa82,0xfa83,0xfa84,0xfa85,0xfa86,0xfa87,
+ 0xfa88,0xfa89,0xfa8a,0xfa8b,0xfa8c,0xfa8d,0xfa8e,0xfa8f,
+ 0xfa90,0xfa91,0xfa92,0xfa93,0xfa94,0xfa95,0xfa96,0xfa97,
+ 0xfa98,0xfa99,0xfa9a,0xfa9b,0xfa9c,0xfa9d,0xfa9e,0xfa9f,
+ 0xfaa0,0xfaa1,0xfaa2,0xfaa3,0xfaa4,0xfaa5,0xfaa6,0xfaa7,
+ 0xfaa8,0xfaa9,0xfaaa,0xfaab,0xfaac,0xfaad,0xfaae,0xfaaf,
+ 0xfab0,0xfab1,0xfab2,0xfab3,0xfab4,0xfab5,0xfab6,0xfab7,
+ 0xfab8,0xfab9,0xfaba,0xfabb,0xfabc,0xfabd,0xfabe,0xfabf,
+ 0xfac0,0xfac1,0xfac2,0xfac3,0xfac4,0xfac5,0xfac6,0xfac7,
+ 0xfac8,0xfac9,0xfaca,0xfacb,0xfacc,0xfacd,0xface,0xfacf,
+ 0xfad0,0xfad1,0xfad2,0xfad3,0xfad4,0xfad5,0xfad6,0xfad7,
+ 0xfad8,0xfad9,0xfada,0xfadb,0xfadc,0xfadd,0xfade,0xfadf,
+ 0xfae0,0xfae1,0xfae2,0xfae3,0xfae4,0xfae5,0xfae6,0xfae7,
+ 0xfae8,0xfae9,0xfaea,0xfaeb,0xfaec,0xfaed,0xfaee,0xfaef,
+ 0xfaf0,0xfaf1,0xfaf2,0xfaf3,0xfaf4,0xfaf5,0xfaf6,0xfaf7,
+ 0xfaf8,0xfaf9,0xfafa,0xfafb,0xfafc,0xfafd,0xfafe,0xfaff,
+ 0xfb00,0xfb01,0xfb02,0xfb03,0xfb04,0xfb05,0xfb06,0xfb07,
+ 0xfb08,0xfb09,0xfb0a,0xfb0b,0xfb0c,0xfb0d,0xfb0e,0xfb0f,
+ 0xfb10,0xfb11,0xfb12,0xfb13,0xfb14,0xfb15,0xfb16,0xfb17,
+ 0xfb18,0xfb19,0xfb1a,0xfb1b,0xfb1c,0xfb1d,0xfb1e,0xfb1f,
+ 0xfb20,0xfb21,0xfb22,0xfb23,0xfb24,0xfb25,0xfb26,0xfb27,
+ 0xfb28,0xfb29,0xfb2a,0xfb2b,0xfb2c,0xfb2d,0xfb2e,0xfb2f,
+ 0xfb30,0xfb31,0xfb32,0xfb33,0xfb34,0xfb35,0xfb36,0xfb37,
+ 0xfb38,0xfb39,0xfb3a,0xfb3b,0xfb3c,0xfb3d,0xfb3e,0xfb3f,
+ 0xfb40,0xfb41,0xfb42,0xfb43,0xfb44,0xfb45,0xfb46,0xfb47,
+ 0xfb48,0xfb49,0xfb4a,0xfb4b,0xfb4c,0xfb4d,0xfb4e,0xfb4f,
+ 0xfb50,0xfb51,0xfb52,0xfb53,0xfb54,0xfb55,0xfb56,0xfb57,
+ 0xfb58,0xfb59,0xfb5a,0xfb5b,0xfb5c,0xfb5d,0xfb5e,0xfb5f,
+ 0xfb60,0xfb61,0xfb62,0xfb63,0xfb64,0xfb65,0xfb66,0xfb67,
+ 0xfb68,0xfb69,0xfb6a,0xfb6b,0xfb6c,0xfb6d,0xfb6e,0xfb6f,
+ 0xfb70,0xfb71,0xfb72,0xfb73,0xfb74,0xfb75,0xfb76,0xfb77,
+ 0xfb78,0xfb79,0xfb7a,0xfb7b,0xfb7c,0xfb7d,0xfb7e,0xfb7f,
+ 0xfb80,0xfb81,0xfb82,0xfb83,0xfb84,0xfb85,0xfb86,0xfb87,
+ 0xfb88,0xfb89,0xfb8a,0xfb8b,0xfb8c,0xfb8d,0xfb8e,0xfb8f,
+ 0xfb90,0xfb91,0xfb92,0xfb93,0xfb94,0xfb95,0xfb96,0xfb97,
+ 0xfb98,0xfb99,0xfb9a,0xfb9b,0xfb9c,0xfb9d,0xfb9e,0xfb9f,
+ 0xfba0,0xfba1,0xfba2,0xfba3,0xfba4,0xfba5,0xfba6,0xfba7,
+ 0xfba8,0xfba9,0xfbaa,0xfbab,0xfbac,0xfbad,0xfbae,0xfbaf,
+ 0xfbb0,0xfbb1,0xfbb2,0xfbb3,0xfbb4,0xfbb5,0xfbb6,0xfbb7,
+ 0xfbb8,0xfbb9,0xfbba,0xfbbb,0xfbbc,0xfbbd,0xfbbe,0xfbbf,
+ 0xfbc0,0xfbc1,0xfbc2,0xfbc3,0xfbc4,0xfbc5,0xfbc6,0xfbc7,
+ 0xfbc8,0xfbc9,0xfbca,0xfbcb,0xfbcc,0xfbcd,0xfbce,0xfbcf,
+ 0xfbd0,0xfbd1,0xfbd2,0xfbd3,0xfbd4,0xfbd5,0xfbd6,0xfbd7,
+ 0xfbd8,0xfbd9,0xfbda,0xfbdb,0xfbdc,0xfbdd,0xfbde,0xfbdf,
+ 0xfbe0,0xfbe1,0xfbe2,0xfbe3,0xfbe4,0xfbe5,0xfbe6,0xfbe7,
+ 0xfbe8,0xfbe9,0xfbea,0xfbeb,0xfbec,0xfbed,0xfbee,0xfbef,
+ 0xfbf0,0xfbf1,0xfbf2,0xfbf3,0xfbf4,0xfbf5,0xfbf6,0xfbf7,
+ 0xfbf8,0xfbf9,0xfbfa,0xfbfb,0xfbfc,0xfbfd,0xfbfe,0xfbff,
+ 0xfc00,0xfc01,0xfc02,0xfc03,0xfc04,0xfc05,0xfc06,0xfc07,
+ 0xfc08,0xfc09,0xfc0a,0xfc0b,0xfc0c,0xfc0d,0xfc0e,0xfc0f,
+ 0xfc10,0xfc11,0xfc12,0xfc13,0xfc14,0xfc15,0xfc16,0xfc17,
+ 0xfc18,0xfc19,0xfc1a,0xfc1b,0xfc1c,0xfc1d,0xfc1e,0xfc1f,
+ 0xfc20,0xfc21,0xfc22,0xfc23,0xfc24,0xfc25,0xfc26,0xfc27,
+ 0xfc28,0xfc29,0xfc2a,0xfc2b,0xfc2c,0xfc2d,0xfc2e,0xfc2f,
+ 0xfc30,0xfc31,0xfc32,0xfc33,0xfc34,0xfc35,0xfc36,0xfc37,
+ 0xfc38,0xfc39,0xfc3a,0xfc3b,0xfc3c,0xfc3d,0xfc3e,0xfc3f,
+ 0xfc40,0xfc41,0xfc42,0xfc43,0xfc44,0xfc45,0xfc46,0xfc47,
+ 0xfc48,0xfc49,0xfc4a,0xfc4b,0xfc4c,0xfc4d,0xfc4e,0xfc4f,
+ 0xfc50,0xfc51,0xfc52,0xfc53,0xfc54,0xfc55,0xfc56,0xfc57,
+ 0xfc58,0xfc59,0xfc5a,0xfc5b,0xfc5c,0xfc5d,0xfc5e,0xfc5f,
+ 0xfc60,0xfc61,0xfc62,0xfc63,0xfc64,0xfc65,0xfc66,0xfc67,
+ 0xfc68,0xfc69,0xfc6a,0xfc6b,0xfc6c,0xfc6d,0xfc6e,0xfc6f,
+ 0xfc70,0xfc71,0xfc72,0xfc73,0xfc74,0xfc75,0xfc76,0xfc77,
+ 0xfc78,0xfc79,0xfc7a,0xfc7b,0xfc7c,0xfc7d,0xfc7e,0xfc7f,
+ 0xfc80,0xfc81,0xfc82,0xfc83,0xfc84,0xfc85,0xfc86,0xfc87,
+ 0xfc88,0xfc89,0xfc8a,0xfc8b,0xfc8c,0xfc8d,0xfc8e,0xfc8f,
+ 0xfc90,0xfc91,0xfc92,0xfc93,0xfc94,0xfc95,0xfc96,0xfc97,
+ 0xfc98,0xfc99,0xfc9a,0xfc9b,0xfc9c,0xfc9d,0xfc9e,0xfc9f,
+ 0xfca0,0xfca1,0xfca2,0xfca3,0xfca4,0xfca5,0xfca6,0xfca7,
+ 0xfca8,0xfca9,0xfcaa,0xfcab,0xfcac,0xfcad,0xfcae,0xfcaf,
+ 0xfcb0,0xfcb1,0xfcb2,0xfcb3,0xfcb4,0xfcb5,0xfcb6,0xfcb7,
+ 0xfcb8,0xfcb9,0xfcba,0xfcbb,0xfcbc,0xfcbd,0xfcbe,0xfcbf,
+ 0xfcc0,0xfcc1,0xfcc2,0xfcc3,0xfcc4,0xfcc5,0xfcc6,0xfcc7,
+ 0xfcc8,0xfcc9,0xfcca,0xfccb,0xfccc,0xfccd,0xfcce,0xfccf,
+ 0xfcd0,0xfcd1,0xfcd2,0xfcd3,0xfcd4,0xfcd5,0xfcd6,0xfcd7,
+ 0xfcd8,0xfcd9,0xfcda,0xfcdb,0xfcdc,0xfcdd,0xfcde,0xfcdf,
+ 0xfce0,0xfce1,0xfce2,0xfce3,0xfce4,0xfce5,0xfce6,0xfce7,
+ 0xfce8,0xfce9,0xfcea,0xfceb,0xfcec,0xfced,0xfcee,0xfcef,
+ 0xfcf0,0xfcf1,0xfcf2,0xfcf3,0xfcf4,0xfcf5,0xfcf6,0xfcf7,
+ 0xfcf8,0xfcf9,0xfcfa,0xfcfb,0xfcfc,0xfcfd,0xfcfe,0xfcff,
+ 0xfd00,0xfd01,0xfd02,0xfd03,0xfd04,0xfd05,0xfd06,0xfd07,
+ 0xfd08,0xfd09,0xfd0a,0xfd0b,0xfd0c,0xfd0d,0xfd0e,0xfd0f,
+ 0xfd10,0xfd11,0xfd12,0xfd13,0xfd14,0xfd15,0xfd16,0xfd17,
+ 0xfd18,0xfd19,0xfd1a,0xfd1b,0xfd1c,0xfd1d,0xfd1e,0xfd1f,
+ 0xfd20,0xfd21,0xfd22,0xfd23,0xfd24,0xfd25,0xfd26,0xfd27,
+ 0xfd28,0xfd29,0xfd2a,0xfd2b,0xfd2c,0xfd2d,0xfd2e,0xfd2f,
+ 0xfd30,0xfd31,0xfd32,0xfd33,0xfd34,0xfd35,0xfd36,0xfd37,
+ 0xfd38,0xfd39,0xfd3a,0xfd3b,0xfd3c,0xfd3d,0xfd3e,0xfd3f,
+ 0xfd40,0xfd41,0xfd42,0xfd43,0xfd44,0xfd45,0xfd46,0xfd47,
+ 0xfd48,0xfd49,0xfd4a,0xfd4b,0xfd4c,0xfd4d,0xfd4e,0xfd4f,
+ 0xfd50,0xfd51,0xfd52,0xfd53,0xfd54,0xfd55,0xfd56,0xfd57,
+ 0xfd58,0xfd59,0xfd5a,0xfd5b,0xfd5c,0xfd5d,0xfd5e,0xfd5f,
+ 0xfd60,0xfd61,0xfd62,0xfd63,0xfd64,0xfd65,0xfd66,0xfd67,
+ 0xfd68,0xfd69,0xfd6a,0xfd6b,0xfd6c,0xfd6d,0xfd6e,0xfd6f,
+ 0xfd70,0xfd71,0xfd72,0xfd73,0xfd74,0xfd75,0xfd76,0xfd77,
+ 0xfd78,0xfd79,0xfd7a,0xfd7b,0xfd7c,0xfd7d,0xfd7e,0xfd7f,
+ 0xfd80,0xfd81,0xfd82,0xfd83,0xfd84,0xfd85,0xfd86,0xfd87,
+ 0xfd88,0xfd89,0xfd8a,0xfd8b,0xfd8c,0xfd8d,0xfd8e,0xfd8f,
+ 0xfd90,0xfd91,0xfd92,0xfd93,0xfd94,0xfd95,0xfd96,0xfd97,
+ 0xfd98,0xfd99,0xfd9a,0xfd9b,0xfd9c,0xfd9d,0xfd9e,0xfd9f,
+ 0xfda0,0xfda1,0xfda2,0xfda3,0xfda4,0xfda5,0xfda6,0xfda7,
+ 0xfda8,0xfda9,0xfdaa,0xfdab,0xfdac,0xfdad,0xfdae,0xfdaf,
+ 0xfdb0,0xfdb1,0xfdb2,0xfdb3,0xfdb4,0xfdb5,0xfdb6,0xfdb7,
+ 0xfdb8,0xfdb9,0xfdba,0xfdbb,0xfdbc,0xfdbd,0xfdbe,0xfdbf,
+ 0xfdc0,0xfdc1,0xfdc2,0xfdc3,0xfdc4,0xfdc5,0xfdc6,0xfdc7,
+ 0xfdc8,0xfdc9,0xfdca,0xfdcb,0xfdcc,0xfdcd,0xfdce,0xfdcf,
+ 0xfdd0,0xfdd1,0xfdd2,0xfdd3,0xfdd4,0xfdd5,0xfdd6,0xfdd7,
+ 0xfdd8,0xfdd9,0xfdda,0xfddb,0xfddc,0xfddd,0xfdde,0xfddf,
+ 0xfde0,0xfde1,0xfde2,0xfde3,0xfde4,0xfde5,0xfde6,0xfde7,
+ 0xfde8,0xfde9,0xfdea,0xfdeb,0xfdec,0xfded,0xfdee,0xfdef,
+ 0xfdf0,0xfdf1,0xfdf2,0xfdf3,0xfdf4,0xfdf5,0xfdf6,0xfdf7,
+ 0xfdf8,0xfdf9,0xfdfa,0xfdfb,0xfdfc,0xfdfd,0xfdfe,0xfdff,
+ 0xfe00,0xfe01,0xfe02,0xfe03,0xfe04,0xfe05,0xfe06,0xfe07,
+ 0xfe08,0xfe09,0xfe0a,0xfe0b,0xfe0c,0xfe0d,0xfe0e,0xfe0f,
+ 0xfe10,0xfe11,0xfe12,0xfe13,0xfe14,0xfe15,0xfe16,0xfe17,
+ 0xfe18,0xfe19,0xfe1a,0xfe1b,0xfe1c,0xfe1d,0xfe1e,0xfe1f,
+ 0xfe20,0xfe21,0xfe22,0xfe23,0xfe24,0xfe25,0xfe26,0xfe27,
+ 0xfe28,0xfe29,0xfe2a,0xfe2b,0xfe2c,0xfe2d,0xfe2e,0xfe2f,
+ 0xfe30,0xfe31,0xfe32,0xfe33,0xfe34,0xfe35,0xfe36,0xfe37,
+ 0xfe38,0xfe39,0xfe3a,0xfe3b,0xfe3c,0xfe3d,0xfe3e,0xfe3f,
+ 0xfe40,0xfe41,0xfe42,0xfe43,0xfe44,0xfe45,0xfe46,0xfe47,
+ 0xfe48,0xfe49,0xfe4a,0xfe4b,0xfe4c,0xfe4d,0xfe4e,0xfe4f,
+ 0xfe50,0xfe51,0xfe52,0xfe53,0xfe54,0xfe55,0xfe56,0xfe57,
+ 0xfe58,0xfe59,0xfe5a,0xfe5b,0xfe5c,0xfe5d,0xfe5e,0xfe5f,
+ 0xfe60,0xfe61,0xfe62,0xfe63,0xfe64,0xfe65,0xfe66,0xfe67,
+ 0xfe68,0xfe69,0xfe6a,0xfe6b,0xfe6c,0xfe6d,0xfe6e,0xfe6f,
+ 0xfe70,0xfe71,0xfe72,0xfe73,0xfe74,0xfe75,0xfe76,0xfe77,
+ 0xfe78,0xfe79,0xfe7a,0xfe7b,0xfe7c,0xfe7d,0xfe7e,0xfe7f,
+ 0xfe80,0xfe81,0xfe82,0xfe83,0xfe84,0xfe85,0xfe86,0xfe87,
+ 0xfe88,0xfe89,0xfe8a,0xfe8b,0xfe8c,0xfe8d,0xfe8e,0xfe8f,
+ 0xfe90,0xfe91,0xfe92,0xfe93,0xfe94,0xfe95,0xfe96,0xfe97,
+ 0xfe98,0xfe99,0xfe9a,0xfe9b,0xfe9c,0xfe9d,0xfe9e,0xfe9f,
+ 0xfea0,0xfea1,0xfea2,0xfea3,0xfea4,0xfea5,0xfea6,0xfea7,
+ 0xfea8,0xfea9,0xfeaa,0xfeab,0xfeac,0xfead,0xfeae,0xfeaf,
+ 0xfeb0,0xfeb1,0xfeb2,0xfeb3,0xfeb4,0xfeb5,0xfeb6,0xfeb7,
+ 0xfeb8,0xfeb9,0xfeba,0xfebb,0xfebc,0xfebd,0xfebe,0xfebf,
+ 0xfec0,0xfec1,0xfec2,0xfec3,0xfec4,0xfec5,0xfec6,0xfec7,
+ 0xfec8,0xfec9,0xfeca,0xfecb,0xfecc,0xfecd,0xfece,0xfecf,
+ 0xfed0,0xfed1,0xfed2,0xfed3,0xfed4,0xfed5,0xfed6,0xfed7,
+ 0xfed8,0xfed9,0xfeda,0xfedb,0xfedc,0xfedd,0xfede,0xfedf,
+ 0xfee0,0xfee1,0xfee2,0xfee3,0xfee4,0xfee5,0xfee6,0xfee7,
+ 0xfee8,0xfee9,0xfeea,0xfeeb,0xfeec,0xfeed,0xfeee,0xfeef,
+ 0xfef0,0xfef1,0xfef2,0xfef3,0xfef4,0xfef5,0xfef6,0xfef7,
+ 0xfef8,0xfef9,0xfefa,0xfefb,0xfefc,0xfefd,0xfefe,0xfeff,
+ 0xff00,0xff01,0xff02,0xff03,0xff04,0xff05,0xff06,0xff07,
+ 0xff08,0xff09,0xff0a,0xff0b,0xff0c,0xff0d,0xff0e,0xff0f,
+ 0xff10,0xff11,0xff12,0xff13,0xff14,0xff15,0xff16,0xff17,
+ 0xff18,0xff19,0xff1a,0xff1b,0xff1c,0xff1d,0xff1e,0xff1f,
+ 0xff20,0xff41,0xff42,0xff43,0xff44,0xff45,0xff46,0xff47,
+ 0xff48,0xff49,0xff4a,0xff4b,0xff4c,0xff4d,0xff4e,0xff4f,
+ 0xff50,0xff51,0xff52,0xff53,0xff54,0xff55,0xff56,0xff57,
+ 0xff58,0xff59,0xff5a,0xff3b,0xff3c,0xff3d,0xff3e,0xff3f,
+ 0xff40,0xff41,0xff42,0xff43,0xff44,0xff45,0xff46,0xff47,
+ 0xff48,0xff49,0xff4a,0xff4b,0xff4c,0xff4d,0xff4e,0xff4f,
+ 0xff50,0xff51,0xff52,0xff53,0xff54,0xff55,0xff56,0xff57,
+ 0xff58,0xff59,0xff5a,0xff5b,0xff5c,0xff5d,0xff5e,0xff5f,
+ 0xff60,0xff61,0xff62,0xff63,0xff64,0xff65,0xff66,0xff67,
+ 0xff68,0xff69,0xff6a,0xff6b,0xff6c,0xff6d,0xff6e,0xff6f,
+ 0xff70,0xff71,0xff72,0xff73,0xff74,0xff75,0xff76,0xff77,
+ 0xff78,0xff79,0xff7a,0xff7b,0xff7c,0xff7d,0xff7e,0xff7f,
+ 0xff80,0xff81,0xff82,0xff83,0xff84,0xff85,0xff86,0xff87,
+ 0xff88,0xff89,0xff8a,0xff8b,0xff8c,0xff8d,0xff8e,0xff8f,
+ 0xff90,0xff91,0xff92,0xff93,0xff94,0xff95,0xff96,0xff97,
+ 0xff98,0xff99,0xff9a,0xff9b,0xff9c,0xff9d,0xff9e,0xff9f,
+ 0xffa0,0xffa1,0xffa2,0xffa3,0xffa4,0xffa5,0xffa6,0xffa7,
+ 0xffa8,0xffa9,0xffaa,0xffab,0xffac,0xffad,0xffae,0xffaf,
+ 0xffb0,0xffb1,0xffb2,0xffb3,0xffb4,0xffb5,0xffb6,0xffb7,
+ 0xffb8,0xffb9,0xffba,0xffbb,0xffbc,0xffbd,0xffbe,0xffbf,
+ 0xffc0,0xffc1,0xffc2,0xffc3,0xffc4,0xffc5,0xffc6,0xffc7,
+ 0xffc8,0xffc9,0xffca,0xffcb,0xffcc,0xffcd,0xffce,0xffcf,
+ 0xffd0,0xffd1,0xffd2,0xffd3,0xffd4,0xffd5,0xffd6,0xffd7,
+ 0xffd8,0xffd9,0xffda,0xffdb,0xffdc,0xffdd,0xffde,0xffdf,
+ 0xffe0,0xffe1,0xffe2,0xffe3,0xffe4,0xffe5,0xffe6,0xffe7,
+ 0xffe8,0xffe9,0xffea,0xffeb,0xffec,0xffed,0xffee,0xffef,
+ 0xfff0,0xfff1,0xfff2,0xfff3,0xfff4,0xfff5,0xfff6,0xfff7,
+ 0xfff8,0xfff9,0xfffa,0xfffb,0xfffc,0xfffd,0xfffe,0xffff
+};
+
+static const uint16_t upcase_table[] = {
+ 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,
+ 0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f,
+ 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,
+ 0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f,
+ 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,
+ 0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f,
+ 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,
+ 0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f,
+ 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f,
+ 0x0060,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,
+ 0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f,
+ 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,
+ 0x0058,0x0059,0x005a,0x007b,0x007c,0x007d,0x007e,0x007f,
+ 0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
+ 0x0088,0x0089,0x008a,0x008b,0x008c,0x008d,0x008e,0x008f,
+ 0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
+ 0x0098,0x0099,0x009a,0x009b,0x009c,0x009d,0x009e,0x009f,
+ 0x00a0,0x00a1,0x00a2,0x00a3,0x00a4,0x00a5,0x00a6,0x00a7,
+ 0x00a8,0x00a9,0x00aa,0x00ab,0x00ac,0x00ad,0x00ae,0x00af,
+ 0x00b0,0x00b1,0x00b2,0x00b3,0x00b4,0x00b5,0x00b6,0x00b7,
+ 0x00b8,0x00b9,0x00ba,0x00bb,0x00bc,0x00bd,0x00be,0x00bf,
+ 0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,
+ 0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,
+ 0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00d7,
+ 0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x00df,
+ 0x00c0,0x00c1,0x00c2,0x00c3,0x00c4,0x00c5,0x00c6,0x00c7,
+ 0x00c8,0x00c9,0x00ca,0x00cb,0x00cc,0x00cd,0x00ce,0x00cf,
+ 0x00d0,0x00d1,0x00d2,0x00d3,0x00d4,0x00d5,0x00d6,0x00f7,
+ 0x00d8,0x00d9,0x00da,0x00db,0x00dc,0x00dd,0x00de,0x0178,
+ 0x0100,0x0100,0x0102,0x0102,0x0104,0x0104,0x0106,0x0106,
+ 0x0108,0x0108,0x010a,0x010a,0x010c,0x010c,0x010e,0x010e,
+ 0x0110,0x0110,0x0112,0x0112,0x0114,0x0114,0x0116,0x0116,
+ 0x0118,0x0118,0x011a,0x011a,0x011c,0x011c,0x011e,0x011e,
+ 0x0120,0x0120,0x0122,0x0122,0x0124,0x0124,0x0126,0x0126,
+ 0x0128,0x0128,0x012a,0x012a,0x012c,0x012c,0x012e,0x012e,
+ 0x0130,0x0131,0x0132,0x0132,0x0134,0x0134,0x0136,0x0136,
+ 0x0138,0x0139,0x0139,0x013b,0x013b,0x013d,0x013d,0x013f,
+ 0x013f,0x0141,0x0141,0x0143,0x0143,0x0145,0x0145,0x0147,
+ 0x0147,0x0149,0x014a,0x014a,0x014c,0x014c,0x014e,0x014e,
+ 0x0150,0x0150,0x0152,0x0152,0x0154,0x0154,0x0156,0x0156,
+ 0x0158,0x0158,0x015a,0x015a,0x015c,0x015c,0x015e,0x015e,
+ 0x0160,0x0160,0x0162,0x0162,0x0164,0x0164,0x0166,0x0166,
+ 0x0168,0x0168,0x016a,0x016a,0x016c,0x016c,0x016e,0x016e,
+ 0x0170,0x0170,0x0172,0x0172,0x0174,0x0174,0x0176,0x0176,
+ 0x0178,0x0179,0x0179,0x017b,0x017b,0x017d,0x017d,0x017f,
+ 0x0180,0x0181,0x0182,0x0182,0x0184,0x0184,0x0186,0x0187,
+ 0x0187,0x0189,0x018a,0x018b,0x018b,0x018d,0x018e,0x018f,
+ 0x0190,0x0191,0x0191,0x0193,0x0194,0x0195,0x0196,0x0197,
+ 0x0198,0x0198,0x019a,0x019b,0x019c,0x019d,0x019e,0x019f,
+ 0x01a0,0x01a0,0x01a2,0x01a2,0x01a4,0x01a4,0x01a6,0x01a7,
+ 0x01a7,0x01a9,0x01aa,0x01ab,0x01ac,0x01ac,0x01ae,0x01af,
+ 0x01af,0x01b1,0x01b2,0x01b3,0x01b3,0x01b5,0x01b5,0x01b7,
+ 0x01b8,0x01b8,0x01ba,0x01bb,0x01bc,0x01bc,0x01be,0x01bf,
+ 0x01c0,0x01c1,0x01c2,0x01c3,0x01c4,0x01c5,0x01c4,0x01c7,
+ 0x01c8,0x01c7,0x01ca,0x01cb,0x01ca,0x01cd,0x01cd,0x01cf,
+ 0x01cf,0x01d1,0x01d1,0x01d3,0x01d3,0x01d5,0x01d5,0x01d7,
+ 0x01d7,0x01d9,0x01d9,0x01db,0x01db,0x018e,0x01de,0x01de,
+ 0x01e0,0x01e0,0x01e2,0x01e2,0x01e4,0x01e4,0x01e6,0x01e6,
+ 0x01e8,0x01e8,0x01ea,0x01ea,0x01ec,0x01ec,0x01ee,0x01ee,
+ 0x01f0,0x01f1,0x01f2,0x01f1,0x01f4,0x01f4,0x01f6,0x01f7,
+ 0x01f8,0x01f9,0x01fa,0x01fa,0x01fc,0x01fc,0x01fe,0x01fe,
+ 0x0200,0x0200,0x0202,0x0202,0x0204,0x0204,0x0206,0x0206,
+ 0x0208,0x0208,0x020a,0x020a,0x020c,0x020c,0x020e,0x020e,
+ 0x0210,0x0210,0x0212,0x0212,0x0214,0x0214,0x0216,0x0216,
+ 0x0218,0x0219,0x021a,0x021b,0x021c,0x021d,0x021e,0x021f,
+ 0x0220,0x0221,0x0222,0x0223,0x0224,0x0225,0x0226,0x0227,
+ 0x0228,0x0229,0x022a,0x022b,0x022c,0x022d,0x022e,0x022f,
+ 0x0230,0x0231,0x0232,0x0233,0x0234,0x0235,0x0236,0x0237,
+ 0x0238,0x0239,0x023a,0x023b,0x023c,0x023d,0x023e,0x023f,
+ 0x0240,0x0241,0x0242,0x0243,0x0244,0x0245,0x0246,0x0247,
+ 0x0248,0x0249,0x024a,0x024b,0x024c,0x024d,0x024e,0x024f,
+ 0x0250,0x0251,0x0252,0x0181,0x0186,0x0255,0x0189,0x018a,
+ 0x0258,0x018f,0x025a,0x0190,0x025c,0x025d,0x025e,0x025f,
+ 0x0193,0x0261,0x0262,0x0194,0x0264,0x0265,0x0266,0x0267,
+ 0x0197,0x0196,0x026a,0x026b,0x026c,0x026d,0x026e,0x019c,
+ 0x0270,0x0271,0x019d,0x0273,0x0274,0x019f,0x0276,0x0277,
+ 0x0278,0x0279,0x027a,0x027b,0x027c,0x027d,0x027e,0x027f,
+ 0x0280,0x0281,0x0282,0x01a9,0x0284,0x0285,0x0286,0x0287,
+ 0x01ae,0x0289,0x01b1,0x01b2,0x028c,0x028d,0x028e,0x028f,
+ 0x0290,0x0291,0x01b7,0x0293,0x0294,0x0295,0x0296,0x0297,
+ 0x0298,0x0299,0x029a,0x029b,0x029c,0x029d,0x029e,0x029f,
+ 0x02a0,0x02a1,0x02a2,0x02a3,0x02a4,0x02a5,0x02a6,0x02a7,
+ 0x02a8,0x02a9,0x02aa,0x02ab,0x02ac,0x02ad,0x02ae,0x02af,
+ 0x02b0,0x02b1,0x02b2,0x02b3,0x02b4,0x02b5,0x02b6,0x02b7,
+ 0x02b8,0x02b9,0x02ba,0x02bb,0x02bc,0x02bd,0x02be,0x02bf,
+ 0x02c0,0x02c1,0x02c2,0x02c3,0x02c4,0x02c5,0x02c6,0x02c7,
+ 0x02c8,0x02c9,0x02ca,0x02cb,0x02cc,0x02cd,0x02ce,0x02cf,
+ 0x02d0,0x02d1,0x02d2,0x02d3,0x02d4,0x02d5,0x02d6,0x02d7,
+ 0x02d8,0x02d9,0x02da,0x02db,0x02dc,0x02dd,0x02de,0x02df,
+ 0x02e0,0x02e1,0x02e2,0x02e3,0x02e4,0x02e5,0x02e6,0x02e7,
+ 0x02e8,0x02e9,0x02ea,0x02eb,0x02ec,0x02ed,0x02ee,0x02ef,
+ 0x02f0,0x02f1,0x02f2,0x02f3,0x02f4,0x02f5,0x02f6,0x02f7,
+ 0x02f8,0x02f9,0x02fa,0x02fb,0x02fc,0x02fd,0x02fe,0x02ff,
+ 0x0300,0x0301,0x0302,0x0303,0x0304,0x0305,0x0306,0x0307,
+ 0x0308,0x0309,0x030a,0x030b,0x030c,0x030d,0x030e,0x030f,
+ 0x0310,0x0311,0x0312,0x0313,0x0314,0x0315,0x0316,0x0317,
+ 0x0318,0x0319,0x031a,0x031b,0x031c,0x031d,0x031e,0x031f,
+ 0x0320,0x0321,0x0322,0x0323,0x0324,0x0325,0x0326,0x0327,
+ 0x0328,0x0329,0x032a,0x032b,0x032c,0x032d,0x032e,0x032f,
+ 0x0330,0x0331,0x0332,0x0333,0x0334,0x0335,0x0336,0x0337,
+ 0x0338,0x0339,0x033a,0x033b,0x033c,0x033d,0x033e,0x033f,
+ 0x0340,0x0341,0x0342,0x0343,0x0344,0x0345,0x0346,0x0347,
+ 0x0348,0x0349,0x034a,0x034b,0x034c,0x034d,0x034e,0x034f,
+ 0x0350,0x0351,0x0352,0x0353,0x0354,0x0355,0x0356,0x0357,
+ 0x0358,0x0359,0x035a,0x035b,0x035c,0x035d,0x035e,0x035f,
+ 0x0360,0x0361,0x0362,0x0363,0x0364,0x0365,0x0366,0x0367,
+ 0x0368,0x0369,0x036a,0x036b,0x036c,0x036d,0x036e,0x036f,
+ 0x0370,0x0371,0x0372,0x0373,0x0374,0x0375,0x0376,0x0377,
+ 0x0378,0x0379,0x037a,0x037b,0x037c,0x037d,0x037e,0x037f,
+ 0x0380,0x0381,0x0382,0x0383,0x0384,0x0385,0x0386,0x0387,
+ 0x0388,0x0389,0x038a,0x038b,0x038c,0x038d,0x038e,0x038f,
+ 0x0390,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,
+ 0x0398,0x0399,0x039a,0x039b,0x039c,0x039d,0x039e,0x039f,
+ 0x03a0,0x03a1,0x03a2,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,
+ 0x03a8,0x03a9,0x03aa,0x03ab,0x0386,0x0388,0x0389,0x038a,
+ 0x03b0,0x0391,0x0392,0x0393,0x0394,0x0395,0x0396,0x0397,
+ 0x0398,0x0399,0x039a,0x039b,0x039c,0x039d,0x039e,0x039f,
+ 0x03a0,0x03a1,0x03a3,0x03a3,0x03a4,0x03a5,0x03a6,0x03a7,
+ 0x03a8,0x03a9,0x03aa,0x03ab,0x038c,0x038e,0x038f,0x03cf,
+ 0x03d0,0x03d1,0x03d2,0x03d3,0x03d4,0x03d5,0x03d6,0x03d7,
+ 0x03d8,0x03d9,0x03da,0x03db,0x03dc,0x03dd,0x03de,0x03df,
+ 0x03e0,0x03e1,0x03e2,0x03e2,0x03e4,0x03e4,0x03e6,0x03e6,
+ 0x03e8,0x03e8,0x03ea,0x03ea,0x03ec,0x03ec,0x03ee,0x03ee,
+ 0x03f0,0x03f1,0x03f2,0x03f3,0x03f4,0x03f5,0x03f6,0x03f7,
+ 0x03f8,0x03f9,0x03fa,0x03fb,0x03fc,0x03fd,0x03fe,0x03ff,
+ 0x0400,0x0401,0x0402,0x0403,0x0404,0x0405,0x0406,0x0407,
+ 0x0408,0x0409,0x040a,0x040b,0x040c,0x040d,0x040e,0x040f,
+ 0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0416,0x0417,
+ 0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,
+ 0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426,0x0427,
+ 0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,
+ 0x0410,0x0411,0x0412,0x0413,0x0414,0x0415,0x0416,0x0417,
+ 0x0418,0x0419,0x041a,0x041b,0x041c,0x041d,0x041e,0x041f,
+ 0x0420,0x0421,0x0422,0x0423,0x0424,0x0425,0x0426,0x0427,
+ 0x0428,0x0429,0x042a,0x042b,0x042c,0x042d,0x042e,0x042f,
+ 0x0450,0x0401,0x0402,0x0403,0x0404,0x0405,0x0406,0x0407,
+ 0x0408,0x0409,0x040a,0x040b,0x040c,0x045d,0x040e,0x040f,
+ 0x0460,0x0460,0x0462,0x0462,0x0464,0x0464,0x0466,0x0466,
+ 0x0468,0x0468,0x046a,0x046a,0x046c,0x046c,0x046e,0x046e,
+ 0x0470,0x0470,0x0472,0x0472,0x0474,0x0474,0x0476,0x0476,
+ 0x0478,0x0478,0x047a,0x047a,0x047c,0x047c,0x047e,0x047e,
+ 0x0480,0x0480,0x0482,0x0483,0x0484,0x0485,0x0486,0x0487,
+ 0x0488,0x0489,0x048a,0x048b,0x048c,0x048d,0x048e,0x048f,
+ 0x0490,0x0490,0x0492,0x0492,0x0494,0x0494,0x0496,0x0496,
+ 0x0498,0x0498,0x049a,0x049a,0x049c,0x049c,0x049e,0x049e,
+ 0x04a0,0x04a0,0x04a2,0x04a2,0x04a4,0x04a4,0x04a6,0x04a6,
+ 0x04a8,0x04a8,0x04aa,0x04aa,0x04ac,0x04ac,0x04ae,0x04ae,
+ 0x04b0,0x04b0,0x04b2,0x04b2,0x04b4,0x04b4,0x04b6,0x04b6,
+ 0x04b8,0x04b8,0x04ba,0x04ba,0x04bc,0x04bc,0x04be,0x04be,
+ 0x04c0,0x04c1,0x04c1,0x04c3,0x04c3,0x04c5,0x04c6,0x04c7,
+ 0x04c7,0x04c9,0x04ca,0x04cb,0x04cb,0x04cd,0x04ce,0x04cf,
+ 0x04d0,0x04d0,0x04d2,0x04d2,0x04d4,0x04d4,0x04d6,0x04d6,
+ 0x04d8,0x04d8,0x04da,0x04da,0x04dc,0x04dc,0x04de,0x04de,
+ 0x04e0,0x04e0,0x04e2,0x04e2,0x04e4,0x04e4,0x04e6,0x04e6,
+ 0x04e8,0x04e8,0x04ea,0x04ea,0x04ec,0x04ed,0x04ee,0x04ee,
+ 0x04f0,0x04f0,0x04f2,0x04f2,0x04f4,0x04f4,0x04f6,0x04f7,
+ 0x04f8,0x04f8,0x04fa,0x04fb,0x04fc,0x04fd,0x04fe,0x04ff,
+ 0x0500,0x0501,0x0502,0x0503,0x0504,0x0505,0x0506,0x0507,
+ 0x0508,0x0509,0x050a,0x050b,0x050c,0x050d,0x050e,0x050f,
+ 0x0510,0x0511,0x0512,0x0513,0x0514,0x0515,0x0516,0x0517,
+ 0x0518,0x0519,0x051a,0x051b,0x051c,0x051d,0x051e,0x051f,
+ 0x0520,0x0521,0x0522,0x0523,0x0524,0x0525,0x0526,0x0527,
+ 0x0528,0x0529,0x052a,0x052b,0x052c,0x052d,0x052e,0x052f,
+ 0x0530,0x0531,0x0532,0x0533,0x0534,0x0535,0x0536,0x0537,
+ 0x0538,0x0539,0x053a,0x053b,0x053c,0x053d,0x053e,0x053f,
+ 0x0540,0x0541,0x0542,0x0543,0x0544,0x0545,0x0546,0x0547,
+ 0x0548,0x0549,0x054a,0x054b,0x054c,0x054d,0x054e,0x054f,
+ 0x0550,0x0551,0x0552,0x0553,0x0554,0x0555,0x0556,0x0557,
+ 0x0558,0x0559,0x055a,0x055b,0x055c,0x055d,0x055e,0x055f,
+ 0x0560,0x0531,0x0532,0x0533,0x0534,0x0535,0x0536,0x0537,
+ 0x0538,0x0539,0x053a,0x053b,0x053c,0x053d,0x053e,0x053f,
+ 0x0540,0x0541,0x0542,0x0543,0x0544,0x0545,0x0546,0x0547,
+ 0x0548,0x0549,0x054a,0x054b,0x054c,0x054d,0x054e,0x054f,
+ 0x0550,0x0551,0x0552,0x0553,0x0554,0x0555,0x0556,0x0587,
+ 0x0588,0x0589,0x058a,0x058b,0x058c,0x058d,0x058e,0x058f,
+ 0x0590,0x0591,0x0592,0x0593,0x0594,0x0595,0x0596,0x0597,
+ 0x0598,0x0599,0x059a,0x059b,0x059c,0x059d,0x059e,0x059f,
+ 0x05a0,0x05a1,0x05a2,0x05a3,0x05a4,0x05a5,0x05a6,0x05a7,
+ 0x05a8,0x05a9,0x05aa,0x05ab,0x05ac,0x05ad,0x05ae,0x05af,
+ 0x05b0,0x05b1,0x05b2,0x05b3,0x05b4,0x05b5,0x05b6,0x05b7,
+ 0x05b8,0x05b9,0x05ba,0x05bb,0x05bc,0x05bd,0x05be,0x05bf,
+ 0x05c0,0x05c1,0x05c2,0x05c3,0x05c4,0x05c5,0x05c6,0x05c7,
+ 0x05c8,0x05c9,0x05ca,0x05cb,0x05cc,0x05cd,0x05ce,0x05cf,
+ 0x05d0,0x05d1,0x05d2,0x05d3,0x05d4,0x05d5,0x05d6,0x05d7,
+ 0x05d8,0x05d9,0x05da,0x05db,0x05dc,0x05dd,0x05de,0x05df,
+ 0x05e0,0x05e1,0x05e2,0x05e3,0x05e4,0x05e5,0x05e6,0x05e7,
+ 0x05e8,0x05e9,0x05ea,0x05eb,0x05ec,0x05ed,0x05ee,0x05ef,
+ 0x05f0,0x05f1,0x05f2,0x05f3,0x05f4,0x05f5,0x05f6,0x05f7,
+ 0x05f8,0x05f9,0x05fa,0x05fb,0x05fc,0x05fd,0x05fe,0x05ff,
+ 0x0600,0x0601,0x0602,0x0603,0x0604,0x0605,0x0606,0x0607,
+ 0x0608,0x0609,0x060a,0x060b,0x060c,0x060d,0x060e,0x060f,
+ 0x0610,0x0611,0x0612,0x0613,0x0614,0x0615,0x0616,0x0617,
+ 0x0618,0x0619,0x061a,0x061b,0x061c,0x061d,0x061e,0x061f,
+ 0x0620,0x0621,0x0622,0x0623,0x0624,0x0625,0x0626,0x0627,
+ 0x0628,0x0629,0x062a,0x062b,0x062c,0x062d,0x062e,0x062f,
+ 0x0630,0x0631,0x0632,0x0633,0x0634,0x0635,0x0636,0x0637,
+ 0x0638,0x0639,0x063a,0x063b,0x063c,0x063d,0x063e,0x063f,
+ 0x0640,0x0641,0x0642,0x0643,0x0644,0x0645,0x0646,0x0647,
+ 0x0648,0x0649,0x064a,0x064b,0x064c,0x064d,0x064e,0x064f,
+ 0x0650,0x0651,0x0652,0x0653,0x0654,0x0655,0x0656,0x0657,
+ 0x0658,0x0659,0x065a,0x065b,0x065c,0x065d,0x065e,0x065f,
+ 0x0660,0x0661,0x0662,0x0663,0x0664,0x0665,0x0666,0x0667,
+ 0x0668,0x0669,0x066a,0x066b,0x066c,0x066d,0x066e,0x066f,
+ 0x0670,0x0671,0x0672,0x0673,0x0674,0x0675,0x0676,0x0677,
+ 0x0678,0x0679,0x067a,0x067b,0x067c,0x067d,0x067e,0x067f,
+ 0x0680,0x0681,0x0682,0x0683,0x0684,0x0685,0x0686,0x0687,
+ 0x0688,0x0689,0x068a,0x068b,0x068c,0x068d,0x068e,0x068f,
+ 0x0690,0x0691,0x0692,0x0693,0x0694,0x0695,0x0696,0x0697,
+ 0x0698,0x0699,0x069a,0x069b,0x069c,0x069d,0x069e,0x069f,
+ 0x06a0,0x06a1,0x06a2,0x06a3,0x06a4,0x06a5,0x06a6,0x06a7,
+ 0x06a8,0x06a9,0x06aa,0x06ab,0x06ac,0x06ad,0x06ae,0x06af,
+ 0x06b0,0x06b1,0x06b2,0x06b3,0x06b4,0x06b5,0x06b6,0x06b7,
+ 0x06b8,0x06b9,0x06ba,0x06bb,0x06bc,0x06bd,0x06be,0x06bf,
+ 0x06c0,0x06c1,0x06c2,0x06c3,0x06c4,0x06c5,0x06c6,0x06c7,
+ 0x06c8,0x06c9,0x06ca,0x06cb,0x06cc,0x06cd,0x06ce,0x06cf,
+ 0x06d0,0x06d1,0x06d2,0x06d3,0x06d4,0x06d5,0x06d6,0x06d7,
+ 0x06d8,0x06d9,0x06da,0x06db,0x06dc,0x06dd,0x06de,0x06df,
+ 0x06e0,0x06e1,0x06e2,0x06e3,0x06e4,0x06e5,0x06e6,0x06e7,
+ 0x06e8,0x06e9,0x06ea,0x06eb,0x06ec,0x06ed,0x06ee,0x06ef,
+ 0x06f0,0x06f1,0x06f2,0x06f3,0x06f4,0x06f5,0x06f6,0x06f7,
+ 0x06f8,0x06f9,0x06fa,0x06fb,0x06fc,0x06fd,0x06fe,0x06ff,
+ 0x0700,0x0701,0x0702,0x0703,0x0704,0x0705,0x0706,0x0707,
+ 0x0708,0x0709,0x070a,0x070b,0x070c,0x070d,0x070e,0x070f,
+ 0x0710,0x0711,0x0712,0x0713,0x0714,0x0715,0x0716,0x0717,
+ 0x0718,0x0719,0x071a,0x071b,0x071c,0x071d,0x071e,0x071f,
+ 0x0720,0x0721,0x0722,0x0723,0x0724,0x0725,0x0726,0x0727,
+ 0x0728,0x0729,0x072a,0x072b,0x072c,0x072d,0x072e,0x072f,
+ 0x0730,0x0731,0x0732,0x0733,0x0734,0x0735,0x0736,0x0737,
+ 0x0738,0x0739,0x073a,0x073b,0x073c,0x073d,0x073e,0x073f,
+ 0x0740,0x0741,0x0742,0x0743,0x0744,0x0745,0x0746,0x0747,
+ 0x0748,0x0749,0x074a,0x074b,0x074c,0x074d,0x074e,0x074f,
+ 0x0750,0x0751,0x0752,0x0753,0x0754,0x0755,0x0756,0x0757,
+ 0x0758,0x0759,0x075a,0x075b,0x075c,0x075d,0x075e,0x075f,
+ 0x0760,0x0761,0x0762,0x0763,0x0764,0x0765,0x0766,0x0767,
+ 0x0768,0x0769,0x076a,0x076b,0x076c,0x076d,0x076e,0x076f,
+ 0x0770,0x0771,0x0772,0x0773,0x0774,0x0775,0x0776,0x0777,
+ 0x0778,0x0779,0x077a,0x077b,0x077c,0x077d,0x077e,0x077f,
+ 0x0780,0x0781,0x0782,0x0783,0x0784,0x0785,0x0786,0x0787,
+ 0x0788,0x0789,0x078a,0x078b,0x078c,0x078d,0x078e,0x078f,
+ 0x0790,0x0791,0x0792,0x0793,0x0794,0x0795,0x0796,0x0797,
+ 0x0798,0x0799,0x079a,0x079b,0x079c,0x079d,0x079e,0x079f,
+ 0x07a0,0x07a1,0x07a2,0x07a3,0x07a4,0x07a5,0x07a6,0x07a7,
+ 0x07a8,0x07a9,0x07aa,0x07ab,0x07ac,0x07ad,0x07ae,0x07af,
+ 0x07b0,0x07b1,0x07b2,0x07b3,0x07b4,0x07b5,0x07b6,0x07b7,
+ 0x07b8,0x07b9,0x07ba,0x07bb,0x07bc,0x07bd,0x07be,0x07bf,
+ 0x07c0,0x07c1,0x07c2,0x07c3,0x07c4,0x07c5,0x07c6,0x07c7,
+ 0x07c8,0x07c9,0x07ca,0x07cb,0x07cc,0x07cd,0x07ce,0x07cf,
+ 0x07d0,0x07d1,0x07d2,0x07d3,0x07d4,0x07d5,0x07d6,0x07d7,
+ 0x07d8,0x07d9,0x07da,0x07db,0x07dc,0x07dd,0x07de,0x07df,
+ 0x07e0,0x07e1,0x07e2,0x07e3,0x07e4,0x07e5,0x07e6,0x07e7,
+ 0x07e8,0x07e9,0x07ea,0x07eb,0x07ec,0x07ed,0x07ee,0x07ef,
+ 0x07f0,0x07f1,0x07f2,0x07f3,0x07f4,0x07f5,0x07f6,0x07f7,
+ 0x07f8,0x07f9,0x07fa,0x07fb,0x07fc,0x07fd,0x07fe,0x07ff,
+ 0x0800,0x0801,0x0802,0x0803,0x0804,0x0805,0x0806,0x0807,
+ 0x0808,0x0809,0x080a,0x080b,0x080c,0x080d,0x080e,0x080f,
+ 0x0810,0x0811,0x0812,0x0813,0x0814,0x0815,0x0816,0x0817,
+ 0x0818,0x0819,0x081a,0x081b,0x081c,0x081d,0x081e,0x081f,
+ 0x0820,0x0821,0x0822,0x0823,0x0824,0x0825,0x0826,0x0827,
+ 0x0828,0x0829,0x082a,0x082b,0x082c,0x082d,0x082e,0x082f,
+ 0x0830,0x0831,0x0832,0x0833,0x0834,0x0835,0x0836,0x0837,
+ 0x0838,0x0839,0x083a,0x083b,0x083c,0x083d,0x083e,0x083f,
+ 0x0840,0x0841,0x0842,0x0843,0x0844,0x0845,0x0846,0x0847,
+ 0x0848,0x0849,0x084a,0x084b,0x084c,0x084d,0x084e,0x084f,
+ 0x0850,0x0851,0x0852,0x0853,0x0854,0x0855,0x0856,0x0857,
+ 0x0858,0x0859,0x085a,0x085b,0x085c,0x085d,0x085e,0x085f,
+ 0x0860,0x0861,0x0862,0x0863,0x0864,0x0865,0x0866,0x0867,
+ 0x0868,0x0869,0x086a,0x086b,0x086c,0x086d,0x086e,0x086f,
+ 0x0870,0x0871,0x0872,0x0873,0x0874,0x0875,0x0876,0x0877,
+ 0x0878,0x0879,0x087a,0x087b,0x087c,0x087d,0x087e,0x087f,
+ 0x0880,0x0881,0x0882,0x0883,0x0884,0x0885,0x0886,0x0887,
+ 0x0888,0x0889,0x088a,0x088b,0x088c,0x088d,0x088e,0x088f,
+ 0x0890,0x0891,0x0892,0x0893,0x0894,0x0895,0x0896,0x0897,
+ 0x0898,0x0899,0x089a,0x089b,0x089c,0x089d,0x089e,0x089f,
+ 0x08a0,0x08a1,0x08a2,0x08a3,0x08a4,0x08a5,0x08a6,0x08a7,
+ 0x08a8,0x08a9,0x08aa,0x08ab,0x08ac,0x08ad,0x08ae,0x08af,
+ 0x08b0,0x08b1,0x08b2,0x08b3,0x08b4,0x08b5,0x08b6,0x08b7,
+ 0x08b8,0x08b9,0x08ba,0x08bb,0x08bc,0x08bd,0x08be,0x08bf,
+ 0x08c0,0x08c1,0x08c2,0x08c3,0x08c4,0x08c5,0x08c6,0x08c7,
+ 0x08c8,0x08c9,0x08ca,0x08cb,0x08cc,0x08cd,0x08ce,0x08cf,
+ 0x08d0,0x08d1,0x08d2,0x08d3,0x08d4,0x08d5,0x08d6,0x08d7,
+ 0x08d8,0x08d9,0x08da,0x08db,0x08dc,0x08dd,0x08de,0x08df,
+ 0x08e0,0x08e1,0x08e2,0x08e3,0x08e4,0x08e5,0x08e6,0x08e7,
+ 0x08e8,0x08e9,0x08ea,0x08eb,0x08ec,0x08ed,0x08ee,0x08ef,
+ 0x08f0,0x08f1,0x08f2,0x08f3,0x08f4,0x08f5,0x08f6,0x08f7,
+ 0x08f8,0x08f9,0x08fa,0x08fb,0x08fc,0x08fd,0x08fe,0x08ff,
+ 0x0900,0x0901,0x0902,0x0903,0x0904,0x0905,0x0906,0x0907,
+ 0x0908,0x0909,0x090a,0x090b,0x090c,0x090d,0x090e,0x090f,
+ 0x0910,0x0911,0x0912,0x0913,0x0914,0x0915,0x0916,0x0917,
+ 0x0918,0x0919,0x091a,0x091b,0x091c,0x091d,0x091e,0x091f,
+ 0x0920,0x0921,0x0922,0x0923,0x0924,0x0925,0x0926,0x0927,
+ 0x0928,0x0929,0x092a,0x092b,0x092c,0x092d,0x092e,0x092f,
+ 0x0930,0x0931,0x0932,0x0933,0x0934,0x0935,0x0936,0x0937,
+ 0x0938,0x0939,0x093a,0x093b,0x093c,0x093d,0x093e,0x093f,
+ 0x0940,0x0941,0x0942,0x0943,0x0944,0x0945,0x0946,0x0947,
+ 0x0948,0x0949,0x094a,0x094b,0x094c,0x094d,0x094e,0x094f,
+ 0x0950,0x0951,0x0952,0x0953,0x0954,0x0955,0x0956,0x0957,
+ 0x0958,0x0959,0x095a,0x095b,0x095c,0x095d,0x095e,0x095f,
+ 0x0960,0x0961,0x0962,0x0963,0x0964,0x0965,0x0966,0x0967,
+ 0x0968,0x0969,0x096a,0x096b,0x096c,0x096d,0x096e,0x096f,
+ 0x0970,0x0971,0x0972,0x0973,0x0974,0x0975,0x0976,0x0977,
+ 0x0978,0x0979,0x097a,0x097b,0x097c,0x097d,0x097e,0x097f,
+ 0x0980,0x0981,0x0982,0x0983,0x0984,0x0985,0x0986,0x0987,
+ 0x0988,0x0989,0x098a,0x098b,0x098c,0x098d,0x098e,0x098f,
+ 0x0990,0x0991,0x0992,0x0993,0x0994,0x0995,0x0996,0x0997,
+ 0x0998,0x0999,0x099a,0x099b,0x099c,0x099d,0x099e,0x099f,
+ 0x09a0,0x09a1,0x09a2,0x09a3,0x09a4,0x09a5,0x09a6,0x09a7,
+ 0x09a8,0x09a9,0x09aa,0x09ab,0x09ac,0x09ad,0x09ae,0x09af,
+ 0x09b0,0x09b1,0x09b2,0x09b3,0x09b4,0x09b5,0x09b6,0x09b7,
+ 0x09b8,0x09b9,0x09ba,0x09bb,0x09bc,0x09bd,0x09be,0x09bf,
+ 0x09c0,0x09c1,0x09c2,0x09c3,0x09c4,0x09c5,0x09c6,0x09c7,
+ 0x09c8,0x09c9,0x09ca,0x09cb,0x09cc,0x09cd,0x09ce,0x09cf,
+ 0x09d0,0x09d1,0x09d2,0x09d3,0x09d4,0x09d5,0x09d6,0x09d7,
+ 0x09d8,0x09d9,0x09da,0x09db,0x09dc,0x09dd,0x09de,0x09df,
+ 0x09e0,0x09e1,0x09e2,0x09e3,0x09e4,0x09e5,0x09e6,0x09e7,
+ 0x09e8,0x09e9,0x09ea,0x09eb,0x09ec,0x09ed,0x09ee,0x09ef,
+ 0x09f0,0x09f1,0x09f2,0x09f3,0x09f4,0x09f5,0x09f6,0x09f7,
+ 0x09f8,0x09f9,0x09fa,0x09fb,0x09fc,0x09fd,0x09fe,0x09ff,
+ 0x0a00,0x0a01,0x0a02,0x0a03,0x0a04,0x0a05,0x0a06,0x0a07,
+ 0x0a08,0x0a09,0x0a0a,0x0a0b,0x0a0c,0x0a0d,0x0a0e,0x0a0f,
+ 0x0a10,0x0a11,0x0a12,0x0a13,0x0a14,0x0a15,0x0a16,0x0a17,
+ 0x0a18,0x0a19,0x0a1a,0x0a1b,0x0a1c,0x0a1d,0x0a1e,0x0a1f,
+ 0x0a20,0x0a21,0x0a22,0x0a23,0x0a24,0x0a25,0x0a26,0x0a27,
+ 0x0a28,0x0a29,0x0a2a,0x0a2b,0x0a2c,0x0a2d,0x0a2e,0x0a2f,
+ 0x0a30,0x0a31,0x0a32,0x0a33,0x0a34,0x0a35,0x0a36,0x0a37,
+ 0x0a38,0x0a39,0x0a3a,0x0a3b,0x0a3c,0x0a3d,0x0a3e,0x0a3f,
+ 0x0a40,0x0a41,0x0a42,0x0a43,0x0a44,0x0a45,0x0a46,0x0a47,
+ 0x0a48,0x0a49,0x0a4a,0x0a4b,0x0a4c,0x0a4d,0x0a4e,0x0a4f,
+ 0x0a50,0x0a51,0x0a52,0x0a53,0x0a54,0x0a55,0x0a56,0x0a57,
+ 0x0a58,0x0a59,0x0a5a,0x0a5b,0x0a5c,0x0a5d,0x0a5e,0x0a5f,
+ 0x0a60,0x0a61,0x0a62,0x0a63,0x0a64,0x0a65,0x0a66,0x0a67,
+ 0x0a68,0x0a69,0x0a6a,0x0a6b,0x0a6c,0x0a6d,0x0a6e,0x0a6f,
+ 0x0a70,0x0a71,0x0a72,0x0a73,0x0a74,0x0a75,0x0a76,0x0a77,
+ 0x0a78,0x0a79,0x0a7a,0x0a7b,0x0a7c,0x0a7d,0x0a7e,0x0a7f,
+ 0x0a80,0x0a81,0x0a82,0x0a83,0x0a84,0x0a85,0x0a86,0x0a87,
+ 0x0a88,0x0a89,0x0a8a,0x0a8b,0x0a8c,0x0a8d,0x0a8e,0x0a8f,
+ 0x0a90,0x0a91,0x0a92,0x0a93,0x0a94,0x0a95,0x0a96,0x0a97,
+ 0x0a98,0x0a99,0x0a9a,0x0a9b,0x0a9c,0x0a9d,0x0a9e,0x0a9f,
+ 0x0aa0,0x0aa1,0x0aa2,0x0aa3,0x0aa4,0x0aa5,0x0aa6,0x0aa7,
+ 0x0aa8,0x0aa9,0x0aaa,0x0aab,0x0aac,0x0aad,0x0aae,0x0aaf,
+ 0x0ab0,0x0ab1,0x0ab2,0x0ab3,0x0ab4,0x0ab5,0x0ab6,0x0ab7,
+ 0x0ab8,0x0ab9,0x0aba,0x0abb,0x0abc,0x0abd,0x0abe,0x0abf,
+ 0x0ac0,0x0ac1,0x0ac2,0x0ac3,0x0ac4,0x0ac5,0x0ac6,0x0ac7,
+ 0x0ac8,0x0ac9,0x0aca,0x0acb,0x0acc,0x0acd,0x0ace,0x0acf,
+ 0x0ad0,0x0ad1,0x0ad2,0x0ad3,0x0ad4,0x0ad5,0x0ad6,0x0ad7,
+ 0x0ad8,0x0ad9,0x0ada,0x0adb,0x0adc,0x0add,0x0ade,0x0adf,
+ 0x0ae0,0x0ae1,0x0ae2,0x0ae3,0x0ae4,0x0ae5,0x0ae6,0x0ae7,
+ 0x0ae8,0x0ae9,0x0aea,0x0aeb,0x0aec,0x0aed,0x0aee,0x0aef,
+ 0x0af0,0x0af1,0x0af2,0x0af3,0x0af4,0x0af5,0x0af6,0x0af7,
+ 0x0af8,0x0af9,0x0afa,0x0afb,0x0afc,0x0afd,0x0afe,0x0aff,
+ 0x0b00,0x0b01,0x0b02,0x0b03,0x0b04,0x0b05,0x0b06,0x0b07,
+ 0x0b08,0x0b09,0x0b0a,0x0b0b,0x0b0c,0x0b0d,0x0b0e,0x0b0f,
+ 0x0b10,0x0b11,0x0b12,0x0b13,0x0b14,0x0b15,0x0b16,0x0b17,
+ 0x0b18,0x0b19,0x0b1a,0x0b1b,0x0b1c,0x0b1d,0x0b1e,0x0b1f,
+ 0x0b20,0x0b21,0x0b22,0x0b23,0x0b24,0x0b25,0x0b26,0x0b27,
+ 0x0b28,0x0b29,0x0b2a,0x0b2b,0x0b2c,0x0b2d,0x0b2e,0x0b2f,
+ 0x0b30,0x0b31,0x0b32,0x0b33,0x0b34,0x0b35,0x0b36,0x0b37,
+ 0x0b38,0x0b39,0x0b3a,0x0b3b,0x0b3c,0x0b3d,0x0b3e,0x0b3f,
+ 0x0b40,0x0b41,0x0b42,0x0b43,0x0b44,0x0b45,0x0b46,0x0b47,
+ 0x0b48,0x0b49,0x0b4a,0x0b4b,0x0b4c,0x0b4d,0x0b4e,0x0b4f,
+ 0x0b50,0x0b51,0x0b52,0x0b53,0x0b54,0x0b55,0x0b56,0x0b57,
+ 0x0b58,0x0b59,0x0b5a,0x0b5b,0x0b5c,0x0b5d,0x0b5e,0x0b5f,
+ 0x0b60,0x0b61,0x0b62,0x0b63,0x0b64,0x0b65,0x0b66,0x0b67,
+ 0x0b68,0x0b69,0x0b6a,0x0b6b,0x0b6c,0x0b6d,0x0b6e,0x0b6f,
+ 0x0b70,0x0b71,0x0b72,0x0b73,0x0b74,0x0b75,0x0b76,0x0b77,
+ 0x0b78,0x0b79,0x0b7a,0x0b7b,0x0b7c,0x0b7d,0x0b7e,0x0b7f,
+ 0x0b80,0x0b81,0x0b82,0x0b83,0x0b84,0x0b85,0x0b86,0x0b87,
+ 0x0b88,0x0b89,0x0b8a,0x0b8b,0x0b8c,0x0b8d,0x0b8e,0x0b8f,
+ 0x0b90,0x0b91,0x0b92,0x0b93,0x0b94,0x0b95,0x0b96,0x0b97,
+ 0x0b98,0x0b99,0x0b9a,0x0b9b,0x0b9c,0x0b9d,0x0b9e,0x0b9f,
+ 0x0ba0,0x0ba1,0x0ba2,0x0ba3,0x0ba4,0x0ba5,0x0ba6,0x0ba7,
+ 0x0ba8,0x0ba9,0x0baa,0x0bab,0x0bac,0x0bad,0x0bae,0x0baf,
+ 0x0bb0,0x0bb1,0x0bb2,0x0bb3,0x0bb4,0x0bb5,0x0bb6,0x0bb7,
+ 0x0bb8,0x0bb9,0x0bba,0x0bbb,0x0bbc,0x0bbd,0x0bbe,0x0bbf,
+ 0x0bc0,0x0bc1,0x0bc2,0x0bc3,0x0bc4,0x0bc5,0x0bc6,0x0bc7,
+ 0x0bc8,0x0bc9,0x0bca,0x0bcb,0x0bcc,0x0bcd,0x0bce,0x0bcf,
+ 0x0bd0,0x0bd1,0x0bd2,0x0bd3,0x0bd4,0x0bd5,0x0bd6,0x0bd7,
+ 0x0bd8,0x0bd9,0x0bda,0x0bdb,0x0bdc,0x0bdd,0x0bde,0x0bdf,
+ 0x0be0,0x0be1,0x0be2,0x0be3,0x0be4,0x0be5,0x0be6,0x0be7,
+ 0x0be8,0x0be9,0x0bea,0x0beb,0x0bec,0x0bed,0x0bee,0x0bef,
+ 0x0bf0,0x0bf1,0x0bf2,0x0bf3,0x0bf4,0x0bf5,0x0bf6,0x0bf7,
+ 0x0bf8,0x0bf9,0x0bfa,0x0bfb,0x0bfc,0x0bfd,0x0bfe,0x0bff,
+ 0x0c00,0x0c01,0x0c02,0x0c03,0x0c04,0x0c05,0x0c06,0x0c07,
+ 0x0c08,0x0c09,0x0c0a,0x0c0b,0x0c0c,0x0c0d,0x0c0e,0x0c0f,
+ 0x0c10,0x0c11,0x0c12,0x0c13,0x0c14,0x0c15,0x0c16,0x0c17,
+ 0x0c18,0x0c19,0x0c1a,0x0c1b,0x0c1c,0x0c1d,0x0c1e,0x0c1f,
+ 0x0c20,0x0c21,0x0c22,0x0c23,0x0c24,0x0c25,0x0c26,0x0c27,
+ 0x0c28,0x0c29,0x0c2a,0x0c2b,0x0c2c,0x0c2d,0x0c2e,0x0c2f,
+ 0x0c30,0x0c31,0x0c32,0x0c33,0x0c34,0x0c35,0x0c36,0x0c37,
+ 0x0c38,0x0c39,0x0c3a,0x0c3b,0x0c3c,0x0c3d,0x0c3e,0x0c3f,
+ 0x0c40,0x0c41,0x0c42,0x0c43,0x0c44,0x0c45,0x0c46,0x0c47,
+ 0x0c48,0x0c49,0x0c4a,0x0c4b,0x0c4c,0x0c4d,0x0c4e,0x0c4f,
+ 0x0c50,0x0c51,0x0c52,0x0c53,0x0c54,0x0c55,0x0c56,0x0c57,
+ 0x0c58,0x0c59,0x0c5a,0x0c5b,0x0c5c,0x0c5d,0x0c5e,0x0c5f,
+ 0x0c60,0x0c61,0x0c62,0x0c63,0x0c64,0x0c65,0x0c66,0x0c67,
+ 0x0c68,0x0c69,0x0c6a,0x0c6b,0x0c6c,0x0c6d,0x0c6e,0x0c6f,
+ 0x0c70,0x0c71,0x0c72,0x0c73,0x0c74,0x0c75,0x0c76,0x0c77,
+ 0x0c78,0x0c79,0x0c7a,0x0c7b,0x0c7c,0x0c7d,0x0c7e,0x0c7f,
+ 0x0c80,0x0c81,0x0c82,0x0c83,0x0c84,0x0c85,0x0c86,0x0c87,
+ 0x0c88,0x0c89,0x0c8a,0x0c8b,0x0c8c,0x0c8d,0x0c8e,0x0c8f,
+ 0x0c90,0x0c91,0x0c92,0x0c93,0x0c94,0x0c95,0x0c96,0x0c97,
+ 0x0c98,0x0c99,0x0c9a,0x0c9b,0x0c9c,0x0c9d,0x0c9e,0x0c9f,
+ 0x0ca0,0x0ca1,0x0ca2,0x0ca3,0x0ca4,0x0ca5,0x0ca6,0x0ca7,
+ 0x0ca8,0x0ca9,0x0caa,0x0cab,0x0cac,0x0cad,0x0cae,0x0caf,
+ 0x0cb0,0x0cb1,0x0cb2,0x0cb3,0x0cb4,0x0cb5,0x0cb6,0x0cb7,
+ 0x0cb8,0x0cb9,0x0cba,0x0cbb,0x0cbc,0x0cbd,0x0cbe,0x0cbf,
+ 0x0cc0,0x0cc1,0x0cc2,0x0cc3,0x0cc4,0x0cc5,0x0cc6,0x0cc7,
+ 0x0cc8,0x0cc9,0x0cca,0x0ccb,0x0ccc,0x0ccd,0x0cce,0x0ccf,
+ 0x0cd0,0x0cd1,0x0cd2,0x0cd3,0x0cd4,0x0cd5,0x0cd6,0x0cd7,
+ 0x0cd8,0x0cd9,0x0cda,0x0cdb,0x0cdc,0x0cdd,0x0cde,0x0cdf,
+ 0x0ce0,0x0ce1,0x0ce2,0x0ce3,0x0ce4,0x0ce5,0x0ce6,0x0ce7,
+ 0x0ce8,0x0ce9,0x0cea,0x0ceb,0x0cec,0x0ced,0x0cee,0x0cef,
+ 0x0cf0,0x0cf1,0x0cf2,0x0cf3,0x0cf4,0x0cf5,0x0cf6,0x0cf7,
+ 0x0cf8,0x0cf9,0x0cfa,0x0cfb,0x0cfc,0x0cfd,0x0cfe,0x0cff,
+ 0x0d00,0x0d01,0x0d02,0x0d03,0x0d04,0x0d05,0x0d06,0x0d07,
+ 0x0d08,0x0d09,0x0d0a,0x0d0b,0x0d0c,0x0d0d,0x0d0e,0x0d0f,
+ 0x0d10,0x0d11,0x0d12,0x0d13,0x0d14,0x0d15,0x0d16,0x0d17,
+ 0x0d18,0x0d19,0x0d1a,0x0d1b,0x0d1c,0x0d1d,0x0d1e,0x0d1f,
+ 0x0d20,0x0d21,0x0d22,0x0d23,0x0d24,0x0d25,0x0d26,0x0d27,
+ 0x0d28,0x0d29,0x0d2a,0x0d2b,0x0d2c,0x0d2d,0x0d2e,0x0d2f,
+ 0x0d30,0x0d31,0x0d32,0x0d33,0x0d34,0x0d35,0x0d36,0x0d37,
+ 0x0d38,0x0d39,0x0d3a,0x0d3b,0x0d3c,0x0d3d,0x0d3e,0x0d3f,
+ 0x0d40,0x0d41,0x0d42,0x0d43,0x0d44,0x0d45,0x0d46,0x0d47,
+ 0x0d48,0x0d49,0x0d4a,0x0d4b,0x0d4c,0x0d4d,0x0d4e,0x0d4f,
+ 0x0d50,0x0d51,0x0d52,0x0d53,0x0d54,0x0d55,0x0d56,0x0d57,
+ 0x0d58,0x0d59,0x0d5a,0x0d5b,0x0d5c,0x0d5d,0x0d5e,0x0d5f,
+ 0x0d60,0x0d61,0x0d62,0x0d63,0x0d64,0x0d65,0x0d66,0x0d67,
+ 0x0d68,0x0d69,0x0d6a,0x0d6b,0x0d6c,0x0d6d,0x0d6e,0x0d6f,
+ 0x0d70,0x0d71,0x0d72,0x0d73,0x0d74,0x0d75,0x0d76,0x0d77,
+ 0x0d78,0x0d79,0x0d7a,0x0d7b,0x0d7c,0x0d7d,0x0d7e,0x0d7f,
+ 0x0d80,0x0d81,0x0d82,0x0d83,0x0d84,0x0d85,0x0d86,0x0d87,
+ 0x0d88,0x0d89,0x0d8a,0x0d8b,0x0d8c,0x0d8d,0x0d8e,0x0d8f,
+ 0x0d90,0x0d91,0x0d92,0x0d93,0x0d94,0x0d95,0x0d96,0x0d97,
+ 0x0d98,0x0d99,0x0d9a,0x0d9b,0x0d9c,0x0d9d,0x0d9e,0x0d9f,
+ 0x0da0,0x0da1,0x0da2,0x0da3,0x0da4,0x0da5,0x0da6,0x0da7,
+ 0x0da8,0x0da9,0x0daa,0x0dab,0x0dac,0x0dad,0x0dae,0x0daf,
+ 0x0db0,0x0db1,0x0db2,0x0db3,0x0db4,0x0db5,0x0db6,0x0db7,
+ 0x0db8,0x0db9,0x0dba,0x0dbb,0x0dbc,0x0dbd,0x0dbe,0x0dbf,
+ 0x0dc0,0x0dc1,0x0dc2,0x0dc3,0x0dc4,0x0dc5,0x0dc6,0x0dc7,
+ 0x0dc8,0x0dc9,0x0dca,0x0dcb,0x0dcc,0x0dcd,0x0dce,0x0dcf,
+ 0x0dd0,0x0dd1,0x0dd2,0x0dd3,0x0dd4,0x0dd5,0x0dd6,0x0dd7,
+ 0x0dd8,0x0dd9,0x0dda,0x0ddb,0x0ddc,0x0ddd,0x0dde,0x0ddf,
+ 0x0de0,0x0de1,0x0de2,0x0de3,0x0de4,0x0de5,0x0de6,0x0de7,
+ 0x0de8,0x0de9,0x0dea,0x0deb,0x0dec,0x0ded,0x0dee,0x0def,
+ 0x0df0,0x0df1,0x0df2,0x0df3,0x0df4,0x0df5,0x0df6,0x0df7,
+ 0x0df8,0x0df9,0x0dfa,0x0dfb,0x0dfc,0x0dfd,0x0dfe,0x0dff,
+ 0x0e00,0x0e01,0x0e02,0x0e03,0x0e04,0x0e05,0x0e06,0x0e07,
+ 0x0e08,0x0e09,0x0e0a,0x0e0b,0x0e0c,0x0e0d,0x0e0e,0x0e0f,
+ 0x0e10,0x0e11,0x0e12,0x0e13,0x0e14,0x0e15,0x0e16,0x0e17,
+ 0x0e18,0x0e19,0x0e1a,0x0e1b,0x0e1c,0x0e1d,0x0e1e,0x0e1f,
+ 0x0e20,0x0e21,0x0e22,0x0e23,0x0e24,0x0e25,0x0e26,0x0e27,
+ 0x0e28,0x0e29,0x0e2a,0x0e2b,0x0e2c,0x0e2d,0x0e2e,0x0e2f,
+ 0x0e30,0x0e31,0x0e32,0x0e33,0x0e34,0x0e35,0x0e36,0x0e37,
+ 0x0e38,0x0e39,0x0e3a,0x0e3b,0x0e3c,0x0e3d,0x0e3e,0x0e3f,
+ 0x0e40,0x0e41,0x0e42,0x0e43,0x0e44,0x0e45,0x0e46,0x0e47,
+ 0x0e48,0x0e49,0x0e4a,0x0e4b,0x0e4c,0x0e4d,0x0e4e,0x0e4f,
+ 0x0e50,0x0e51,0x0e52,0x0e53,0x0e54,0x0e55,0x0e56,0x0e57,
+ 0x0e58,0x0e59,0x0e5a,0x0e5b,0x0e5c,0x0e5d,0x0e5e,0x0e5f,
+ 0x0e60,0x0e61,0x0e62,0x0e63,0x0e64,0x0e65,0x0e66,0x0e67,
+ 0x0e68,0x0e69,0x0e6a,0x0e6b,0x0e6c,0x0e6d,0x0e6e,0x0e6f,
+ 0x0e70,0x0e71,0x0e72,0x0e73,0x0e74,0x0e75,0x0e76,0x0e77,
+ 0x0e78,0x0e79,0x0e7a,0x0e7b,0x0e7c,0x0e7d,0x0e7e,0x0e7f,
+ 0x0e80,0x0e81,0x0e82,0x0e83,0x0e84,0x0e85,0x0e86,0x0e87,
+ 0x0e88,0x0e89,0x0e8a,0x0e8b,0x0e8c,0x0e8d,0x0e8e,0x0e8f,
+ 0x0e90,0x0e91,0x0e92,0x0e93,0x0e94,0x0e95,0x0e96,0x0e97,
+ 0x0e98,0x0e99,0x0e9a,0x0e9b,0x0e9c,0x0e9d,0x0e9e,0x0e9f,
+ 0x0ea0,0x0ea1,0x0ea2,0x0ea3,0x0ea4,0x0ea5,0x0ea6,0x0ea7,
+ 0x0ea8,0x0ea9,0x0eaa,0x0eab,0x0eac,0x0ead,0x0eae,0x0eaf,
+ 0x0eb0,0x0eb1,0x0eb2,0x0eb3,0x0eb4,0x0eb5,0x0eb6,0x0eb7,
+ 0x0eb8,0x0eb9,0x0eba,0x0ebb,0x0ebc,0x0ebd,0x0ebe,0x0ebf,
+ 0x0ec0,0x0ec1,0x0ec2,0x0ec3,0x0ec4,0x0ec5,0x0ec6,0x0ec7,
+ 0x0ec8,0x0ec9,0x0eca,0x0ecb,0x0ecc,0x0ecd,0x0ece,0x0ecf,
+ 0x0ed0,0x0ed1,0x0ed2,0x0ed3,0x0ed4,0x0ed5,0x0ed6,0x0ed7,
+ 0x0ed8,0x0ed9,0x0eda,0x0edb,0x0edc,0x0edd,0x0ede,0x0edf,
+ 0x0ee0,0x0ee1,0x0ee2,0x0ee3,0x0ee4,0x0ee5,0x0ee6,0x0ee7,
+ 0x0ee8,0x0ee9,0x0eea,0x0eeb,0x0eec,0x0eed,0x0eee,0x0eef,
+ 0x0ef0,0x0ef1,0x0ef2,0x0ef3,0x0ef4,0x0ef5,0x0ef6,0x0ef7,
+ 0x0ef8,0x0ef9,0x0efa,0x0efb,0x0efc,0x0efd,0x0efe,0x0eff,
+ 0x0f00,0x0f01,0x0f02,0x0f03,0x0f04,0x0f05,0x0f06,0x0f07,
+ 0x0f08,0x0f09,0x0f0a,0x0f0b,0x0f0c,0x0f0d,0x0f0e,0x0f0f,
+ 0x0f10,0x0f11,0x0f12,0x0f13,0x0f14,0x0f15,0x0f16,0x0f17,
+ 0x0f18,0x0f19,0x0f1a,0x0f1b,0x0f1c,0x0f1d,0x0f1e,0x0f1f,
+ 0x0f20,0x0f21,0x0f22,0x0f23,0x0f24,0x0f25,0x0f26,0x0f27,
+ 0x0f28,0x0f29,0x0f2a,0x0f2b,0x0f2c,0x0f2d,0x0f2e,0x0f2f,
+ 0x0f30,0x0f31,0x0f32,0x0f33,0x0f34,0x0f35,0x0f36,0x0f37,
+ 0x0f38,0x0f39,0x0f3a,0x0f3b,0x0f3c,0x0f3d,0x0f3e,0x0f3f,
+ 0x0f40,0x0f41,0x0f42,0x0f43,0x0f44,0x0f45,0x0f46,0x0f47,
+ 0x0f48,0x0f49,0x0f4a,0x0f4b,0x0f4c,0x0f4d,0x0f4e,0x0f4f,
+ 0x0f50,0x0f51,0x0f52,0x0f53,0x0f54,0x0f55,0x0f56,0x0f57,
+ 0x0f58,0x0f59,0x0f5a,0x0f5b,0x0f5c,0x0f5d,0x0f5e,0x0f5f,
+ 0x0f60,0x0f61,0x0f62,0x0f63,0x0f64,0x0f65,0x0f66,0x0f67,
+ 0x0f68,0x0f69,0x0f6a,0x0f6b,0x0f6c,0x0f6d,0x0f6e,0x0f6f,
+ 0x0f70,0x0f71,0x0f72,0x0f73,0x0f74,0x0f75,0x0f76,0x0f77,
+ 0x0f78,0x0f79,0x0f7a,0x0f7b,0x0f7c,0x0f7d,0x0f7e,0x0f7f,
+ 0x0f80,0x0f81,0x0f82,0x0f83,0x0f84,0x0f85,0x0f86,0x0f87,
+ 0x0f88,0x0f89,0x0f8a,0x0f8b,0x0f8c,0x0f8d,0x0f8e,0x0f8f,
+ 0x0f90,0x0f91,0x0f92,0x0f93,0x0f94,0x0f95,0x0f96,0x0f97,
+ 0x0f98,0x0f99,0x0f9a,0x0f9b,0x0f9c,0x0f9d,0x0f9e,0x0f9f,
+ 0x0fa0,0x0fa1,0x0fa2,0x0fa3,0x0fa4,0x0fa5,0x0fa6,0x0fa7,
+ 0x0fa8,0x0fa9,0x0faa,0x0fab,0x0fac,0x0fad,0x0fae,0x0faf,
+ 0x0fb0,0x0fb1,0x0fb2,0x0fb3,0x0fb4,0x0fb5,0x0fb6,0x0fb7,
+ 0x0fb8,0x0fb9,0x0fba,0x0fbb,0x0fbc,0x0fbd,0x0fbe,0x0fbf,
+ 0x0fc0,0x0fc1,0x0fc2,0x0fc3,0x0fc4,0x0fc5,0x0fc6,0x0fc7,
+ 0x0fc8,0x0fc9,0x0fca,0x0fcb,0x0fcc,0x0fcd,0x0fce,0x0fcf,
+ 0x0fd0,0x0fd1,0x0fd2,0x0fd3,0x0fd4,0x0fd5,0x0fd6,0x0fd7,
+ 0x0fd8,0x0fd9,0x0fda,0x0fdb,0x0fdc,0x0fdd,0x0fde,0x0fdf,
+ 0x0fe0,0x0fe1,0x0fe2,0x0fe3,0x0fe4,0x0fe5,0x0fe6,0x0fe7,
+ 0x0fe8,0x0fe9,0x0fea,0x0feb,0x0fec,0x0fed,0x0fee,0x0fef,
+ 0x0ff0,0x0ff1,0x0ff2,0x0ff3,0x0ff4,0x0ff5,0x0ff6,0x0ff7,
+ 0x0ff8,0x0ff9,0x0ffa,0x0ffb,0x0ffc,0x0ffd,0x0ffe,0x0fff,
+ 0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007,
+ 0x1008,0x1009,0x100a,0x100b,0x100c,0x100d,0x100e,0x100f,
+ 0x1010,0x1011,0x1012,0x1013,0x1014,0x1015,0x1016,0x1017,
+ 0x1018,0x1019,0x101a,0x101b,0x101c,0x101d,0x101e,0x101f,
+ 0x1020,0x1021,0x1022,0x1023,0x1024,0x1025,0x1026,0x1027,
+ 0x1028,0x1029,0x102a,0x102b,0x102c,0x102d,0x102e,0x102f,
+ 0x1030,0x1031,0x1032,0x1033,0x1034,0x1035,0x1036,0x1037,
+ 0x1038,0x1039,0x103a,0x103b,0x103c,0x103d,0x103e,0x103f,
+ 0x1040,0x1041,0x1042,0x1043,0x1044,0x1045,0x1046,0x1047,
+ 0x1048,0x1049,0x104a,0x104b,0x104c,0x104d,0x104e,0x104f,
+ 0x1050,0x1051,0x1052,0x1053,0x1054,0x1055,0x1056,0x1057,
+ 0x1058,0x1059,0x105a,0x105b,0x105c,0x105d,0x105e,0x105f,
+ 0x1060,0x1061,0x1062,0x1063,0x1064,0x1065,0x1066,0x1067,
+ 0x1068,0x1069,0x106a,0x106b,0x106c,0x106d,0x106e,0x106f,
+ 0x1070,0x1071,0x1072,0x1073,0x1074,0x1075,0x1076,0x1077,
+ 0x1078,0x1079,0x107a,0x107b,0x107c,0x107d,0x107e,0x107f,
+ 0x1080,0x1081,0x1082,0x1083,0x1084,0x1085,0x1086,0x1087,
+ 0x1088,0x1089,0x108a,0x108b,0x108c,0x108d,0x108e,0x108f,
+ 0x1090,0x1091,0x1092,0x1093,0x1094,0x1095,0x1096,0x1097,
+ 0x1098,0x1099,0x109a,0x109b,0x109c,0x109d,0x109e,0x109f,
+ 0x10a0,0x10a1,0x10a2,0x10a3,0x10a4,0x10a5,0x10a6,0x10a7,
+ 0x10a8,0x10a9,0x10aa,0x10ab,0x10ac,0x10ad,0x10ae,0x10af,
+ 0x10b0,0x10b1,0x10b2,0x10b3,0x10b4,0x10b5,0x10b6,0x10b7,
+ 0x10b8,0x10b9,0x10ba,0x10bb,0x10bc,0x10bd,0x10be,0x10bf,
+ 0x10c0,0x10c1,0x10c2,0x10c3,0x10c4,0x10c5,0x10c6,0x10c7,
+ 0x10c8,0x10c9,0x10ca,0x10cb,0x10cc,0x10cd,0x10ce,0x10cf,
+ 0x10d0,0x10d1,0x10d2,0x10d3,0x10d4,0x10d5,0x10d6,0x10d7,
+ 0x10d8,0x10d9,0x10da,0x10db,0x10dc,0x10dd,0x10de,0x10df,
+ 0x10e0,0x10e1,0x10e2,0x10e3,0x10e4,0x10e5,0x10e6,0x10e7,
+ 0x10e8,0x10e9,0x10ea,0x10eb,0x10ec,0x10ed,0x10ee,0x10ef,
+ 0x10f0,0x10f1,0x10f2,0x10f3,0x10f4,0x10f5,0x10f6,0x10f7,
+ 0x10f8,0x10f9,0x10fa,0x10fb,0x10fc,0x10fd,0x10fe,0x10ff,
+ 0x1100,0x1101,0x1102,0x1103,0x1104,0x1105,0x1106,0x1107,
+ 0x1108,0x1109,0x110a,0x110b,0x110c,0x110d,0x110e,0x110f,
+ 0x1110,0x1111,0x1112,0x1113,0x1114,0x1115,0x1116,0x1117,
+ 0x1118,0x1119,0x111a,0x111b,0x111c,0x111d,0x111e,0x111f,
+ 0x1120,0x1121,0x1122,0x1123,0x1124,0x1125,0x1126,0x1127,
+ 0x1128,0x1129,0x112a,0x112b,0x112c,0x112d,0x112e,0x112f,
+ 0x1130,0x1131,0x1132,0x1133,0x1134,0x1135,0x1136,0x1137,
+ 0x1138,0x1139,0x113a,0x113b,0x113c,0x113d,0x113e,0x113f,
+ 0x1140,0x1141,0x1142,0x1143,0x1144,0x1145,0x1146,0x1147,
+ 0x1148,0x1149,0x114a,0x114b,0x114c,0x114d,0x114e,0x114f,
+ 0x1150,0x1151,0x1152,0x1153,0x1154,0x1155,0x1156,0x1157,
+ 0x1158,0x1159,0x115a,0x115b,0x115c,0x115d,0x115e,0x115f,
+ 0x1160,0x1161,0x1162,0x1163,0x1164,0x1165,0x1166,0x1167,
+ 0x1168,0x1169,0x116a,0x116b,0x116c,0x116d,0x116e,0x116f,
+ 0x1170,0x1171,0x1172,0x1173,0x1174,0x1175,0x1176,0x1177,
+ 0x1178,0x1179,0x117a,0x117b,0x117c,0x117d,0x117e,0x117f,
+ 0x1180,0x1181,0x1182,0x1183,0x1184,0x1185,0x1186,0x1187,
+ 0x1188,0x1189,0x118a,0x118b,0x118c,0x118d,0x118e,0x118f,
+ 0x1190,0x1191,0x1192,0x1193,0x1194,0x1195,0x1196,0x1197,
+ 0x1198,0x1199,0x119a,0x119b,0x119c,0x119d,0x119e,0x119f,
+ 0x11a0,0x11a1,0x11a2,0x11a3,0x11a4,0x11a5,0x11a6,0x11a7,
+ 0x11a8,0x11a9,0x11aa,0x11ab,0x11ac,0x11ad,0x11ae,0x11af,
+ 0x11b0,0x11b1,0x11b2,0x11b3,0x11b4,0x11b5,0x11b6,0x11b7,
+ 0x11b8,0x11b9,0x11ba,0x11bb,0x11bc,0x11bd,0x11be,0x11bf,
+ 0x11c0,0x11c1,0x11c2,0x11c3,0x11c4,0x11c5,0x11c6,0x11c7,
+ 0x11c8,0x11c9,0x11ca,0x11cb,0x11cc,0x11cd,0x11ce,0x11cf,
+ 0x11d0,0x11d1,0x11d2,0x11d3,0x11d4,0x11d5,0x11d6,0x11d7,
+ 0x11d8,0x11d9,0x11da,0x11db,0x11dc,0x11dd,0x11de,0x11df,
+ 0x11e0,0x11e1,0x11e2,0x11e3,0x11e4,0x11e5,0x11e6,0x11e7,
+ 0x11e8,0x11e9,0x11ea,0x11eb,0x11ec,0x11ed,0x11ee,0x11ef,
+ 0x11f0,0x11f1,0x11f2,0x11f3,0x11f4,0x11f5,0x11f6,0x11f7,
+ 0x11f8,0x11f9,0x11fa,0x11fb,0x11fc,0x11fd,0x11fe,0x11ff,
+ 0x1200,0x1201,0x1202,0x1203,0x1204,0x1205,0x1206,0x1207,
+ 0x1208,0x1209,0x120a,0x120b,0x120c,0x120d,0x120e,0x120f,
+ 0x1210,0x1211,0x1212,0x1213,0x1214,0x1215,0x1216,0x1217,
+ 0x1218,0x1219,0x121a,0x121b,0x121c,0x121d,0x121e,0x121f,
+ 0x1220,0x1221,0x1222,0x1223,0x1224,0x1225,0x1226,0x1227,
+ 0x1228,0x1229,0x122a,0x122b,0x122c,0x122d,0x122e,0x122f,
+ 0x1230,0x1231,0x1232,0x1233,0x1234,0x1235,0x1236,0x1237,
+ 0x1238,0x1239,0x123a,0x123b,0x123c,0x123d,0x123e,0x123f,
+ 0x1240,0x1241,0x1242,0x1243,0x1244,0x1245,0x1246,0x1247,
+ 0x1248,0x1249,0x124a,0x124b,0x124c,0x124d,0x124e,0x124f,
+ 0x1250,0x1251,0x1252,0x1253,0x1254,0x1255,0x1256,0x1257,
+ 0x1258,0x1259,0x125a,0x125b,0x125c,0x125d,0x125e,0x125f,
+ 0x1260,0x1261,0x1262,0x1263,0x1264,0x1265,0x1266,0x1267,
+ 0x1268,0x1269,0x126a,0x126b,0x126c,0x126d,0x126e,0x126f,
+ 0x1270,0x1271,0x1272,0x1273,0x1274,0x1275,0x1276,0x1277,
+ 0x1278,0x1279,0x127a,0x127b,0x127c,0x127d,0x127e,0x127f,
+ 0x1280,0x1281,0x1282,0x1283,0x1284,0x1285,0x1286,0x1287,
+ 0x1288,0x1289,0x128a,0x128b,0x128c,0x128d,0x128e,0x128f,
+ 0x1290,0x1291,0x1292,0x1293,0x1294,0x1295,0x1296,0x1297,
+ 0x1298,0x1299,0x129a,0x129b,0x129c,0x129d,0x129e,0x129f,
+ 0x12a0,0x12a1,0x12a2,0x12a3,0x12a4,0x12a5,0x12a6,0x12a7,
+ 0x12a8,0x12a9,0x12aa,0x12ab,0x12ac,0x12ad,0x12ae,0x12af,
+ 0x12b0,0x12b1,0x12b2,0x12b3,0x12b4,0x12b5,0x12b6,0x12b7,
+ 0x12b8,0x12b9,0x12ba,0x12bb,0x12bc,0x12bd,0x12be,0x12bf,
+ 0x12c0,0x12c1,0x12c2,0x12c3,0x12c4,0x12c5,0x12c6,0x12c7,
+ 0x12c8,0x12c9,0x12ca,0x12cb,0x12cc,0x12cd,0x12ce,0x12cf,
+ 0x12d0,0x12d1,0x12d2,0x12d3,0x12d4,0x12d5,0x12d6,0x12d7,
+ 0x12d8,0x12d9,0x12da,0x12db,0x12dc,0x12dd,0x12de,0x12df,
+ 0x12e0,0x12e1,0x12e2,0x12e3,0x12e4,0x12e5,0x12e6,0x12e7,
+ 0x12e8,0x12e9,0x12ea,0x12eb,0x12ec,0x12ed,0x12ee,0x12ef,
+ 0x12f0,0x12f1,0x12f2,0x12f3,0x12f4,0x12f5,0x12f6,0x12f7,
+ 0x12f8,0x12f9,0x12fa,0x12fb,0x12fc,0x12fd,0x12fe,0x12ff,
+ 0x1300,0x1301,0x1302,0x1303,0x1304,0x1305,0x1306,0x1307,
+ 0x1308,0x1309,0x130a,0x130b,0x130c,0x130d,0x130e,0x130f,
+ 0x1310,0x1311,0x1312,0x1313,0x1314,0x1315,0x1316,0x1317,
+ 0x1318,0x1319,0x131a,0x131b,0x131c,0x131d,0x131e,0x131f,
+ 0x1320,0x1321,0x1322,0x1323,0x1324,0x1325,0x1326,0x1327,
+ 0x1328,0x1329,0x132a,0x132b,0x132c,0x132d,0x132e,0x132f,
+ 0x1330,0x1331,0x1332,0x1333,0x1334,0x1335,0x1336,0x1337,
+ 0x1338,0x1339,0x133a,0x133b,0x133c,0x133d,0x133e,0x133f,
+ 0x1340,0x1341,0x1342,0x1343,0x1344,0x1345,0x1346,0x1347,
+ 0x1348,0x1349,0x134a,0x134b,0x134c,0x134d,0x134e,0x134f,
+ 0x1350,0x1351,0x1352,0x1353,0x1354,0x1355,0x1356,0x1357,
+ 0x1358,0x1359,0x135a,0x135b,0x135c,0x135d,0x135e,0x135f,
+ 0x1360,0x1361,0x1362,0x1363,0x1364,0x1365,0x1366,0x1367,
+ 0x1368,0x1369,0x136a,0x136b,0x136c,0x136d,0x136e,0x136f,
+ 0x1370,0x1371,0x1372,0x1373,0x1374,0x1375,0x1376,0x1377,
+ 0x1378,0x1379,0x137a,0x137b,0x137c,0x137d,0x137e,0x137f,
+ 0x1380,0x1381,0x1382,0x1383,0x1384,0x1385,0x1386,0x1387,
+ 0x1388,0x1389,0x138a,0x138b,0x138c,0x138d,0x138e,0x138f,
+ 0x1390,0x1391,0x1392,0x1393,0x1394,0x1395,0x1396,0x1397,
+ 0x1398,0x1399,0x139a,0x139b,0x139c,0x139d,0x139e,0x139f,
+ 0x13a0,0x13a1,0x13a2,0x13a3,0x13a4,0x13a5,0x13a6,0x13a7,
+ 0x13a8,0x13a9,0x13aa,0x13ab,0x13ac,0x13ad,0x13ae,0x13af,
+ 0x13b0,0x13b1,0x13b2,0x13b3,0x13b4,0x13b5,0x13b6,0x13b7,
+ 0x13b8,0x13b9,0x13ba,0x13bb,0x13bc,0x13bd,0x13be,0x13bf,
+ 0x13c0,0x13c1,0x13c2,0x13c3,0x13c4,0x13c5,0x13c6,0x13c7,
+ 0x13c8,0x13c9,0x13ca,0x13cb,0x13cc,0x13cd,0x13ce,0x13cf,
+ 0x13d0,0x13d1,0x13d2,0x13d3,0x13d4,0x13d5,0x13d6,0x13d7,
+ 0x13d8,0x13d9,0x13da,0x13db,0x13dc,0x13dd,0x13de,0x13df,
+ 0x13e0,0x13e1,0x13e2,0x13e3,0x13e4,0x13e5,0x13e6,0x13e7,
+ 0x13e8,0x13e9,0x13ea,0x13eb,0x13ec,0x13ed,0x13ee,0x13ef,
+ 0x13f0,0x13f1,0x13f2,0x13f3,0x13f4,0x13f5,0x13f6,0x13f7,
+ 0x13f8,0x13f9,0x13fa,0x13fb,0x13fc,0x13fd,0x13fe,0x13ff,
+ 0x1400,0x1401,0x1402,0x1403,0x1404,0x1405,0x1406,0x1407,
+ 0x1408,0x1409,0x140a,0x140b,0x140c,0x140d,0x140e,0x140f,
+ 0x1410,0x1411,0x1412,0x1413,0x1414,0x1415,0x1416,0x1417,
+ 0x1418,0x1419,0x141a,0x141b,0x141c,0x141d,0x141e,0x141f,
+ 0x1420,0x1421,0x1422,0x1423,0x1424,0x1425,0x1426,0x1427,
+ 0x1428,0x1429,0x142a,0x142b,0x142c,0x142d,0x142e,0x142f,
+ 0x1430,0x1431,0x1432,0x1433,0x1434,0x1435,0x1436,0x1437,
+ 0x1438,0x1439,0x143a,0x143b,0x143c,0x143d,0x143e,0x143f,
+ 0x1440,0x1441,0x1442,0x1443,0x1444,0x1445,0x1446,0x1447,
+ 0x1448,0x1449,0x144a,0x144b,0x144c,0x144d,0x144e,0x144f,
+ 0x1450,0x1451,0x1452,0x1453,0x1454,0x1455,0x1456,0x1457,
+ 0x1458,0x1459,0x145a,0x145b,0x145c,0x145d,0x145e,0x145f,
+ 0x1460,0x1461,0x1462,0x1463,0x1464,0x1465,0x1466,0x1467,
+ 0x1468,0x1469,0x146a,0x146b,0x146c,0x146d,0x146e,0x146f,
+ 0x1470,0x1471,0x1472,0x1473,0x1474,0x1475,0x1476,0x1477,
+ 0x1478,0x1479,0x147a,0x147b,0x147c,0x147d,0x147e,0x147f,
+ 0x1480,0x1481,0x1482,0x1483,0x1484,0x1485,0x1486,0x1487,
+ 0x1488,0x1489,0x148a,0x148b,0x148c,0x148d,0x148e,0x148f,
+ 0x1490,0x1491,0x1492,0x1493,0x1494,0x1495,0x1496,0x1497,
+ 0x1498,0x1499,0x149a,0x149b,0x149c,0x149d,0x149e,0x149f,
+ 0x14a0,0x14a1,0x14a2,0x14a3,0x14a4,0x14a5,0x14a6,0x14a7,
+ 0x14a8,0x14a9,0x14aa,0x14ab,0x14ac,0x14ad,0x14ae,0x14af,
+ 0x14b0,0x14b1,0x14b2,0x14b3,0x14b4,0x14b5,0x14b6,0x14b7,
+ 0x14b8,0x14b9,0x14ba,0x14bb,0x14bc,0x14bd,0x14be,0x14bf,
+ 0x14c0,0x14c1,0x14c2,0x14c3,0x14c4,0x14c5,0x14c6,0x14c7,
+ 0x14c8,0x14c9,0x14ca,0x14cb,0x14cc,0x14cd,0x14ce,0x14cf,
+ 0x14d0,0x14d1,0x14d2,0x14d3,0x14d4,0x14d5,0x14d6,0x14d7,
+ 0x14d8,0x14d9,0x14da,0x14db,0x14dc,0x14dd,0x14de,0x14df,
+ 0x14e0,0x14e1,0x14e2,0x14e3,0x14e4,0x14e5,0x14e6,0x14e7,
+ 0x14e8,0x14e9,0x14ea,0x14eb,0x14ec,0x14ed,0x14ee,0x14ef,
+ 0x14f0,0x14f1,0x14f2,0x14f3,0x14f4,0x14f5,0x14f6,0x14f7,
+ 0x14f8,0x14f9,0x14fa,0x14fb,0x14fc,0x14fd,0x14fe,0x14ff,
+ 0x1500,0x1501,0x1502,0x1503,0x1504,0x1505,0x1506,0x1507,
+ 0x1508,0x1509,0x150a,0x150b,0x150c,0x150d,0x150e,0x150f,
+ 0x1510,0x1511,0x1512,0x1513,0x1514,0x1515,0x1516,0x1517,
+ 0x1518,0x1519,0x151a,0x151b,0x151c,0x151d,0x151e,0x151f,
+ 0x1520,0x1521,0x1522,0x1523,0x1524,0x1525,0x1526,0x1527,
+ 0x1528,0x1529,0x152a,0x152b,0x152c,0x152d,0x152e,0x152f,
+ 0x1530,0x1531,0x1532,0x1533,0x1534,0x1535,0x1536,0x1537,
+ 0x1538,0x1539,0x153a,0x153b,0x153c,0x153d,0x153e,0x153f,
+ 0x1540,0x1541,0x1542,0x1543,0x1544,0x1545,0x1546,0x1547,
+ 0x1548,0x1549,0x154a,0x154b,0x154c,0x154d,0x154e,0x154f,
+ 0x1550,0x1551,0x1552,0x1553,0x1554,0x1555,0x1556,0x1557,
+ 0x1558,0x1559,0x155a,0x155b,0x155c,0x155d,0x155e,0x155f,
+ 0x1560,0x1561,0x1562,0x1563,0x1564,0x1565,0x1566,0x1567,
+ 0x1568,0x1569,0x156a,0x156b,0x156c,0x156d,0x156e,0x156f,
+ 0x1570,0x1571,0x1572,0x1573,0x1574,0x1575,0x1576,0x1577,
+ 0x1578,0x1579,0x157a,0x157b,0x157c,0x157d,0x157e,0x157f,
+ 0x1580,0x1581,0x1582,0x1583,0x1584,0x1585,0x1586,0x1587,
+ 0x1588,0x1589,0x158a,0x158b,0x158c,0x158d,0x158e,0x158f,
+ 0x1590,0x1591,0x1592,0x1593,0x1594,0x1595,0x1596,0x1597,
+ 0x1598,0x1599,0x159a,0x159b,0x159c,0x159d,0x159e,0x159f,
+ 0x15a0,0x15a1,0x15a2,0x15a3,0x15a4,0x15a5,0x15a6,0x15a7,
+ 0x15a8,0x15a9,0x15aa,0x15ab,0x15ac,0x15ad,0x15ae,0x15af,
+ 0x15b0,0x15b1,0x15b2,0x15b3,0x15b4,0x15b5,0x15b6,0x15b7,
+ 0x15b8,0x15b9,0x15ba,0x15bb,0x15bc,0x15bd,0x15be,0x15bf,
+ 0x15c0,0x15c1,0x15c2,0x15c3,0x15c4,0x15c5,0x15c6,0x15c7,
+ 0x15c8,0x15c9,0x15ca,0x15cb,0x15cc,0x15cd,0x15ce,0x15cf,
+ 0x15d0,0x15d1,0x15d2,0x15d3,0x15d4,0x15d5,0x15d6,0x15d7,
+ 0x15d8,0x15d9,0x15da,0x15db,0x15dc,0x15dd,0x15de,0x15df,
+ 0x15e0,0x15e1,0x15e2,0x15e3,0x15e4,0x15e5,0x15e6,0x15e7,
+ 0x15e8,0x15e9,0x15ea,0x15eb,0x15ec,0x15ed,0x15ee,0x15ef,
+ 0x15f0,0x15f1,0x15f2,0x15f3,0x15f4,0x15f5,0x15f6,0x15f7,
+ 0x15f8,0x15f9,0x15fa,0x15fb,0x15fc,0x15fd,0x15fe,0x15ff,
+ 0x1600,0x1601,0x1602,0x1603,0x1604,0x1605,0x1606,0x1607,
+ 0x1608,0x1609,0x160a,0x160b,0x160c,0x160d,0x160e,0x160f,
+ 0x1610,0x1611,0x1612,0x1613,0x1614,0x1615,0x1616,0x1617,
+ 0x1618,0x1619,0x161a,0x161b,0x161c,0x161d,0x161e,0x161f,
+ 0x1620,0x1621,0x1622,0x1623,0x1624,0x1625,0x1626,0x1627,
+ 0x1628,0x1629,0x162a,0x162b,0x162c,0x162d,0x162e,0x162f,
+ 0x1630,0x1631,0x1632,0x1633,0x1634,0x1635,0x1636,0x1637,
+ 0x1638,0x1639,0x163a,0x163b,0x163c,0x163d,0x163e,0x163f,
+ 0x1640,0x1641,0x1642,0x1643,0x1644,0x1645,0x1646,0x1647,
+ 0x1648,0x1649,0x164a,0x164b,0x164c,0x164d,0x164e,0x164f,
+ 0x1650,0x1651,0x1652,0x1653,0x1654,0x1655,0x1656,0x1657,
+ 0x1658,0x1659,0x165a,0x165b,0x165c,0x165d,0x165e,0x165f,
+ 0x1660,0x1661,0x1662,0x1663,0x1664,0x1665,0x1666,0x1667,
+ 0x1668,0x1669,0x166a,0x166b,0x166c,0x166d,0x166e,0x166f,
+ 0x1670,0x1671,0x1672,0x1673,0x1674,0x1675,0x1676,0x1677,
+ 0x1678,0x1679,0x167a,0x167b,0x167c,0x167d,0x167e,0x167f,
+ 0x1680,0x1681,0x1682,0x1683,0x1684,0x1685,0x1686,0x1687,
+ 0x1688,0x1689,0x168a,0x168b,0x168c,0x168d,0x168e,0x168f,
+ 0x1690,0x1691,0x1692,0x1693,0x1694,0x1695,0x1696,0x1697,
+ 0x1698,0x1699,0x169a,0x169b,0x169c,0x169d,0x169e,0x169f,
+ 0x16a0,0x16a1,0x16a2,0x16a3,0x16a4,0x16a5,0x16a6,0x16a7,
+ 0x16a8,0x16a9,0x16aa,0x16ab,0x16ac,0x16ad,0x16ae,0x16af,
+ 0x16b0,0x16b1,0x16b2,0x16b3,0x16b4,0x16b5,0x16b6,0x16b7,
+ 0x16b8,0x16b9,0x16ba,0x16bb,0x16bc,0x16bd,0x16be,0x16bf,
+ 0x16c0,0x16c1,0x16c2,0x16c3,0x16c4,0x16c5,0x16c6,0x16c7,
+ 0x16c8,0x16c9,0x16ca,0x16cb,0x16cc,0x16cd,0x16ce,0x16cf,
+ 0x16d0,0x16d1,0x16d2,0x16d3,0x16d4,0x16d5,0x16d6,0x16d7,
+ 0x16d8,0x16d9,0x16da,0x16db,0x16dc,0x16dd,0x16de,0x16df,
+ 0x16e0,0x16e1,0x16e2,0x16e3,0x16e4,0x16e5,0x16e6,0x16e7,
+ 0x16e8,0x16e9,0x16ea,0x16eb,0x16ec,0x16ed,0x16ee,0x16ef,
+ 0x16f0,0x16f1,0x16f2,0x16f3,0x16f4,0x16f5,0x16f6,0x16f7,
+ 0x16f8,0x16f9,0x16fa,0x16fb,0x16fc,0x16fd,0x16fe,0x16ff,
+ 0x1700,0x1701,0x1702,0x1703,0x1704,0x1705,0x1706,0x1707,
+ 0x1708,0x1709,0x170a,0x170b,0x170c,0x170d,0x170e,0x170f,
+ 0x1710,0x1711,0x1712,0x1713,0x1714,0x1715,0x1716,0x1717,
+ 0x1718,0x1719,0x171a,0x171b,0x171c,0x171d,0x171e,0x171f,
+ 0x1720,0x1721,0x1722,0x1723,0x1724,0x1725,0x1726,0x1727,
+ 0x1728,0x1729,0x172a,0x172b,0x172c,0x172d,0x172e,0x172f,
+ 0x1730,0x1731,0x1732,0x1733,0x1734,0x1735,0x1736,0x1737,
+ 0x1738,0x1739,0x173a,0x173b,0x173c,0x173d,0x173e,0x173f,
+ 0x1740,0x1741,0x1742,0x1743,0x1744,0x1745,0x1746,0x1747,
+ 0x1748,0x1749,0x174a,0x174b,0x174c,0x174d,0x174e,0x174f,
+ 0x1750,0x1751,0x1752,0x1753,0x1754,0x1755,0x1756,0x1757,
+ 0x1758,0x1759,0x175a,0x175b,0x175c,0x175d,0x175e,0x175f,
+ 0x1760,0x1761,0x1762,0x1763,0x1764,0x1765,0x1766,0x1767,
+ 0x1768,0x1769,0x176a,0x176b,0x176c,0x176d,0x176e,0x176f,
+ 0x1770,0x1771,0x1772,0x1773,0x1774,0x1775,0x1776,0x1777,
+ 0x1778,0x1779,0x177a,0x177b,0x177c,0x177d,0x177e,0x177f,
+ 0x1780,0x1781,0x1782,0x1783,0x1784,0x1785,0x1786,0x1787,
+ 0x1788,0x1789,0x178a,0x178b,0x178c,0x178d,0x178e,0x178f,
+ 0x1790,0x1791,0x1792,0x1793,0x1794,0x1795,0x1796,0x1797,
+ 0x1798,0x1799,0x179a,0x179b,0x179c,0x179d,0x179e,0x179f,
+ 0x17a0,0x17a1,0x17a2,0x17a3,0x17a4,0x17a5,0x17a6,0x17a7,
+ 0x17a8,0x17a9,0x17aa,0x17ab,0x17ac,0x17ad,0x17ae,0x17af,
+ 0x17b0,0x17b1,0x17b2,0x17b3,0x17b4,0x17b5,0x17b6,0x17b7,
+ 0x17b8,0x17b9,0x17ba,0x17bb,0x17bc,0x17bd,0x17be,0x17bf,
+ 0x17c0,0x17c1,0x17c2,0x17c3,0x17c4,0x17c5,0x17c6,0x17c7,
+ 0x17c8,0x17c9,0x17ca,0x17cb,0x17cc,0x17cd,0x17ce,0x17cf,
+ 0x17d0,0x17d1,0x17d2,0x17d3,0x17d4,0x17d5,0x17d6,0x17d7,
+ 0x17d8,0x17d9,0x17da,0x17db,0x17dc,0x17dd,0x17de,0x17df,
+ 0x17e0,0x17e1,0x17e2,0x17e3,0x17e4,0x17e5,0x17e6,0x17e7,
+ 0x17e8,0x17e9,0x17ea,0x17eb,0x17ec,0x17ed,0x17ee,0x17ef,
+ 0x17f0,0x17f1,0x17f2,0x17f3,0x17f4,0x17f5,0x17f6,0x17f7,
+ 0x17f8,0x17f9,0x17fa,0x17fb,0x17fc,0x17fd,0x17fe,0x17ff,
+ 0x1800,0x1801,0x1802,0x1803,0x1804,0x1805,0x1806,0x1807,
+ 0x1808,0x1809,0x180a,0x180b,0x180c,0x180d,0x180e,0x180f,
+ 0x1810,0x1811,0x1812,0x1813,0x1814,0x1815,0x1816,0x1817,
+ 0x1818,0x1819,0x181a,0x181b,0x181c,0x181d,0x181e,0x181f,
+ 0x1820,0x1821,0x1822,0x1823,0x1824,0x1825,0x1826,0x1827,
+ 0x1828,0x1829,0x182a,0x182b,0x182c,0x182d,0x182e,0x182f,
+ 0x1830,0x1831,0x1832,0x1833,0x1834,0x1835,0x1836,0x1837,
+ 0x1838,0x1839,0x183a,0x183b,0x183c,0x183d,0x183e,0x183f,
+ 0x1840,0x1841,0x1842,0x1843,0x1844,0x1845,0x1846,0x1847,
+ 0x1848,0x1849,0x184a,0x184b,0x184c,0x184d,0x184e,0x184f,
+ 0x1850,0x1851,0x1852,0x1853,0x1854,0x1855,0x1856,0x1857,
+ 0x1858,0x1859,0x185a,0x185b,0x185c,0x185d,0x185e,0x185f,
+ 0x1860,0x1861,0x1862,0x1863,0x1864,0x1865,0x1866,0x1867,
+ 0x1868,0x1869,0x186a,0x186b,0x186c,0x186d,0x186e,0x186f,
+ 0x1870,0x1871,0x1872,0x1873,0x1874,0x1875,0x1876,0x1877,
+ 0x1878,0x1879,0x187a,0x187b,0x187c,0x187d,0x187e,0x187f,
+ 0x1880,0x1881,0x1882,0x1883,0x1884,0x1885,0x1886,0x1887,
+ 0x1888,0x1889,0x188a,0x188b,0x188c,0x188d,0x188e,0x188f,
+ 0x1890,0x1891,0x1892,0x1893,0x1894,0x1895,0x1896,0x1897,
+ 0x1898,0x1899,0x189a,0x189b,0x189c,0x189d,0x189e,0x189f,
+ 0x18a0,0x18a1,0x18a2,0x18a3,0x18a4,0x18a5,0x18a6,0x18a7,
+ 0x18a8,0x18a9,0x18aa,0x18ab,0x18ac,0x18ad,0x18ae,0x18af,
+ 0x18b0,0x18b1,0x18b2,0x18b3,0x18b4,0x18b5,0x18b6,0x18b7,
+ 0x18b8,0x18b9,0x18ba,0x18bb,0x18bc,0x18bd,0x18be,0x18bf,
+ 0x18c0,0x18c1,0x18c2,0x18c3,0x18c4,0x18c5,0x18c6,0x18c7,
+ 0x18c8,0x18c9,0x18ca,0x18cb,0x18cc,0x18cd,0x18ce,0x18cf,
+ 0x18d0,0x18d1,0x18d2,0x18d3,0x18d4,0x18d5,0x18d6,0x18d7,
+ 0x18d8,0x18d9,0x18da,0x18db,0x18dc,0x18dd,0x18de,0x18df,
+ 0x18e0,0x18e1,0x18e2,0x18e3,0x18e4,0x18e5,0x18e6,0x18e7,
+ 0x18e8,0x18e9,0x18ea,0x18eb,0x18ec,0x18ed,0x18ee,0x18ef,
+ 0x18f0,0x18f1,0x18f2,0x18f3,0x18f4,0x18f5,0x18f6,0x18f7,
+ 0x18f8,0x18f9,0x18fa,0x18fb,0x18fc,0x18fd,0x18fe,0x18ff,
+ 0x1900,0x1901,0x1902,0x1903,0x1904,0x1905,0x1906,0x1907,
+ 0x1908,0x1909,0x190a,0x190b,0x190c,0x190d,0x190e,0x190f,
+ 0x1910,0x1911,0x1912,0x1913,0x1914,0x1915,0x1916,0x1917,
+ 0x1918,0x1919,0x191a,0x191b,0x191c,0x191d,0x191e,0x191f,
+ 0x1920,0x1921,0x1922,0x1923,0x1924,0x1925,0x1926,0x1927,
+ 0x1928,0x1929,0x192a,0x192b,0x192c,0x192d,0x192e,0x192f,
+ 0x1930,0x1931,0x1932,0x1933,0x1934,0x1935,0x1936,0x1937,
+ 0x1938,0x1939,0x193a,0x193b,0x193c,0x193d,0x193e,0x193f,
+ 0x1940,0x1941,0x1942,0x1943,0x1944,0x1945,0x1946,0x1947,
+ 0x1948,0x1949,0x194a,0x194b,0x194c,0x194d,0x194e,0x194f,
+ 0x1950,0x1951,0x1952,0x1953,0x1954,0x1955,0x1956,0x1957,
+ 0x1958,0x1959,0x195a,0x195b,0x195c,0x195d,0x195e,0x195f,
+ 0x1960,0x1961,0x1962,0x1963,0x1964,0x1965,0x1966,0x1967,
+ 0x1968,0x1969,0x196a,0x196b,0x196c,0x196d,0x196e,0x196f,
+ 0x1970,0x1971,0x1972,0x1973,0x1974,0x1975,0x1976,0x1977,
+ 0x1978,0x1979,0x197a,0x197b,0x197c,0x197d,0x197e,0x197f,
+ 0x1980,0x1981,0x1982,0x1983,0x1984,0x1985,0x1986,0x1987,
+ 0x1988,0x1989,0x198a,0x198b,0x198c,0x198d,0x198e,0x198f,
+ 0x1990,0x1991,0x1992,0x1993,0x1994,0x1995,0x1996,0x1997,
+ 0x1998,0x1999,0x199a,0x199b,0x199c,0x199d,0x199e,0x199f,
+ 0x19a0,0x19a1,0x19a2,0x19a3,0x19a4,0x19a5,0x19a6,0x19a7,
+ 0x19a8,0x19a9,0x19aa,0x19ab,0x19ac,0x19ad,0x19ae,0x19af,
+ 0x19b0,0x19b1,0x19b2,0x19b3,0x19b4,0x19b5,0x19b6,0x19b7,
+ 0x19b8,0x19b9,0x19ba,0x19bb,0x19bc,0x19bd,0x19be,0x19bf,
+ 0x19c0,0x19c1,0x19c2,0x19c3,0x19c4,0x19c5,0x19c6,0x19c7,
+ 0x19c8,0x19c9,0x19ca,0x19cb,0x19cc,0x19cd,0x19ce,0x19cf,
+ 0x19d0,0x19d1,0x19d2,0x19d3,0x19d4,0x19d5,0x19d6,0x19d7,
+ 0x19d8,0x19d9,0x19da,0x19db,0x19dc,0x19dd,0x19de,0x19df,
+ 0x19e0,0x19e1,0x19e2,0x19e3,0x19e4,0x19e5,0x19e6,0x19e7,
+ 0x19e8,0x19e9,0x19ea,0x19eb,0x19ec,0x19ed,0x19ee,0x19ef,
+ 0x19f0,0x19f1,0x19f2,0x19f3,0x19f4,0x19f5,0x19f6,0x19f7,
+ 0x19f8,0x19f9,0x19fa,0x19fb,0x19fc,0x19fd,0x19fe,0x19ff,
+ 0x1a00,0x1a01,0x1a02,0x1a03,0x1a04,0x1a05,0x1a06,0x1a07,
+ 0x1a08,0x1a09,0x1a0a,0x1a0b,0x1a0c,0x1a0d,0x1a0e,0x1a0f,
+ 0x1a10,0x1a11,0x1a12,0x1a13,0x1a14,0x1a15,0x1a16,0x1a17,
+ 0x1a18,0x1a19,0x1a1a,0x1a1b,0x1a1c,0x1a1d,0x1a1e,0x1a1f,
+ 0x1a20,0x1a21,0x1a22,0x1a23,0x1a24,0x1a25,0x1a26,0x1a27,
+ 0x1a28,0x1a29,0x1a2a,0x1a2b,0x1a2c,0x1a2d,0x1a2e,0x1a2f,
+ 0x1a30,0x1a31,0x1a32,0x1a33,0x1a34,0x1a35,0x1a36,0x1a37,
+ 0x1a38,0x1a39,0x1a3a,0x1a3b,0x1a3c,0x1a3d,0x1a3e,0x1a3f,
+ 0x1a40,0x1a41,0x1a42,0x1a43,0x1a44,0x1a45,0x1a46,0x1a47,
+ 0x1a48,0x1a49,0x1a4a,0x1a4b,0x1a4c,0x1a4d,0x1a4e,0x1a4f,
+ 0x1a50,0x1a51,0x1a52,0x1a53,0x1a54,0x1a55,0x1a56,0x1a57,
+ 0x1a58,0x1a59,0x1a5a,0x1a5b,0x1a5c,0x1a5d,0x1a5e,0x1a5f,
+ 0x1a60,0x1a61,0x1a62,0x1a63,0x1a64,0x1a65,0x1a66,0x1a67,
+ 0x1a68,0x1a69,0x1a6a,0x1a6b,0x1a6c,0x1a6d,0x1a6e,0x1a6f,
+ 0x1a70,0x1a71,0x1a72,0x1a73,0x1a74,0x1a75,0x1a76,0x1a77,
+ 0x1a78,0x1a79,0x1a7a,0x1a7b,0x1a7c,0x1a7d,0x1a7e,0x1a7f,
+ 0x1a80,0x1a81,0x1a82,0x1a83,0x1a84,0x1a85,0x1a86,0x1a87,
+ 0x1a88,0x1a89,0x1a8a,0x1a8b,0x1a8c,0x1a8d,0x1a8e,0x1a8f,
+ 0x1a90,0x1a91,0x1a92,0x1a93,0x1a94,0x1a95,0x1a96,0x1a97,
+ 0x1a98,0x1a99,0x1a9a,0x1a9b,0x1a9c,0x1a9d,0x1a9e,0x1a9f,
+ 0x1aa0,0x1aa1,0x1aa2,0x1aa3,0x1aa4,0x1aa5,0x1aa6,0x1aa7,
+ 0x1aa8,0x1aa9,0x1aaa,0x1aab,0x1aac,0x1aad,0x1aae,0x1aaf,
+ 0x1ab0,0x1ab1,0x1ab2,0x1ab3,0x1ab4,0x1ab5,0x1ab6,0x1ab7,
+ 0x1ab8,0x1ab9,0x1aba,0x1abb,0x1abc,0x1abd,0x1abe,0x1abf,
+ 0x1ac0,0x1ac1,0x1ac2,0x1ac3,0x1ac4,0x1ac5,0x1ac6,0x1ac7,
+ 0x1ac8,0x1ac9,0x1aca,0x1acb,0x1acc,0x1acd,0x1ace,0x1acf,
+ 0x1ad0,0x1ad1,0x1ad2,0x1ad3,0x1ad4,0x1ad5,0x1ad6,0x1ad7,
+ 0x1ad8,0x1ad9,0x1ada,0x1adb,0x1adc,0x1add,0x1ade,0x1adf,
+ 0x1ae0,0x1ae1,0x1ae2,0x1ae3,0x1ae4,0x1ae5,0x1ae6,0x1ae7,
+ 0x1ae8,0x1ae9,0x1aea,0x1aeb,0x1aec,0x1aed,0x1aee,0x1aef,
+ 0x1af0,0x1af1,0x1af2,0x1af3,0x1af4,0x1af5,0x1af6,0x1af7,
+ 0x1af8,0x1af9,0x1afa,0x1afb,0x1afc,0x1afd,0x1afe,0x1aff,
+ 0x1b00,0x1b01,0x1b02,0x1b03,0x1b04,0x1b05,0x1b06,0x1b07,
+ 0x1b08,0x1b09,0x1b0a,0x1b0b,0x1b0c,0x1b0d,0x1b0e,0x1b0f,
+ 0x1b10,0x1b11,0x1b12,0x1b13,0x1b14,0x1b15,0x1b16,0x1b17,
+ 0x1b18,0x1b19,0x1b1a,0x1b1b,0x1b1c,0x1b1d,0x1b1e,0x1b1f,
+ 0x1b20,0x1b21,0x1b22,0x1b23,0x1b24,0x1b25,0x1b26,0x1b27,
+ 0x1b28,0x1b29,0x1b2a,0x1b2b,0x1b2c,0x1b2d,0x1b2e,0x1b2f,
+ 0x1b30,0x1b31,0x1b32,0x1b33,0x1b34,0x1b35,0x1b36,0x1b37,
+ 0x1b38,0x1b39,0x1b3a,0x1b3b,0x1b3c,0x1b3d,0x1b3e,0x1b3f,
+ 0x1b40,0x1b41,0x1b42,0x1b43,0x1b44,0x1b45,0x1b46,0x1b47,
+ 0x1b48,0x1b49,0x1b4a,0x1b4b,0x1b4c,0x1b4d,0x1b4e,0x1b4f,
+ 0x1b50,0x1b51,0x1b52,0x1b53,0x1b54,0x1b55,0x1b56,0x1b57,
+ 0x1b58,0x1b59,0x1b5a,0x1b5b,0x1b5c,0x1b5d,0x1b5e,0x1b5f,
+ 0x1b60,0x1b61,0x1b62,0x1b63,0x1b64,0x1b65,0x1b66,0x1b67,
+ 0x1b68,0x1b69,0x1b6a,0x1b6b,0x1b6c,0x1b6d,0x1b6e,0x1b6f,
+ 0x1b70,0x1b71,0x1b72,0x1b73,0x1b74,0x1b75,0x1b76,0x1b77,
+ 0x1b78,0x1b79,0x1b7a,0x1b7b,0x1b7c,0x1b7d,0x1b7e,0x1b7f,
+ 0x1b80,0x1b81,0x1b82,0x1b83,0x1b84,0x1b85,0x1b86,0x1b87,
+ 0x1b88,0x1b89,0x1b8a,0x1b8b,0x1b8c,0x1b8d,0x1b8e,0x1b8f,
+ 0x1b90,0x1b91,0x1b92,0x1b93,0x1b94,0x1b95,0x1b96,0x1b97,
+ 0x1b98,0x1b99,0x1b9a,0x1b9b,0x1b9c,0x1b9d,0x1b9e,0x1b9f,
+ 0x1ba0,0x1ba1,0x1ba2,0x1ba3,0x1ba4,0x1ba5,0x1ba6,0x1ba7,
+ 0x1ba8,0x1ba9,0x1baa,0x1bab,0x1bac,0x1bad,0x1bae,0x1baf,
+ 0x1bb0,0x1bb1,0x1bb2,0x1bb3,0x1bb4,0x1bb5,0x1bb6,0x1bb7,
+ 0x1bb8,0x1bb9,0x1bba,0x1bbb,0x1bbc,0x1bbd,0x1bbe,0x1bbf,
+ 0x1bc0,0x1bc1,0x1bc2,0x1bc3,0x1bc4,0x1bc5,0x1bc6,0x1bc7,
+ 0x1bc8,0x1bc9,0x1bca,0x1bcb,0x1bcc,0x1bcd,0x1bce,0x1bcf,
+ 0x1bd0,0x1bd1,0x1bd2,0x1bd3,0x1bd4,0x1bd5,0x1bd6,0x1bd7,
+ 0x1bd8,0x1bd9,0x1bda,0x1bdb,0x1bdc,0x1bdd,0x1bde,0x1bdf,
+ 0x1be0,0x1be1,0x1be2,0x1be3,0x1be4,0x1be5,0x1be6,0x1be7,
+ 0x1be8,0x1be9,0x1bea,0x1beb,0x1bec,0x1bed,0x1bee,0x1bef,
+ 0x1bf0,0x1bf1,0x1bf2,0x1bf3,0x1bf4,0x1bf5,0x1bf6,0x1bf7,
+ 0x1bf8,0x1bf9,0x1bfa,0x1bfb,0x1bfc,0x1bfd,0x1bfe,0x1bff,
+ 0x1c00,0x1c01,0x1c02,0x1c03,0x1c04,0x1c05,0x1c06,0x1c07,
+ 0x1c08,0x1c09,0x1c0a,0x1c0b,0x1c0c,0x1c0d,0x1c0e,0x1c0f,
+ 0x1c10,0x1c11,0x1c12,0x1c13,0x1c14,0x1c15,0x1c16,0x1c17,
+ 0x1c18,0x1c19,0x1c1a,0x1c1b,0x1c1c,0x1c1d,0x1c1e,0x1c1f,
+ 0x1c20,0x1c21,0x1c22,0x1c23,0x1c24,0x1c25,0x1c26,0x1c27,
+ 0x1c28,0x1c29,0x1c2a,0x1c2b,0x1c2c,0x1c2d,0x1c2e,0x1c2f,
+ 0x1c30,0x1c31,0x1c32,0x1c33,0x1c34,0x1c35,0x1c36,0x1c37,
+ 0x1c38,0x1c39,0x1c3a,0x1c3b,0x1c3c,0x1c3d,0x1c3e,0x1c3f,
+ 0x1c40,0x1c41,0x1c42,0x1c43,0x1c44,0x1c45,0x1c46,0x1c47,
+ 0x1c48,0x1c49,0x1c4a,0x1c4b,0x1c4c,0x1c4d,0x1c4e,0x1c4f,
+ 0x1c50,0x1c51,0x1c52,0x1c53,0x1c54,0x1c55,0x1c56,0x1c57,
+ 0x1c58,0x1c59,0x1c5a,0x1c5b,0x1c5c,0x1c5d,0x1c5e,0x1c5f,
+ 0x1c60,0x1c61,0x1c62,0x1c63,0x1c64,0x1c65,0x1c66,0x1c67,
+ 0x1c68,0x1c69,0x1c6a,0x1c6b,0x1c6c,0x1c6d,0x1c6e,0x1c6f,
+ 0x1c70,0x1c71,0x1c72,0x1c73,0x1c74,0x1c75,0x1c76,0x1c77,
+ 0x1c78,0x1c79,0x1c7a,0x1c7b,0x1c7c,0x1c7d,0x1c7e,0x1c7f,
+ 0x1c80,0x1c81,0x1c82,0x1c83,0x1c84,0x1c85,0x1c86,0x1c87,
+ 0x1c88,0x1c89,0x1c8a,0x1c8b,0x1c8c,0x1c8d,0x1c8e,0x1c8f,
+ 0x1c90,0x1c91,0x1c92,0x1c93,0x1c94,0x1c95,0x1c96,0x1c97,
+ 0x1c98,0x1c99,0x1c9a,0x1c9b,0x1c9c,0x1c9d,0x1c9e,0x1c9f,
+ 0x1ca0,0x1ca1,0x1ca2,0x1ca3,0x1ca4,0x1ca5,0x1ca6,0x1ca7,
+ 0x1ca8,0x1ca9,0x1caa,0x1cab,0x1cac,0x1cad,0x1cae,0x1caf,
+ 0x1cb0,0x1cb1,0x1cb2,0x1cb3,0x1cb4,0x1cb5,0x1cb6,0x1cb7,
+ 0x1cb8,0x1cb9,0x1cba,0x1cbb,0x1cbc,0x1cbd,0x1cbe,0x1cbf,
+ 0x1cc0,0x1cc1,0x1cc2,0x1cc3,0x1cc4,0x1cc5,0x1cc6,0x1cc7,
+ 0x1cc8,0x1cc9,0x1cca,0x1ccb,0x1ccc,0x1ccd,0x1cce,0x1ccf,
+ 0x1cd0,0x1cd1,0x1cd2,0x1cd3,0x1cd4,0x1cd5,0x1cd6,0x1cd7,
+ 0x1cd8,0x1cd9,0x1cda,0x1cdb,0x1cdc,0x1cdd,0x1cde,0x1cdf,
+ 0x1ce0,0x1ce1,0x1ce2,0x1ce3,0x1ce4,0x1ce5,0x1ce6,0x1ce7,
+ 0x1ce8,0x1ce9,0x1cea,0x1ceb,0x1cec,0x1ced,0x1cee,0x1cef,
+ 0x1cf0,0x1cf1,0x1cf2,0x1cf3,0x1cf4,0x1cf5,0x1cf6,0x1cf7,
+ 0x1cf8,0x1cf9,0x1cfa,0x1cfb,0x1cfc,0x1cfd,0x1cfe,0x1cff,
+ 0x1d00,0x1d01,0x1d02,0x1d03,0x1d04,0x1d05,0x1d06,0x1d07,
+ 0x1d08,0x1d09,0x1d0a,0x1d0b,0x1d0c,0x1d0d,0x1d0e,0x1d0f,
+ 0x1d10,0x1d11,0x1d12,0x1d13,0x1d14,0x1d15,0x1d16,0x1d17,
+ 0x1d18,0x1d19,0x1d1a,0x1d1b,0x1d1c,0x1d1d,0x1d1e,0x1d1f,
+ 0x1d20,0x1d21,0x1d22,0x1d23,0x1d24,0x1d25,0x1d26,0x1d27,
+ 0x1d28,0x1d29,0x1d2a,0x1d2b,0x1d2c,0x1d2d,0x1d2e,0x1d2f,
+ 0x1d30,0x1d31,0x1d32,0x1d33,0x1d34,0x1d35,0x1d36,0x1d37,
+ 0x1d38,0x1d39,0x1d3a,0x1d3b,0x1d3c,0x1d3d,0x1d3e,0x1d3f,
+ 0x1d40,0x1d41,0x1d42,0x1d43,0x1d44,0x1d45,0x1d46,0x1d47,
+ 0x1d48,0x1d49,0x1d4a,0x1d4b,0x1d4c,0x1d4d,0x1d4e,0x1d4f,
+ 0x1d50,0x1d51,0x1d52,0x1d53,0x1d54,0x1d55,0x1d56,0x1d57,
+ 0x1d58,0x1d59,0x1d5a,0x1d5b,0x1d5c,0x1d5d,0x1d5e,0x1d5f,
+ 0x1d60,0x1d61,0x1d62,0x1d63,0x1d64,0x1d65,0x1d66,0x1d67,
+ 0x1d68,0x1d69,0x1d6a,0x1d6b,0x1d6c,0x1d6d,0x1d6e,0x1d6f,
+ 0x1d70,0x1d71,0x1d72,0x1d73,0x1d74,0x1d75,0x1d76,0x1d77,
+ 0x1d78,0x1d79,0x1d7a,0x1d7b,0x1d7c,0x1d7d,0x1d7e,0x1d7f,
+ 0x1d80,0x1d81,0x1d82,0x1d83,0x1d84,0x1d85,0x1d86,0x1d87,
+ 0x1d88,0x1d89,0x1d8a,0x1d8b,0x1d8c,0x1d8d,0x1d8e,0x1d8f,
+ 0x1d90,0x1d91,0x1d92,0x1d93,0x1d94,0x1d95,0x1d96,0x1d97,
+ 0x1d98,0x1d99,0x1d9a,0x1d9b,0x1d9c,0x1d9d,0x1d9e,0x1d9f,
+ 0x1da0,0x1da1,0x1da2,0x1da3,0x1da4,0x1da5,0x1da6,0x1da7,
+ 0x1da8,0x1da9,0x1daa,0x1dab,0x1dac,0x1dad,0x1dae,0x1daf,
+ 0x1db0,0x1db1,0x1db2,0x1db3,0x1db4,0x1db5,0x1db6,0x1db7,
+ 0x1db8,0x1db9,0x1dba,0x1dbb,0x1dbc,0x1dbd,0x1dbe,0x1dbf,
+ 0x1dc0,0x1dc1,0x1dc2,0x1dc3,0x1dc4,0x1dc5,0x1dc6,0x1dc7,
+ 0x1dc8,0x1dc9,0x1dca,0x1dcb,0x1dcc,0x1dcd,0x1dce,0x1dcf,
+ 0x1dd0,0x1dd1,0x1dd2,0x1dd3,0x1dd4,0x1dd5,0x1dd6,0x1dd7,
+ 0x1dd8,0x1dd9,0x1dda,0x1ddb,0x1ddc,0x1ddd,0x1dde,0x1ddf,
+ 0x1de0,0x1de1,0x1de2,0x1de3,0x1de4,0x1de5,0x1de6,0x1de7,
+ 0x1de8,0x1de9,0x1dea,0x1deb,0x1dec,0x1ded,0x1dee,0x1def,
+ 0x1df0,0x1df1,0x1df2,0x1df3,0x1df4,0x1df5,0x1df6,0x1df7,
+ 0x1df8,0x1df9,0x1dfa,0x1dfb,0x1dfc,0x1dfd,0x1dfe,0x1dff,
+ 0x1e00,0x1e00,0x1e02,0x1e02,0x1e04,0x1e04,0x1e06,0x1e06,
+ 0x1e08,0x1e08,0x1e0a,0x1e0a,0x1e0c,0x1e0c,0x1e0e,0x1e0e,
+ 0x1e10,0x1e10,0x1e12,0x1e12,0x1e14,0x1e14,0x1e16,0x1e16,
+ 0x1e18,0x1e18,0x1e1a,0x1e1a,0x1e1c,0x1e1c,0x1e1e,0x1e1e,
+ 0x1e20,0x1e20,0x1e22,0x1e22,0x1e24,0x1e24,0x1e26,0x1e26,
+ 0x1e28,0x1e28,0x1e2a,0x1e2a,0x1e2c,0x1e2c,0x1e2e,0x1e2e,
+ 0x1e30,0x1e30,0x1e32,0x1e32,0x1e34,0x1e34,0x1e36,0x1e36,
+ 0x1e38,0x1e38,0x1e3a,0x1e3a,0x1e3c,0x1e3c,0x1e3e,0x1e3e,
+ 0x1e40,0x1e40,0x1e42,0x1e42,0x1e44,0x1e44,0x1e46,0x1e46,
+ 0x1e48,0x1e48,0x1e4a,0x1e4a,0x1e4c,0x1e4c,0x1e4e,0x1e4e,
+ 0x1e50,0x1e50,0x1e52,0x1e52,0x1e54,0x1e54,0x1e56,0x1e56,
+ 0x1e58,0x1e58,0x1e5a,0x1e5a,0x1e5c,0x1e5c,0x1e5e,0x1e5e,
+ 0x1e60,0x1e60,0x1e62,0x1e62,0x1e64,0x1e64,0x1e66,0x1e66,
+ 0x1e68,0x1e68,0x1e6a,0x1e6a,0x1e6c,0x1e6c,0x1e6e,0x1e6e,
+ 0x1e70,0x1e70,0x1e72,0x1e72,0x1e74,0x1e74,0x1e76,0x1e76,
+ 0x1e78,0x1e78,0x1e7a,0x1e7a,0x1e7c,0x1e7c,0x1e7e,0x1e7e,
+ 0x1e80,0x1e80,0x1e82,0x1e82,0x1e84,0x1e84,0x1e86,0x1e86,
+ 0x1e88,0x1e88,0x1e8a,0x1e8a,0x1e8c,0x1e8c,0x1e8e,0x1e8e,
+ 0x1e90,0x1e90,0x1e92,0x1e92,0x1e94,0x1e94,0x1e96,0x1e97,
+ 0x1e98,0x1e99,0x1e9a,0x1e9b,0x1e9c,0x1e9d,0x1e9e,0x1e9f,
+ 0x1ea0,0x1ea0,0x1ea2,0x1ea2,0x1ea4,0x1ea4,0x1ea6,0x1ea6,
+ 0x1ea8,0x1ea8,0x1eaa,0x1eaa,0x1eac,0x1eac,0x1eae,0x1eae,
+ 0x1eb0,0x1eb0,0x1eb2,0x1eb2,0x1eb4,0x1eb4,0x1eb6,0x1eb6,
+ 0x1eb8,0x1eb8,0x1eba,0x1eba,0x1ebc,0x1ebc,0x1ebe,0x1ebe,
+ 0x1ec0,0x1ec0,0x1ec2,0x1ec2,0x1ec4,0x1ec4,0x1ec6,0x1ec6,
+ 0x1ec8,0x1ec8,0x1eca,0x1eca,0x1ecc,0x1ecc,0x1ece,0x1ece,
+ 0x1ed0,0x1ed0,0x1ed2,0x1ed2,0x1ed4,0x1ed4,0x1ed6,0x1ed6,
+ 0x1ed8,0x1ed8,0x1eda,0x1eda,0x1edc,0x1edc,0x1ede,0x1ede,
+ 0x1ee0,0x1ee0,0x1ee2,0x1ee2,0x1ee4,0x1ee4,0x1ee6,0x1ee6,
+ 0x1ee8,0x1ee8,0x1eea,0x1eea,0x1eec,0x1eec,0x1eee,0x1eee,
+ 0x1ef0,0x1ef0,0x1ef2,0x1ef2,0x1ef4,0x1ef4,0x1ef6,0x1ef6,
+ 0x1ef8,0x1ef8,0x1efa,0x1efb,0x1efc,0x1efd,0x1efe,0x1eff,
+ 0x1f08,0x1f09,0x1f0a,0x1f0b,0x1f0c,0x1f0d,0x1f0e,0x1f0f,
+ 0x1f08,0x1f09,0x1f0a,0x1f0b,0x1f0c,0x1f0d,0x1f0e,0x1f0f,
+ 0x1f18,0x1f19,0x1f1a,0x1f1b,0x1f1c,0x1f1d,0x1f16,0x1f17,
+ 0x1f18,0x1f19,0x1f1a,0x1f1b,0x1f1c,0x1f1d,0x1f1e,0x1f1f,
+ 0x1f28,0x1f29,0x1f2a,0x1f2b,0x1f2c,0x1f2d,0x1f2e,0x1f2f,
+ 0x1f28,0x1f29,0x1f2a,0x1f2b,0x1f2c,0x1f2d,0x1f2e,0x1f2f,
+ 0x1f38,0x1f39,0x1f3a,0x1f3b,0x1f3c,0x1f3d,0x1f3e,0x1f3f,
+ 0x1f38,0x1f39,0x1f3a,0x1f3b,0x1f3c,0x1f3d,0x1f3e,0x1f3f,
+ 0x1f48,0x1f49,0x1f4a,0x1f4b,0x1f4c,0x1f4d,0x1f46,0x1f47,
+ 0x1f48,0x1f49,0x1f4a,0x1f4b,0x1f4c,0x1f4d,0x1f4e,0x1f4f,
+ 0x1f50,0x1f59,0x1f52,0x1f5b,0x1f54,0x1f5d,0x1f56,0x1f5f,
+ 0x1f58,0x1f59,0x1f5a,0x1f5b,0x1f5c,0x1f5d,0x1f5e,0x1f5f,
+ 0x1f68,0x1f69,0x1f6a,0x1f6b,0x1f6c,0x1f6d,0x1f6e,0x1f6f,
+ 0x1f68,0x1f69,0x1f6a,0x1f6b,0x1f6c,0x1f6d,0x1f6e,0x1f6f,
+ 0x1fba,0x1fbb,0x1fc8,0x1fc9,0x1fca,0x1fcb,0x1fda,0x1fdb,
+ 0x1ff8,0x1ff9,0x1fea,0x1feb,0x1ffa,0x1ffb,0x1f7e,0x1f7f,
+ 0x1f80,0x1f81,0x1f82,0x1f83,0x1f84,0x1f85,0x1f86,0x1f87,
+ 0x1f88,0x1f89,0x1f8a,0x1f8b,0x1f8c,0x1f8d,0x1f8e,0x1f8f,
+ 0x1f90,0x1f91,0x1f92,0x1f93,0x1f94,0x1f95,0x1f96,0x1f97,
+ 0x1f98,0x1f99,0x1f9a,0x1f9b,0x1f9c,0x1f9d,0x1f9e,0x1f9f,
+ 0x1fa0,0x1fa1,0x1fa2,0x1fa3,0x1fa4,0x1fa5,0x1fa6,0x1fa7,
+ 0x1fa8,0x1fa9,0x1faa,0x1fab,0x1fac,0x1fad,0x1fae,0x1faf,
+ 0x1fb8,0x1fb9,0x1fb2,0x1fb3,0x1fb4,0x1fb5,0x1fb6,0x1fb7,
+ 0x1fb8,0x1fb9,0x1fba,0x1fbb,0x1fbc,0x1fbd,0x1fbe,0x1fbf,
+ 0x1fc0,0x1fc1,0x1fc2,0x1fc3,0x1fc4,0x1fc5,0x1fc6,0x1fc7,
+ 0x1fc8,0x1fc9,0x1fca,0x1fcb,0x1fcc,0x1fcd,0x1fce,0x1fcf,
+ 0x1fd8,0x1fd9,0x1fd2,0x1fd3,0x1fd4,0x1fd5,0x1fd6,0x1fd7,
+ 0x1fd8,0x1fd9,0x1fda,0x1fdb,0x1fdc,0x1fdd,0x1fde,0x1fdf,
+ 0x1fe8,0x1fe9,0x1fe2,0x1fe3,0x1fe4,0x1fec,0x1fe6,0x1fe7,
+ 0x1fe8,0x1fe9,0x1fea,0x1feb,0x1fec,0x1fed,0x1fee,0x1fef,
+ 0x1ff0,0x1ff1,0x1ff2,0x1ff3,0x1ff4,0x1ff5,0x1ff6,0x1ff7,
+ 0x1ff8,0x1ff9,0x1ffa,0x1ffb,0x1ffc,0x1ffd,0x1ffe,0x1fff,
+ 0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007,
+ 0x2008,0x2009,0x200a,0x200b,0x200c,0x200d,0x200e,0x200f,
+ 0x2010,0x2011,0x2012,0x2013,0x2014,0x2015,0x2016,0x2017,
+ 0x2018,0x2019,0x201a,0x201b,0x201c,0x201d,0x201e,0x201f,
+ 0x2020,0x2021,0x2022,0x2023,0x2024,0x2025,0x2026,0x2027,
+ 0x2028,0x2029,0x202a,0x202b,0x202c,0x202d,0x202e,0x202f,
+ 0x2030,0x2031,0x2032,0x2033,0x2034,0x2035,0x2036,0x2037,
+ 0x2038,0x2039,0x203a,0x203b,0x203c,0x203d,0x203e,0x203f,
+ 0x2040,0x2041,0x2042,0x2043,0x2044,0x2045,0x2046,0x2047,
+ 0x2048,0x2049,0x204a,0x204b,0x204c,0x204d,0x204e,0x204f,
+ 0x2050,0x2051,0x2052,0x2053,0x2054,0x2055,0x2056,0x2057,
+ 0x2058,0x2059,0x205a,0x205b,0x205c,0x205d,0x205e,0x205f,
+ 0x2060,0x2061,0x2062,0x2063,0x2064,0x2065,0x2066,0x2067,
+ 0x2068,0x2069,0x206a,0x206b,0x206c,0x206d,0x206e,0x206f,
+ 0x2070,0x2071,0x2072,0x2073,0x2074,0x2075,0x2076,0x2077,
+ 0x2078,0x2079,0x207a,0x207b,0x207c,0x207d,0x207e,0x207f,
+ 0x2080,0x2081,0x2082,0x2083,0x2084,0x2085,0x2086,0x2087,
+ 0x2088,0x2089,0x208a,0x208b,0x208c,0x208d,0x208e,0x208f,
+ 0x2090,0x2091,0x2092,0x2093,0x2094,0x2095,0x2096,0x2097,
+ 0x2098,0x2099,0x209a,0x209b,0x209c,0x209d,0x209e,0x209f,
+ 0x20a0,0x20a1,0x20a2,0x20a3,0x20a4,0x20a5,0x20a6,0x20a7,
+ 0x20a8,0x20a9,0x20aa,0x20ab,0x20ac,0x20ad,0x20ae,0x20af,
+ 0x20b0,0x20b1,0x20b2,0x20b3,0x20b4,0x20b5,0x20b6,0x20b7,
+ 0x20b8,0x20b9,0x20ba,0x20bb,0x20bc,0x20bd,0x20be,0x20bf,
+ 0x20c0,0x20c1,0x20c2,0x20c3,0x20c4,0x20c5,0x20c6,0x20c7,
+ 0x20c8,0x20c9,0x20ca,0x20cb,0x20cc,0x20cd,0x20ce,0x20cf,
+ 0x20d0,0x20d1,0x20d2,0x20d3,0x20d4,0x20d5,0x20d6,0x20d7,
+ 0x20d8,0x20d9,0x20da,0x20db,0x20dc,0x20dd,0x20de,0x20df,
+ 0x20e0,0x20e1,0x20e2,0x20e3,0x20e4,0x20e5,0x20e6,0x20e7,
+ 0x20e8,0x20e9,0x20ea,0x20eb,0x20ec,0x20ed,0x20ee,0x20ef,
+ 0x20f0,0x20f1,0x20f2,0x20f3,0x20f4,0x20f5,0x20f6,0x20f7,
+ 0x20f8,0x20f9,0x20fa,0x20fb,0x20fc,0x20fd,0x20fe,0x20ff,
+ 0x2100,0x2101,0x2102,0x2103,0x2104,0x2105,0x2106,0x2107,
+ 0x2108,0x2109,0x210a,0x210b,0x210c,0x210d,0x210e,0x210f,
+ 0x2110,0x2111,0x2112,0x2113,0x2114,0x2115,0x2116,0x2117,
+ 0x2118,0x2119,0x211a,0x211b,0x211c,0x211d,0x211e,0x211f,
+ 0x2120,0x2121,0x2122,0x2123,0x2124,0x2125,0x2126,0x2127,
+ 0x2128,0x2129,0x212a,0x212b,0x212c,0x212d,0x212e,0x212f,
+ 0x2130,0x2131,0x2132,0x2133,0x2134,0x2135,0x2136,0x2137,
+ 0x2138,0x2139,0x213a,0x213b,0x213c,0x213d,0x213e,0x213f,
+ 0x2140,0x2141,0x2142,0x2143,0x2144,0x2145,0x2146,0x2147,
+ 0x2148,0x2149,0x214a,0x214b,0x214c,0x214d,0x214e,0x214f,
+ 0x2150,0x2151,0x2152,0x2153,0x2154,0x2155,0x2156,0x2157,
+ 0x2158,0x2159,0x215a,0x215b,0x215c,0x215d,0x215e,0x215f,
+ 0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,0x2167,
+ 0x2168,0x2169,0x216a,0x216b,0x216c,0x216d,0x216e,0x216f,
+ 0x2160,0x2161,0x2162,0x2163,0x2164,0x2165,0x2166,0x2167,
+ 0x2168,0x2169,0x216a,0x216b,0x216c,0x216d,0x216e,0x216f,
+ 0x2180,0x2181,0x2182,0x2183,0x2184,0x2185,0x2186,0x2187,
+ 0x2188,0x2189,0x218a,0x218b,0x218c,0x218d,0x218e,0x218f,
+ 0x2190,0x2191,0x2192,0x2193,0x2194,0x2195,0x2196,0x2197,
+ 0x2198,0x2199,0x219a,0x219b,0x219c,0x219d,0x219e,0x219f,
+ 0x21a0,0x21a1,0x21a2,0x21a3,0x21a4,0x21a5,0x21a6,0x21a7,
+ 0x21a8,0x21a9,0x21aa,0x21ab,0x21ac,0x21ad,0x21ae,0x21af,
+ 0x21b0,0x21b1,0x21b2,0x21b3,0x21b4,0x21b5,0x21b6,0x21b7,
+ 0x21b8,0x21b9,0x21ba,0x21bb,0x21bc,0x21bd,0x21be,0x21bf,
+ 0x21c0,0x21c1,0x21c2,0x21c3,0x21c4,0x21c5,0x21c6,0x21c7,
+ 0x21c8,0x21c9,0x21ca,0x21cb,0x21cc,0x21cd,0x21ce,0x21cf,
+ 0x21d0,0x21d1,0x21d2,0x21d3,0x21d4,0x21d5,0x21d6,0x21d7,
+ 0x21d8,0x21d9,0x21da,0x21db,0x21dc,0x21dd,0x21de,0x21df,
+ 0x21e0,0x21e1,0x21e2,0x21e3,0x21e4,0x21e5,0x21e6,0x21e7,
+ 0x21e8,0x21e9,0x21ea,0x21eb,0x21ec,0x21ed,0x21ee,0x21ef,
+ 0x21f0,0x21f1,0x21f2,0x21f3,0x21f4,0x21f5,0x21f6,0x21f7,
+ 0x21f8,0x21f9,0x21fa,0x21fb,0x21fc,0x21fd,0x21fe,0x21ff,
+ 0x2200,0x2201,0x2202,0x2203,0x2204,0x2205,0x2206,0x2207,
+ 0x2208,0x2209,0x220a,0x220b,0x220c,0x220d,0x220e,0x220f,
+ 0x2210,0x2211,0x2212,0x2213,0x2214,0x2215,0x2216,0x2217,
+ 0x2218,0x2219,0x221a,0x221b,0x221c,0x221d,0x221e,0x221f,
+ 0x2220,0x2221,0x2222,0x2223,0x2224,0x2225,0x2226,0x2227,
+ 0x2228,0x2229,0x222a,0x222b,0x222c,0x222d,0x222e,0x222f,
+ 0x2230,0x2231,0x2232,0x2233,0x2234,0x2235,0x2236,0x2237,
+ 0x2238,0x2239,0x223a,0x223b,0x223c,0x223d,0x223e,0x223f,
+ 0x2240,0x2241,0x2242,0x2243,0x2244,0x2245,0x2246,0x2247,
+ 0x2248,0x2249,0x224a,0x224b,0x224c,0x224d,0x224e,0x224f,
+ 0x2250,0x2251,0x2252,0x2253,0x2254,0x2255,0x2256,0x2257,
+ 0x2258,0x2259,0x225a,0x225b,0x225c,0x225d,0x225e,0x225f,
+ 0x2260,0x2261,0x2262,0x2263,0x2264,0x2265,0x2266,0x2267,
+ 0x2268,0x2269,0x226a,0x226b,0x226c,0x226d,0x226e,0x226f,
+ 0x2270,0x2271,0x2272,0x2273,0x2274,0x2275,0x2276,0x2277,
+ 0x2278,0x2279,0x227a,0x227b,0x227c,0x227d,0x227e,0x227f,
+ 0x2280,0x2281,0x2282,0x2283,0x2284,0x2285,0x2286,0x2287,
+ 0x2288,0x2289,0x228a,0x228b,0x228c,0x228d,0x228e,0x228f,
+ 0x2290,0x2291,0x2292,0x2293,0x2294,0x2295,0x2296,0x2297,
+ 0x2298,0x2299,0x229a,0x229b,0x229c,0x229d,0x229e,0x229f,
+ 0x22a0,0x22a1,0x22a2,0x22a3,0x22a4,0x22a5,0x22a6,0x22a7,
+ 0x22a8,0x22a9,0x22aa,0x22ab,0x22ac,0x22ad,0x22ae,0x22af,
+ 0x22b0,0x22b1,0x22b2,0x22b3,0x22b4,0x22b5,0x22b6,0x22b7,
+ 0x22b8,0x22b9,0x22ba,0x22bb,0x22bc,0x22bd,0x22be,0x22bf,
+ 0x22c0,0x22c1,0x22c2,0x22c3,0x22c4,0x22c5,0x22c6,0x22c7,
+ 0x22c8,0x22c9,0x22ca,0x22cb,0x22cc,0x22cd,0x22ce,0x22cf,
+ 0x22d0,0x22d1,0x22d2,0x22d3,0x22d4,0x22d5,0x22d6,0x22d7,
+ 0x22d8,0x22d9,0x22da,0x22db,0x22dc,0x22dd,0x22de,0x22df,
+ 0x22e0,0x22e1,0x22e2,0x22e3,0x22e4,0x22e5,0x22e6,0x22e7,
+ 0x22e8,0x22e9,0x22ea,0x22eb,0x22ec,0x22ed,0x22ee,0x22ef,
+ 0x22f0,0x22f1,0x22f2,0x22f3,0x22f4,0x22f5,0x22f6,0x22f7,
+ 0x22f8,0x22f9,0x22fa,0x22fb,0x22fc,0x22fd,0x22fe,0x22ff,
+ 0x2300,0x2301,0x2302,0x2303,0x2304,0x2305,0x2306,0x2307,
+ 0x2308,0x2309,0x230a,0x230b,0x230c,0x230d,0x230e,0x230f,
+ 0x2310,0x2311,0x2312,0x2313,0x2314,0x2315,0x2316,0x2317,
+ 0x2318,0x2319,0x231a,0x231b,0x231c,0x231d,0x231e,0x231f,
+ 0x2320,0x2321,0x2322,0x2323,0x2324,0x2325,0x2326,0x2327,
+ 0x2328,0x2329,0x232a,0x232b,0x232c,0x232d,0x232e,0x232f,
+ 0x2330,0x2331,0x2332,0x2333,0x2334,0x2335,0x2336,0x2337,
+ 0x2338,0x2339,0x233a,0x233b,0x233c,0x233d,0x233e,0x233f,
+ 0x2340,0x2341,0x2342,0x2343,0x2344,0x2345,0x2346,0x2347,
+ 0x2348,0x2349,0x234a,0x234b,0x234c,0x234d,0x234e,0x234f,
+ 0x2350,0x2351,0x2352,0x2353,0x2354,0x2355,0x2356,0x2357,
+ 0x2358,0x2359,0x235a,0x235b,0x235c,0x235d,0x235e,0x235f,
+ 0x2360,0x2361,0x2362,0x2363,0x2364,0x2365,0x2366,0x2367,
+ 0x2368,0x2369,0x236a,0x236b,0x236c,0x236d,0x236e,0x236f,
+ 0x2370,0x2371,0x2372,0x2373,0x2374,0x2375,0x2376,0x2377,
+ 0x2378,0x2379,0x237a,0x237b,0x237c,0x237d,0x237e,0x237f,
+ 0x2380,0x2381,0x2382,0x2383,0x2384,0x2385,0x2386,0x2387,
+ 0x2388,0x2389,0x238a,0x238b,0x238c,0x238d,0x238e,0x238f,
+ 0x2390,0x2391,0x2392,0x2393,0x2394,0x2395,0x2396,0x2397,
+ 0x2398,0x2399,0x239a,0x239b,0x239c,0x239d,0x239e,0x239f,
+ 0x23a0,0x23a1,0x23a2,0x23a3,0x23a4,0x23a5,0x23a6,0x23a7,
+ 0x23a8,0x23a9,0x23aa,0x23ab,0x23ac,0x23ad,0x23ae,0x23af,
+ 0x23b0,0x23b1,0x23b2,0x23b3,0x23b4,0x23b5,0x23b6,0x23b7,
+ 0x23b8,0x23b9,0x23ba,0x23bb,0x23bc,0x23bd,0x23be,0x23bf,
+ 0x23c0,0x23c1,0x23c2,0x23c3,0x23c4,0x23c5,0x23c6,0x23c7,
+ 0x23c8,0x23c9,0x23ca,0x23cb,0x23cc,0x23cd,0x23ce,0x23cf,
+ 0x23d0,0x23d1,0x23d2,0x23d3,0x23d4,0x23d5,0x23d6,0x23d7,
+ 0x23d8,0x23d9,0x23da,0x23db,0x23dc,0x23dd,0x23de,0x23df,
+ 0x23e0,0x23e1,0x23e2,0x23e3,0x23e4,0x23e5,0x23e6,0x23e7,
+ 0x23e8,0x23e9,0x23ea,0x23eb,0x23ec,0x23ed,0x23ee,0x23ef,
+ 0x23f0,0x23f1,0x23f2,0x23f3,0x23f4,0x23f5,0x23f6,0x23f7,
+ 0x23f8,0x23f9,0x23fa,0x23fb,0x23fc,0x23fd,0x23fe,0x23ff,
+ 0x2400,0x2401,0x2402,0x2403,0x2404,0x2405,0x2406,0x2407,
+ 0x2408,0x2409,0x240a,0x240b,0x240c,0x240d,0x240e,0x240f,
+ 0x2410,0x2411,0x2412,0x2413,0x2414,0x2415,0x2416,0x2417,
+ 0x2418,0x2419,0x241a,0x241b,0x241c,0x241d,0x241e,0x241f,
+ 0x2420,0x2421,0x2422,0x2423,0x2424,0x2425,0x2426,0x2427,
+ 0x2428,0x2429,0x242a,0x242b,0x242c,0x242d,0x242e,0x242f,
+ 0x2430,0x2431,0x2432,0x2433,0x2434,0x2435,0x2436,0x2437,
+ 0x2438,0x2439,0x243a,0x243b,0x243c,0x243d,0x243e,0x243f,
+ 0x2440,0x2441,0x2442,0x2443,0x2444,0x2445,0x2446,0x2447,
+ 0x2448,0x2449,0x244a,0x244b,0x244c,0x244d,0x244e,0x244f,
+ 0x2450,0x2451,0x2452,0x2453,0x2454,0x2455,0x2456,0x2457,
+ 0x2458,0x2459,0x245a,0x245b,0x245c,0x245d,0x245e,0x245f,
+ 0x2460,0x2461,0x2462,0x2463,0x2464,0x2465,0x2466,0x2467,
+ 0x2468,0x2469,0x246a,0x246b,0x246c,0x246d,0x246e,0x246f,
+ 0x2470,0x2471,0x2472,0x2473,0x2474,0x2475,0x2476,0x2477,
+ 0x2478,0x2479,0x247a,0x247b,0x247c,0x247d,0x247e,0x247f,
+ 0x2480,0x2481,0x2482,0x2483,0x2484,0x2485,0x2486,0x2487,
+ 0x2488,0x2489,0x248a,0x248b,0x248c,0x248d,0x248e,0x248f,
+ 0x2490,0x2491,0x2492,0x2493,0x2494,0x2495,0x2496,0x2497,
+ 0x2498,0x2499,0x249a,0x249b,0x249c,0x249d,0x249e,0x249f,
+ 0x24a0,0x24a1,0x24a2,0x24a3,0x24a4,0x24a5,0x24a6,0x24a7,
+ 0x24a8,0x24a9,0x24aa,0x24ab,0x24ac,0x24ad,0x24ae,0x24af,
+ 0x24b0,0x24b1,0x24b2,0x24b3,0x24b4,0x24b5,0x24b6,0x24b7,
+ 0x24b8,0x24b9,0x24ba,0x24bb,0x24bc,0x24bd,0x24be,0x24bf,
+ 0x24c0,0x24c1,0x24c2,0x24c3,0x24c4,0x24c5,0x24c6,0x24c7,
+ 0x24c8,0x24c9,0x24ca,0x24cb,0x24cc,0x24cd,0x24ce,0x24cf,
+ 0x24b6,0x24b7,0x24b8,0x24b9,0x24ba,0x24bb,0x24bc,0x24bd,
+ 0x24be,0x24bf,0x24c0,0x24c1,0x24c2,0x24c3,0x24c4,0x24c5,
+ 0x24c6,0x24c7,0x24c8,0x24c9,0x24ca,0x24cb,0x24cc,0x24cd,
+ 0x24ce,0x24cf,0x24ea,0x24eb,0x24ec,0x24ed,0x24ee,0x24ef,
+ 0x24f0,0x24f1,0x24f2,0x24f3,0x24f4,0x24f5,0x24f6,0x24f7,
+ 0x24f8,0x24f9,0x24fa,0x24fb,0x24fc,0x24fd,0x24fe,0x24ff,
+ 0x2500,0x2501,0x2502,0x2503,0x2504,0x2505,0x2506,0x2507,
+ 0x2508,0x2509,0x250a,0x250b,0x250c,0x250d,0x250e,0x250f,
+ 0x2510,0x2511,0x2512,0x2513,0x2514,0x2515,0x2516,0x2517,
+ 0x2518,0x2519,0x251a,0x251b,0x251c,0x251d,0x251e,0x251f,
+ 0x2520,0x2521,0x2522,0x2523,0x2524,0x2525,0x2526,0x2527,
+ 0x2528,0x2529,0x252a,0x252b,0x252c,0x252d,0x252e,0x252f,
+ 0x2530,0x2531,0x2532,0x2533,0x2534,0x2535,0x2536,0x2537,
+ 0x2538,0x2539,0x253a,0x253b,0x253c,0x253d,0x253e,0x253f,
+ 0x2540,0x2541,0x2542,0x2543,0x2544,0x2545,0x2546,0x2547,
+ 0x2548,0x2549,0x254a,0x254b,0x254c,0x254d,0x254e,0x254f,
+ 0x2550,0x2551,0x2552,0x2553,0x2554,0x2555,0x2556,0x2557,
+ 0x2558,0x2559,0x255a,0x255b,0x255c,0x255d,0x255e,0x255f,
+ 0x2560,0x2561,0x2562,0x2563,0x2564,0x2565,0x2566,0x2567,
+ 0x2568,0x2569,0x256a,0x256b,0x256c,0x256d,0x256e,0x256f,
+ 0x2570,0x2571,0x2572,0x2573,0x2574,0x2575,0x2576,0x2577,
+ 0x2578,0x2579,0x257a,0x257b,0x257c,0x257d,0x257e,0x257f,
+ 0x2580,0x2581,0x2582,0x2583,0x2584,0x2585,0x2586,0x2587,
+ 0x2588,0x2589,0x258a,0x258b,0x258c,0x258d,0x258e,0x258f,
+ 0x2590,0x2591,0x2592,0x2593,0x2594,0x2595,0x2596,0x2597,
+ 0x2598,0x2599,0x259a,0x259b,0x259c,0x259d,0x259e,0x259f,
+ 0x25a0,0x25a1,0x25a2,0x25a3,0x25a4,0x25a5,0x25a6,0x25a7,
+ 0x25a8,0x25a9,0x25aa,0x25ab,0x25ac,0x25ad,0x25ae,0x25af,
+ 0x25b0,0x25b1,0x25b2,0x25b3,0x25b4,0x25b5,0x25b6,0x25b7,
+ 0x25b8,0x25b9,0x25ba,0x25bb,0x25bc,0x25bd,0x25be,0x25bf,
+ 0x25c0,0x25c1,0x25c2,0x25c3,0x25c4,0x25c5,0x25c6,0x25c7,
+ 0x25c8,0x25c9,0x25ca,0x25cb,0x25cc,0x25cd,0x25ce,0x25cf,
+ 0x25d0,0x25d1,0x25d2,0x25d3,0x25d4,0x25d5,0x25d6,0x25d7,
+ 0x25d8,0x25d9,0x25da,0x25db,0x25dc,0x25dd,0x25de,0x25df,
+ 0x25e0,0x25e1,0x25e2,0x25e3,0x25e4,0x25e5,0x25e6,0x25e7,
+ 0x25e8,0x25e9,0x25ea,0x25eb,0x25ec,0x25ed,0x25ee,0x25ef,
+ 0x25f0,0x25f1,0x25f2,0x25f3,0x25f4,0x25f5,0x25f6,0x25f7,
+ 0x25f8,0x25f9,0x25fa,0x25fb,0x25fc,0x25fd,0x25fe,0x25ff,
+ 0x2600,0x2601,0x2602,0x2603,0x2604,0x2605,0x2606,0x2607,
+ 0x2608,0x2609,0x260a,0x260b,0x260c,0x260d,0x260e,0x260f,
+ 0x2610,0x2611,0x2612,0x2613,0x2614,0x2615,0x2616,0x2617,
+ 0x2618,0x2619,0x261a,0x261b,0x261c,0x261d,0x261e,0x261f,
+ 0x2620,0x2621,0x2622,0x2623,0x2624,0x2625,0x2626,0x2627,
+ 0x2628,0x2629,0x262a,0x262b,0x262c,0x262d,0x262e,0x262f,
+ 0x2630,0x2631,0x2632,0x2633,0x2634,0x2635,0x2636,0x2637,
+ 0x2638,0x2639,0x263a,0x263b,0x263c,0x263d,0x263e,0x263f,
+ 0x2640,0x2641,0x2642,0x2643,0x2644,0x2645,0x2646,0x2647,
+ 0x2648,0x2649,0x264a,0x264b,0x264c,0x264d,0x264e,0x264f,
+ 0x2650,0x2651,0x2652,0x2653,0x2654,0x2655,0x2656,0x2657,
+ 0x2658,0x2659,0x265a,0x265b,0x265c,0x265d,0x265e,0x265f,
+ 0x2660,0x2661,0x2662,0x2663,0x2664,0x2665,0x2666,0x2667,
+ 0x2668,0x2669,0x266a,0x266b,0x266c,0x266d,0x266e,0x266f,
+ 0x2670,0x2671,0x2672,0x2673,0x2674,0x2675,0x2676,0x2677,
+ 0x2678,0x2679,0x267a,0x267b,0x267c,0x267d,0x267e,0x267f,
+ 0x2680,0x2681,0x2682,0x2683,0x2684,0x2685,0x2686,0x2687,
+ 0x2688,0x2689,0x268a,0x268b,0x268c,0x268d,0x268e,0x268f,
+ 0x2690,0x2691,0x2692,0x2693,0x2694,0x2695,0x2696,0x2697,
+ 0x2698,0x2699,0x269a,0x269b,0x269c,0x269d,0x269e,0x269f,
+ 0x26a0,0x26a1,0x26a2,0x26a3,0x26a4,0x26a5,0x26a6,0x26a7,
+ 0x26a8,0x26a9,0x26aa,0x26ab,0x26ac,0x26ad,0x26ae,0x26af,
+ 0x26b0,0x26b1,0x26b2,0x26b3,0x26b4,0x26b5,0x26b6,0x26b7,
+ 0x26b8,0x26b9,0x26ba,0x26bb,0x26bc,0x26bd,0x26be,0x26bf,
+ 0x26c0,0x26c1,0x26c2,0x26c3,0x26c4,0x26c5,0x26c6,0x26c7,
+ 0x26c8,0x26c9,0x26ca,0x26cb,0x26cc,0x26cd,0x26ce,0x26cf,
+ 0x26d0,0x26d1,0x26d2,0x26d3,0x26d4,0x26d5,0x26d6,0x26d7,
+ 0x26d8,0x26d9,0x26da,0x26db,0x26dc,0x26dd,0x26de,0x26df,
+ 0x26e0,0x26e1,0x26e2,0x26e3,0x26e4,0x26e5,0x26e6,0x26e7,
+ 0x26e8,0x26e9,0x26ea,0x26eb,0x26ec,0x26ed,0x26ee,0x26ef,
+ 0x26f0,0x26f1,0x26f2,0x26f3,0x26f4,0x26f5,0x26f6,0x26f7,
+ 0x26f8,0x26f9,0x26fa,0x26fb,0x26fc,0x26fd,0x26fe,0x26ff,
+ 0x2700,0x2701,0x2702,0x2703,0x2704,0x2705,0x2706,0x2707,
+ 0x2708,0x2709,0x270a,0x270b,0x270c,0x270d,0x270e,0x270f,
+ 0x2710,0x2711,0x2712,0x2713,0x2714,0x2715,0x2716,0x2717,
+ 0x2718,0x2719,0x271a,0x271b,0x271c,0x271d,0x271e,0x271f,
+ 0x2720,0x2721,0x2722,0x2723,0x2724,0x2725,0x2726,0x2727,
+ 0x2728,0x2729,0x272a,0x272b,0x272c,0x272d,0x272e,0x272f,
+ 0x2730,0x2731,0x2732,0x2733,0x2734,0x2735,0x2736,0x2737,
+ 0x2738,0x2739,0x273a,0x273b,0x273c,0x273d,0x273e,0x273f,
+ 0x2740,0x2741,0x2742,0x2743,0x2744,0x2745,0x2746,0x2747,
+ 0x2748,0x2749,0x274a,0x274b,0x274c,0x274d,0x274e,0x274f,
+ 0x2750,0x2751,0x2752,0x2753,0x2754,0x2755,0x2756,0x2757,
+ 0x2758,0x2759,0x275a,0x275b,0x275c,0x275d,0x275e,0x275f,
+ 0x2760,0x2761,0x2762,0x2763,0x2764,0x2765,0x2766,0x2767,
+ 0x2768,0x2769,0x276a,0x276b,0x276c,0x276d,0x276e,0x276f,
+ 0x2770,0x2771,0x2772,0x2773,0x2774,0x2775,0x2776,0x2777,
+ 0x2778,0x2779,0x277a,0x277b,0x277c,0x277d,0x277e,0x277f,
+ 0x2780,0x2781,0x2782,0x2783,0x2784,0x2785,0x2786,0x2787,
+ 0x2788,0x2789,0x278a,0x278b,0x278c,0x278d,0x278e,0x278f,
+ 0x2790,0x2791,0x2792,0x2793,0x2794,0x2795,0x2796,0x2797,
+ 0x2798,0x2799,0x279a,0x279b,0x279c,0x279d,0x279e,0x279f,
+ 0x27a0,0x27a1,0x27a2,0x27a3,0x27a4,0x27a5,0x27a6,0x27a7,
+ 0x27a8,0x27a9,0x27aa,0x27ab,0x27ac,0x27ad,0x27ae,0x27af,
+ 0x27b0,0x27b1,0x27b2,0x27b3,0x27b4,0x27b5,0x27b6,0x27b7,
+ 0x27b8,0x27b9,0x27ba,0x27bb,0x27bc,0x27bd,0x27be,0x27bf,
+ 0x27c0,0x27c1,0x27c2,0x27c3,0x27c4,0x27c5,0x27c6,0x27c7,
+ 0x27c8,0x27c9,0x27ca,0x27cb,0x27cc,0x27cd,0x27ce,0x27cf,
+ 0x27d0,0x27d1,0x27d2,0x27d3,0x27d4,0x27d5,0x27d6,0x27d7,
+ 0x27d8,0x27d9,0x27da,0x27db,0x27dc,0x27dd,0x27de,0x27df,
+ 0x27e0,0x27e1,0x27e2,0x27e3,0x27e4,0x27e5,0x27e6,0x27e7,
+ 0x27e8,0x27e9,0x27ea,0x27eb,0x27ec,0x27ed,0x27ee,0x27ef,
+ 0x27f0,0x27f1,0x27f2,0x27f3,0x27f4,0x27f5,0x27f6,0x27f7,
+ 0x27f8,0x27f9,0x27fa,0x27fb,0x27fc,0x27fd,0x27fe,0x27ff,
+ 0x2800,0x2801,0x2802,0x2803,0x2804,0x2805,0x2806,0x2807,
+ 0x2808,0x2809,0x280a,0x280b,0x280c,0x280d,0x280e,0x280f,
+ 0x2810,0x2811,0x2812,0x2813,0x2814,0x2815,0x2816,0x2817,
+ 0x2818,0x2819,0x281a,0x281b,0x281c,0x281d,0x281e,0x281f,
+ 0x2820,0x2821,0x2822,0x2823,0x2824,0x2825,0x2826,0x2827,
+ 0x2828,0x2829,0x282a,0x282b,0x282c,0x282d,0x282e,0x282f,
+ 0x2830,0x2831,0x2832,0x2833,0x2834,0x2835,0x2836,0x2837,
+ 0x2838,0x2839,0x283a,0x283b,0x283c,0x283d,0x283e,0x283f,
+ 0x2840,0x2841,0x2842,0x2843,0x2844,0x2845,0x2846,0x2847,
+ 0x2848,0x2849,0x284a,0x284b,0x284c,0x284d,0x284e,0x284f,
+ 0x2850,0x2851,0x2852,0x2853,0x2854,0x2855,0x2856,0x2857,
+ 0x2858,0x2859,0x285a,0x285b,0x285c,0x285d,0x285e,0x285f,
+ 0x2860,0x2861,0x2862,0x2863,0x2864,0x2865,0x2866,0x2867,
+ 0x2868,0x2869,0x286a,0x286b,0x286c,0x286d,0x286e,0x286f,
+ 0x2870,0x2871,0x2872,0x2873,0x2874,0x2875,0x2876,0x2877,
+ 0x2878,0x2879,0x287a,0x287b,0x287c,0x287d,0x287e,0x287f,
+ 0x2880,0x2881,0x2882,0x2883,0x2884,0x2885,0x2886,0x2887,
+ 0x2888,0x2889,0x288a,0x288b,0x288c,0x288d,0x288e,0x288f,
+ 0x2890,0x2891,0x2892,0x2893,0x2894,0x2895,0x2896,0x2897,
+ 0x2898,0x2899,0x289a,0x289b,0x289c,0x289d,0x289e,0x289f,
+ 0x28a0,0x28a1,0x28a2,0x28a3,0x28a4,0x28a5,0x28a6,0x28a7,
+ 0x28a8,0x28a9,0x28aa,0x28ab,0x28ac,0x28ad,0x28ae,0x28af,
+ 0x28b0,0x28b1,0x28b2,0x28b3,0x28b4,0x28b5,0x28b6,0x28b7,
+ 0x28b8,0x28b9,0x28ba,0x28bb,0x28bc,0x28bd,0x28be,0x28bf,
+ 0x28c0,0x28c1,0x28c2,0x28c3,0x28c4,0x28c5,0x28c6,0x28c7,
+ 0x28c8,0x28c9,0x28ca,0x28cb,0x28cc,0x28cd,0x28ce,0x28cf,
+ 0x28d0,0x28d1,0x28d2,0x28d3,0x28d4,0x28d5,0x28d6,0x28d7,
+ 0x28d8,0x28d9,0x28da,0x28db,0x28dc,0x28dd,0x28de,0x28df,
+ 0x28e0,0x28e1,0x28e2,0x28e3,0x28e4,0x28e5,0x28e6,0x28e7,
+ 0x28e8,0x28e9,0x28ea,0x28eb,0x28ec,0x28ed,0x28ee,0x28ef,
+ 0x28f0,0x28f1,0x28f2,0x28f3,0x28f4,0x28f5,0x28f6,0x28f7,
+ 0x28f8,0x28f9,0x28fa,0x28fb,0x28fc,0x28fd,0x28fe,0x28ff,
+ 0x2900,0x2901,0x2902,0x2903,0x2904,0x2905,0x2906,0x2907,
+ 0x2908,0x2909,0x290a,0x290b,0x290c,0x290d,0x290e,0x290f,
+ 0x2910,0x2911,0x2912,0x2913,0x2914,0x2915,0x2916,0x2917,
+ 0x2918,0x2919,0x291a,0x291b,0x291c,0x291d,0x291e,0x291f,
+ 0x2920,0x2921,0x2922,0x2923,0x2924,0x2925,0x2926,0x2927,
+ 0x2928,0x2929,0x292a,0x292b,0x292c,0x292d,0x292e,0x292f,
+ 0x2930,0x2931,0x2932,0x2933,0x2934,0x2935,0x2936,0x2937,
+ 0x2938,0x2939,0x293a,0x293b,0x293c,0x293d,0x293e,0x293f,
+ 0x2940,0x2941,0x2942,0x2943,0x2944,0x2945,0x2946,0x2947,
+ 0x2948,0x2949,0x294a,0x294b,0x294c,0x294d,0x294e,0x294f,
+ 0x2950,0x2951,0x2952,0x2953,0x2954,0x2955,0x2956,0x2957,
+ 0x2958,0x2959,0x295a,0x295b,0x295c,0x295d,0x295e,0x295f,
+ 0x2960,0x2961,0x2962,0x2963,0x2964,0x2965,0x2966,0x2967,
+ 0x2968,0x2969,0x296a,0x296b,0x296c,0x296d,0x296e,0x296f,
+ 0x2970,0x2971,0x2972,0x2973,0x2974,0x2975,0x2976,0x2977,
+ 0x2978,0x2979,0x297a,0x297b,0x297c,0x297d,0x297e,0x297f,
+ 0x2980,0x2981,0x2982,0x2983,0x2984,0x2985,0x2986,0x2987,
+ 0x2988,0x2989,0x298a,0x298b,0x298c,0x298d,0x298e,0x298f,
+ 0x2990,0x2991,0x2992,0x2993,0x2994,0x2995,0x2996,0x2997,
+ 0x2998,0x2999,0x299a,0x299b,0x299c,0x299d,0x299e,0x299f,
+ 0x29a0,0x29a1,0x29a2,0x29a3,0x29a4,0x29a5,0x29a6,0x29a7,
+ 0x29a8,0x29a9,0x29aa,0x29ab,0x29ac,0x29ad,0x29ae,0x29af,
+ 0x29b0,0x29b1,0x29b2,0x29b3,0x29b4,0x29b5,0x29b6,0x29b7,
+ 0x29b8,0x29b9,0x29ba,0x29bb,0x29bc,0x29bd,0x29be,0x29bf,
+ 0x29c0,0x29c1,0x29c2,0x29c3,0x29c4,0x29c5,0x29c6,0x29c7,
+ 0x29c8,0x29c9,0x29ca,0x29cb,0x29cc,0x29cd,0x29ce,0x29cf,
+ 0x29d0,0x29d1,0x29d2,0x29d3,0x29d4,0x29d5,0x29d6,0x29d7,
+ 0x29d8,0x29d9,0x29da,0x29db,0x29dc,0x29dd,0x29de,0x29df,
+ 0x29e0,0x29e1,0x29e2,0x29e3,0x29e4,0x29e5,0x29e6,0x29e7,
+ 0x29e8,0x29e9,0x29ea,0x29eb,0x29ec,0x29ed,0x29ee,0x29ef,
+ 0x29f0,0x29f1,0x29f2,0x29f3,0x29f4,0x29f5,0x29f6,0x29f7,
+ 0x29f8,0x29f9,0x29fa,0x29fb,0x29fc,0x29fd,0x29fe,0x29ff,
+ 0x2a00,0x2a01,0x2a02,0x2a03,0x2a04,0x2a05,0x2a06,0x2a07,
+ 0x2a08,0x2a09,0x2a0a,0x2a0b,0x2a0c,0x2a0d,0x2a0e,0x2a0f,
+ 0x2a10,0x2a11,0x2a12,0x2a13,0x2a14,0x2a15,0x2a16,0x2a17,
+ 0x2a18,0x2a19,0x2a1a,0x2a1b,0x2a1c,0x2a1d,0x2a1e,0x2a1f,
+ 0x2a20,0x2a21,0x2a22,0x2a23,0x2a24,0x2a25,0x2a26,0x2a27,
+ 0x2a28,0x2a29,0x2a2a,0x2a2b,0x2a2c,0x2a2d,0x2a2e,0x2a2f,
+ 0x2a30,0x2a31,0x2a32,0x2a33,0x2a34,0x2a35,0x2a36,0x2a37,
+ 0x2a38,0x2a39,0x2a3a,0x2a3b,0x2a3c,0x2a3d,0x2a3e,0x2a3f,
+ 0x2a40,0x2a41,0x2a42,0x2a43,0x2a44,0x2a45,0x2a46,0x2a47,
+ 0x2a48,0x2a49,0x2a4a,0x2a4b,0x2a4c,0x2a4d,0x2a4e,0x2a4f,
+ 0x2a50,0x2a51,0x2a52,0x2a53,0x2a54,0x2a55,0x2a56,0x2a57,
+ 0x2a58,0x2a59,0x2a5a,0x2a5b,0x2a5c,0x2a5d,0x2a5e,0x2a5f,
+ 0x2a60,0x2a61,0x2a62,0x2a63,0x2a64,0x2a65,0x2a66,0x2a67,
+ 0x2a68,0x2a69,0x2a6a,0x2a6b,0x2a6c,0x2a6d,0x2a6e,0x2a6f,
+ 0x2a70,0x2a71,0x2a72,0x2a73,0x2a74,0x2a75,0x2a76,0x2a77,
+ 0x2a78,0x2a79,0x2a7a,0x2a7b,0x2a7c,0x2a7d,0x2a7e,0x2a7f,
+ 0x2a80,0x2a81,0x2a82,0x2a83,0x2a84,0x2a85,0x2a86,0x2a87,
+ 0x2a88,0x2a89,0x2a8a,0x2a8b,0x2a8c,0x2a8d,0x2a8e,0x2a8f,
+ 0x2a90,0x2a91,0x2a92,0x2a93,0x2a94,0x2a95,0x2a96,0x2a97,
+ 0x2a98,0x2a99,0x2a9a,0x2a9b,0x2a9c,0x2a9d,0x2a9e,0x2a9f,
+ 0x2aa0,0x2aa1,0x2aa2,0x2aa3,0x2aa4,0x2aa5,0x2aa6,0x2aa7,
+ 0x2aa8,0x2aa9,0x2aaa,0x2aab,0x2aac,0x2aad,0x2aae,0x2aaf,
+ 0x2ab0,0x2ab1,0x2ab2,0x2ab3,0x2ab4,0x2ab5,0x2ab6,0x2ab7,
+ 0x2ab8,0x2ab9,0x2aba,0x2abb,0x2abc,0x2abd,0x2abe,0x2abf,
+ 0x2ac0,0x2ac1,0x2ac2,0x2ac3,0x2ac4,0x2ac5,0x2ac6,0x2ac7,
+ 0x2ac8,0x2ac9,0x2aca,0x2acb,0x2acc,0x2acd,0x2ace,0x2acf,
+ 0x2ad0,0x2ad1,0x2ad2,0x2ad3,0x2ad4,0x2ad5,0x2ad6,0x2ad7,
+ 0x2ad8,0x2ad9,0x2ada,0x2adb,0x2adc,0x2add,0x2ade,0x2adf,
+ 0x2ae0,0x2ae1,0x2ae2,0x2ae3,0x2ae4,0x2ae5,0x2ae6,0x2ae7,
+ 0x2ae8,0x2ae9,0x2aea,0x2aeb,0x2aec,0x2aed,0x2aee,0x2aef,
+ 0x2af0,0x2af1,0x2af2,0x2af3,0x2af4,0x2af5,0x2af6,0x2af7,
+ 0x2af8,0x2af9,0x2afa,0x2afb,0x2afc,0x2afd,0x2afe,0x2aff,
+ 0x2b00,0x2b01,0x2b02,0x2b03,0x2b04,0x2b05,0x2b06,0x2b07,
+ 0x2b08,0x2b09,0x2b0a,0x2b0b,0x2b0c,0x2b0d,0x2b0e,0x2b0f,
+ 0x2b10,0x2b11,0x2b12,0x2b13,0x2b14,0x2b15,0x2b16,0x2b17,
+ 0x2b18,0x2b19,0x2b1a,0x2b1b,0x2b1c,0x2b1d,0x2b1e,0x2b1f,
+ 0x2b20,0x2b21,0x2b22,0x2b23,0x2b24,0x2b25,0x2b26,0x2b27,
+ 0x2b28,0x2b29,0x2b2a,0x2b2b,0x2b2c,0x2b2d,0x2b2e,0x2b2f,
+ 0x2b30,0x2b31,0x2b32,0x2b33,0x2b34,0x2b35,0x2b36,0x2b37,
+ 0x2b38,0x2b39,0x2b3a,0x2b3b,0x2b3c,0x2b3d,0x2b3e,0x2b3f,
+ 0x2b40,0x2b41,0x2b42,0x2b43,0x2b44,0x2b45,0x2b46,0x2b47,
+ 0x2b48,0x2b49,0x2b4a,0x2b4b,0x2b4c,0x2b4d,0x2b4e,0x2b4f,
+ 0x2b50,0x2b51,0x2b52,0x2b53,0x2b54,0x2b55,0x2b56,0x2b57,
+ 0x2b58,0x2b59,0x2b5a,0x2b5b,0x2b5c,0x2b5d,0x2b5e,0x2b5f,
+ 0x2b60,0x2b61,0x2b62,0x2b63,0x2b64,0x2b65,0x2b66,0x2b67,
+ 0x2b68,0x2b69,0x2b6a,0x2b6b,0x2b6c,0x2b6d,0x2b6e,0x2b6f,
+ 0x2b70,0x2b71,0x2b72,0x2b73,0x2b74,0x2b75,0x2b76,0x2b77,
+ 0x2b78,0x2b79,0x2b7a,0x2b7b,0x2b7c,0x2b7d,0x2b7e,0x2b7f,
+ 0x2b80,0x2b81,0x2b82,0x2b83,0x2b84,0x2b85,0x2b86,0x2b87,
+ 0x2b88,0x2b89,0x2b8a,0x2b8b,0x2b8c,0x2b8d,0x2b8e,0x2b8f,
+ 0x2b90,0x2b91,0x2b92,0x2b93,0x2b94,0x2b95,0x2b96,0x2b97,
+ 0x2b98,0x2b99,0x2b9a,0x2b9b,0x2b9c,0x2b9d,0x2b9e,0x2b9f,
+ 0x2ba0,0x2ba1,0x2ba2,0x2ba3,0x2ba4,0x2ba5,0x2ba6,0x2ba7,
+ 0x2ba8,0x2ba9,0x2baa,0x2bab,0x2bac,0x2bad,0x2bae,0x2baf,
+ 0x2bb0,0x2bb1,0x2bb2,0x2bb3,0x2bb4,0x2bb5,0x2bb6,0x2bb7,
+ 0x2bb8,0x2bb9,0x2bba,0x2bbb,0x2bbc,0x2bbd,0x2bbe,0x2bbf,
+ 0x2bc0,0x2bc1,0x2bc2,0x2bc3,0x2bc4,0x2bc5,0x2bc6,0x2bc7,
+ 0x2bc8,0x2bc9,0x2bca,0x2bcb,0x2bcc,0x2bcd,0x2bce,0x2bcf,
+ 0x2bd0,0x2bd1,0x2bd2,0x2bd3,0x2bd4,0x2bd5,0x2bd6,0x2bd7,
+ 0x2bd8,0x2bd9,0x2bda,0x2bdb,0x2bdc,0x2bdd,0x2bde,0x2bdf,
+ 0x2be0,0x2be1,0x2be2,0x2be3,0x2be4,0x2be5,0x2be6,0x2be7,
+ 0x2be8,0x2be9,0x2bea,0x2beb,0x2bec,0x2bed,0x2bee,0x2bef,
+ 0x2bf0,0x2bf1,0x2bf2,0x2bf3,0x2bf4,0x2bf5,0x2bf6,0x2bf7,
+ 0x2bf8,0x2bf9,0x2bfa,0x2bfb,0x2bfc,0x2bfd,0x2bfe,0x2bff,
+ 0x2c00,0x2c01,0x2c02,0x2c03,0x2c04,0x2c05,0x2c06,0x2c07,
+ 0x2c08,0x2c09,0x2c0a,0x2c0b,0x2c0c,0x2c0d,0x2c0e,0x2c0f,
+ 0x2c10,0x2c11,0x2c12,0x2c13,0x2c14,0x2c15,0x2c16,0x2c17,
+ 0x2c18,0x2c19,0x2c1a,0x2c1b,0x2c1c,0x2c1d,0x2c1e,0x2c1f,
+ 0x2c20,0x2c21,0x2c22,0x2c23,0x2c24,0x2c25,0x2c26,0x2c27,
+ 0x2c28,0x2c29,0x2c2a,0x2c2b,0x2c2c,0x2c2d,0x2c2e,0x2c2f,
+ 0x2c30,0x2c31,0x2c32,0x2c33,0x2c34,0x2c35,0x2c36,0x2c37,
+ 0x2c38,0x2c39,0x2c3a,0x2c3b,0x2c3c,0x2c3d,0x2c3e,0x2c3f,
+ 0x2c40,0x2c41,0x2c42,0x2c43,0x2c44,0x2c45,0x2c46,0x2c47,
+ 0x2c48,0x2c49,0x2c4a,0x2c4b,0x2c4c,0x2c4d,0x2c4e,0x2c4f,
+ 0x2c50,0x2c51,0x2c52,0x2c53,0x2c54,0x2c55,0x2c56,0x2c57,
+ 0x2c58,0x2c59,0x2c5a,0x2c5b,0x2c5c,0x2c5d,0x2c5e,0x2c5f,
+ 0x2c60,0x2c61,0x2c62,0x2c63,0x2c64,0x2c65,0x2c66,0x2c67,
+ 0x2c68,0x2c69,0x2c6a,0x2c6b,0x2c6c,0x2c6d,0x2c6e,0x2c6f,
+ 0x2c70,0x2c71,0x2c72,0x2c73,0x2c74,0x2c75,0x2c76,0x2c77,
+ 0x2c78,0x2c79,0x2c7a,0x2c7b,0x2c7c,0x2c7d,0x2c7e,0x2c7f,
+ 0x2c80,0x2c81,0x2c82,0x2c83,0x2c84,0x2c85,0x2c86,0x2c87,
+ 0x2c88,0x2c89,0x2c8a,0x2c8b,0x2c8c,0x2c8d,0x2c8e,0x2c8f,
+ 0x2c90,0x2c91,0x2c92,0x2c93,0x2c94,0x2c95,0x2c96,0x2c97,
+ 0x2c98,0x2c99,0x2c9a,0x2c9b,0x2c9c,0x2c9d,0x2c9e,0x2c9f,
+ 0x2ca0,0x2ca1,0x2ca2,0x2ca3,0x2ca4,0x2ca5,0x2ca6,0x2ca7,
+ 0x2ca8,0x2ca9,0x2caa,0x2cab,0x2cac,0x2cad,0x2cae,0x2caf,
+ 0x2cb0,0x2cb1,0x2cb2,0x2cb3,0x2cb4,0x2cb5,0x2cb6,0x2cb7,
+ 0x2cb8,0x2cb9,0x2cba,0x2cbb,0x2cbc,0x2cbd,0x2cbe,0x2cbf,
+ 0x2cc0,0x2cc1,0x2cc2,0x2cc3,0x2cc4,0x2cc5,0x2cc6,0x2cc7,
+ 0x2cc8,0x2cc9,0x2cca,0x2ccb,0x2ccc,0x2ccd,0x2cce,0x2ccf,
+ 0x2cd0,0x2cd1,0x2cd2,0x2cd3,0x2cd4,0x2cd5,0x2cd6,0x2cd7,
+ 0x2cd8,0x2cd9,0x2cda,0x2cdb,0x2cdc,0x2cdd,0x2cde,0x2cdf,
+ 0x2ce0,0x2ce1,0x2ce2,0x2ce3,0x2ce4,0x2ce5,0x2ce6,0x2ce7,
+ 0x2ce8,0x2ce9,0x2cea,0x2ceb,0x2cec,0x2ced,0x2cee,0x2cef,
+ 0x2cf0,0x2cf1,0x2cf2,0x2cf3,0x2cf4,0x2cf5,0x2cf6,0x2cf7,
+ 0x2cf8,0x2cf9,0x2cfa,0x2cfb,0x2cfc,0x2cfd,0x2cfe,0x2cff,
+ 0x2d00,0x2d01,0x2d02,0x2d03,0x2d04,0x2d05,0x2d06,0x2d07,
+ 0x2d08,0x2d09,0x2d0a,0x2d0b,0x2d0c,0x2d0d,0x2d0e,0x2d0f,
+ 0x2d10,0x2d11,0x2d12,0x2d13,0x2d14,0x2d15,0x2d16,0x2d17,
+ 0x2d18,0x2d19,0x2d1a,0x2d1b,0x2d1c,0x2d1d,0x2d1e,0x2d1f,
+ 0x2d20,0x2d21,0x2d22,0x2d23,0x2d24,0x2d25,0x2d26,0x2d27,
+ 0x2d28,0x2d29,0x2d2a,0x2d2b,0x2d2c,0x2d2d,0x2d2e,0x2d2f,
+ 0x2d30,0x2d31,0x2d32,0x2d33,0x2d34,0x2d35,0x2d36,0x2d37,
+ 0x2d38,0x2d39,0x2d3a,0x2d3b,0x2d3c,0x2d3d,0x2d3e,0x2d3f,
+ 0x2d40,0x2d41,0x2d42,0x2d43,0x2d44,0x2d45,0x2d46,0x2d47,
+ 0x2d48,0x2d49,0x2d4a,0x2d4b,0x2d4c,0x2d4d,0x2d4e,0x2d4f,
+ 0x2d50,0x2d51,0x2d52,0x2d53,0x2d54,0x2d55,0x2d56,0x2d57,
+ 0x2d58,0x2d59,0x2d5a,0x2d5b,0x2d5c,0x2d5d,0x2d5e,0x2d5f,
+ 0x2d60,0x2d61,0x2d62,0x2d63,0x2d64,0x2d65,0x2d66,0x2d67,
+ 0x2d68,0x2d69,0x2d6a,0x2d6b,0x2d6c,0x2d6d,0x2d6e,0x2d6f,
+ 0x2d70,0x2d71,0x2d72,0x2d73,0x2d74,0x2d75,0x2d76,0x2d77,
+ 0x2d78,0x2d79,0x2d7a,0x2d7b,0x2d7c,0x2d7d,0x2d7e,0x2d7f,
+ 0x2d80,0x2d81,0x2d82,0x2d83,0x2d84,0x2d85,0x2d86,0x2d87,
+ 0x2d88,0x2d89,0x2d8a,0x2d8b,0x2d8c,0x2d8d,0x2d8e,0x2d8f,
+ 0x2d90,0x2d91,0x2d92,0x2d93,0x2d94,0x2d95,0x2d96,0x2d97,
+ 0x2d98,0x2d99,0x2d9a,0x2d9b,0x2d9c,0x2d9d,0x2d9e,0x2d9f,
+ 0x2da0,0x2da1,0x2da2,0x2da3,0x2da4,0x2da5,0x2da6,0x2da7,
+ 0x2da8,0x2da9,0x2daa,0x2dab,0x2dac,0x2dad,0x2dae,0x2daf,
+ 0x2db0,0x2db1,0x2db2,0x2db3,0x2db4,0x2db5,0x2db6,0x2db7,
+ 0x2db8,0x2db9,0x2dba,0x2dbb,0x2dbc,0x2dbd,0x2dbe,0x2dbf,
+ 0x2dc0,0x2dc1,0x2dc2,0x2dc3,0x2dc4,0x2dc5,0x2dc6,0x2dc7,
+ 0x2dc8,0x2dc9,0x2dca,0x2dcb,0x2dcc,0x2dcd,0x2dce,0x2dcf,
+ 0x2dd0,0x2dd1,0x2dd2,0x2dd3,0x2dd4,0x2dd5,0x2dd6,0x2dd7,
+ 0x2dd8,0x2dd9,0x2dda,0x2ddb,0x2ddc,0x2ddd,0x2dde,0x2ddf,
+ 0x2de0,0x2de1,0x2de2,0x2de3,0x2de4,0x2de5,0x2de6,0x2de7,
+ 0x2de8,0x2de9,0x2dea,0x2deb,0x2dec,0x2ded,0x2dee,0x2def,
+ 0x2df0,0x2df1,0x2df2,0x2df3,0x2df4,0x2df5,0x2df6,0x2df7,
+ 0x2df8,0x2df9,0x2dfa,0x2dfb,0x2dfc,0x2dfd,0x2dfe,0x2dff,
+ 0x2e00,0x2e01,0x2e02,0x2e03,0x2e04,0x2e05,0x2e06,0x2e07,
+ 0x2e08,0x2e09,0x2e0a,0x2e0b,0x2e0c,0x2e0d,0x2e0e,0x2e0f,
+ 0x2e10,0x2e11,0x2e12,0x2e13,0x2e14,0x2e15,0x2e16,0x2e17,
+ 0x2e18,0x2e19,0x2e1a,0x2e1b,0x2e1c,0x2e1d,0x2e1e,0x2e1f,
+ 0x2e20,0x2e21,0x2e22,0x2e23,0x2e24,0x2e25,0x2e26,0x2e27,
+ 0x2e28,0x2e29,0x2e2a,0x2e2b,0x2e2c,0x2e2d,0x2e2e,0x2e2f,
+ 0x2e30,0x2e31,0x2e32,0x2e33,0x2e34,0x2e35,0x2e36,0x2e37,
+ 0x2e38,0x2e39,0x2e3a,0x2e3b,0x2e3c,0x2e3d,0x2e3e,0x2e3f,
+ 0x2e40,0x2e41,0x2e42,0x2e43,0x2e44,0x2e45,0x2e46,0x2e47,
+ 0x2e48,0x2e49,0x2e4a,0x2e4b,0x2e4c,0x2e4d,0x2e4e,0x2e4f,
+ 0x2e50,0x2e51,0x2e52,0x2e53,0x2e54,0x2e55,0x2e56,0x2e57,
+ 0x2e58,0x2e59,0x2e5a,0x2e5b,0x2e5c,0x2e5d,0x2e5e,0x2e5f,
+ 0x2e60,0x2e61,0x2e62,0x2e63,0x2e64,0x2e65,0x2e66,0x2e67,
+ 0x2e68,0x2e69,0x2e6a,0x2e6b,0x2e6c,0x2e6d,0x2e6e,0x2e6f,
+ 0x2e70,0x2e71,0x2e72,0x2e73,0x2e74,0x2e75,0x2e76,0x2e77,
+ 0x2e78,0x2e79,0x2e7a,0x2e7b,0x2e7c,0x2e7d,0x2e7e,0x2e7f,
+ 0x2e80,0x2e81,0x2e82,0x2e83,0x2e84,0x2e85,0x2e86,0x2e87,
+ 0x2e88,0x2e89,0x2e8a,0x2e8b,0x2e8c,0x2e8d,0x2e8e,0x2e8f,
+ 0x2e90,0x2e91,0x2e92,0x2e93,0x2e94,0x2e95,0x2e96,0x2e97,
+ 0x2e98,0x2e99,0x2e9a,0x2e9b,0x2e9c,0x2e9d,0x2e9e,0x2e9f,
+ 0x2ea0,0x2ea1,0x2ea2,0x2ea3,0x2ea4,0x2ea5,0x2ea6,0x2ea7,
+ 0x2ea8,0x2ea9,0x2eaa,0x2eab,0x2eac,0x2ead,0x2eae,0x2eaf,
+ 0x2eb0,0x2eb1,0x2eb2,0x2eb3,0x2eb4,0x2eb5,0x2eb6,0x2eb7,
+ 0x2eb8,0x2eb9,0x2eba,0x2ebb,0x2ebc,0x2ebd,0x2ebe,0x2ebf,
+ 0x2ec0,0x2ec1,0x2ec2,0x2ec3,0x2ec4,0x2ec5,0x2ec6,0x2ec7,
+ 0x2ec8,0x2ec9,0x2eca,0x2ecb,0x2ecc,0x2ecd,0x2ece,0x2ecf,
+ 0x2ed0,0x2ed1,0x2ed2,0x2ed3,0x2ed4,0x2ed5,0x2ed6,0x2ed7,
+ 0x2ed8,0x2ed9,0x2eda,0x2edb,0x2edc,0x2edd,0x2ede,0x2edf,
+ 0x2ee0,0x2ee1,0x2ee2,0x2ee3,0x2ee4,0x2ee5,0x2ee6,0x2ee7,
+ 0x2ee8,0x2ee9,0x2eea,0x2eeb,0x2eec,0x2eed,0x2eee,0x2eef,
+ 0x2ef0,0x2ef1,0x2ef2,0x2ef3,0x2ef4,0x2ef5,0x2ef6,0x2ef7,
+ 0x2ef8,0x2ef9,0x2efa,0x2efb,0x2efc,0x2efd,0x2efe,0x2eff,
+ 0x2f00,0x2f01,0x2f02,0x2f03,0x2f04,0x2f05,0x2f06,0x2f07,
+ 0x2f08,0x2f09,0x2f0a,0x2f0b,0x2f0c,0x2f0d,0x2f0e,0x2f0f,
+ 0x2f10,0x2f11,0x2f12,0x2f13,0x2f14,0x2f15,0x2f16,0x2f17,
+ 0x2f18,0x2f19,0x2f1a,0x2f1b,0x2f1c,0x2f1d,0x2f1e,0x2f1f,
+ 0x2f20,0x2f21,0x2f22,0x2f23,0x2f24,0x2f25,0x2f26,0x2f27,
+ 0x2f28,0x2f29,0x2f2a,0x2f2b,0x2f2c,0x2f2d,0x2f2e,0x2f2f,
+ 0x2f30,0x2f31,0x2f32,0x2f33,0x2f34,0x2f35,0x2f36,0x2f37,
+ 0x2f38,0x2f39,0x2f3a,0x2f3b,0x2f3c,0x2f3d,0x2f3e,0x2f3f,
+ 0x2f40,0x2f41,0x2f42,0x2f43,0x2f44,0x2f45,0x2f46,0x2f47,
+ 0x2f48,0x2f49,0x2f4a,0x2f4b,0x2f4c,0x2f4d,0x2f4e,0x2f4f,
+ 0x2f50,0x2f51,0x2f52,0x2f53,0x2f54,0x2f55,0x2f56,0x2f57,
+ 0x2f58,0x2f59,0x2f5a,0x2f5b,0x2f5c,0x2f5d,0x2f5e,0x2f5f,
+ 0x2f60,0x2f61,0x2f62,0x2f63,0x2f64,0x2f65,0x2f66,0x2f67,
+ 0x2f68,0x2f69,0x2f6a,0x2f6b,0x2f6c,0x2f6d,0x2f6e,0x2f6f,
+ 0x2f70,0x2f71,0x2f72,0x2f73,0x2f74,0x2f75,0x2f76,0x2f77,
+ 0x2f78,0x2f79,0x2f7a,0x2f7b,0x2f7c,0x2f7d,0x2f7e,0x2f7f,
+ 0x2f80,0x2f81,0x2f82,0x2f83,0x2f84,0x2f85,0x2f86,0x2f87,
+ 0x2f88,0x2f89,0x2f8a,0x2f8b,0x2f8c,0x2f8d,0x2f8e,0x2f8f,
+ 0x2f90,0x2f91,0x2f92,0x2f93,0x2f94,0x2f95,0x2f96,0x2f97,
+ 0x2f98,0x2f99,0x2f9a,0x2f9b,0x2f9c,0x2f9d,0x2f9e,0x2f9f,
+ 0x2fa0,0x2fa1,0x2fa2,0x2fa3,0x2fa4,0x2fa5,0x2fa6,0x2fa7,
+ 0x2fa8,0x2fa9,0x2faa,0x2fab,0x2fac,0x2fad,0x2fae,0x2faf,
+ 0x2fb0,0x2fb1,0x2fb2,0x2fb3,0x2fb4,0x2fb5,0x2fb6,0x2fb7,
+ 0x2fb8,0x2fb9,0x2fba,0x2fbb,0x2fbc,0x2fbd,0x2fbe,0x2fbf,
+ 0x2fc0,0x2fc1,0x2fc2,0x2fc3,0x2fc4,0x2fc5,0x2fc6,0x2fc7,
+ 0x2fc8,0x2fc9,0x2fca,0x2fcb,0x2fcc,0x2fcd,0x2fce,0x2fcf,
+ 0x2fd0,0x2fd1,0x2fd2,0x2fd3,0x2fd4,0x2fd5,0x2fd6,0x2fd7,
+ 0x2fd8,0x2fd9,0x2fda,0x2fdb,0x2fdc,0x2fdd,0x2fde,0x2fdf,
+ 0x2fe0,0x2fe1,0x2fe2,0x2fe3,0x2fe4,0x2fe5,0x2fe6,0x2fe7,
+ 0x2fe8,0x2fe9,0x2fea,0x2feb,0x2fec,0x2fed,0x2fee,0x2fef,
+ 0x2ff0,0x2ff1,0x2ff2,0x2ff3,0x2ff4,0x2ff5,0x2ff6,0x2ff7,
+ 0x2ff8,0x2ff9,0x2ffa,0x2ffb,0x2ffc,0x2ffd,0x2ffe,0x2fff,
+ 0x3000,0x3001,0x3002,0x3003,0x3004,0x3005,0x3006,0x3007,
+ 0x3008,0x3009,0x300a,0x300b,0x300c,0x300d,0x300e,0x300f,
+ 0x3010,0x3011,0x3012,0x3013,0x3014,0x3015,0x3016,0x3017,
+ 0x3018,0x3019,0x301a,0x301b,0x301c,0x301d,0x301e,0x301f,
+ 0x3020,0x3021,0x3022,0x3023,0x3024,0x3025,0x3026,0x3027,
+ 0x3028,0x3029,0x302a,0x302b,0x302c,0x302d,0x302e,0x302f,
+ 0x3030,0x3031,0x3032,0x3033,0x3034,0x3035,0x3036,0x3037,
+ 0x3038,0x3039,0x303a,0x303b,0x303c,0x303d,0x303e,0x303f,
+ 0x3040,0x3041,0x3042,0x3043,0x3044,0x3045,0x3046,0x3047,
+ 0x3048,0x3049,0x304a,0x304b,0x304c,0x304d,0x304e,0x304f,
+ 0x3050,0x3051,0x3052,0x3053,0x3054,0x3055,0x3056,0x3057,
+ 0x3058,0x3059,0x305a,0x305b,0x305c,0x305d,0x305e,0x305f,
+ 0x3060,0x3061,0x3062,0x3063,0x3064,0x3065,0x3066,0x3067,
+ 0x3068,0x3069,0x306a,0x306b,0x306c,0x306d,0x306e,0x306f,
+ 0x3070,0x3071,0x3072,0x3073,0x3074,0x3075,0x3076,0x3077,
+ 0x3078,0x3079,0x307a,0x307b,0x307c,0x307d,0x307e,0x307f,
+ 0x3080,0x3081,0x3082,0x3083,0x3084,0x3085,0x3086,0x3087,
+ 0x3088,0x3089,0x308a,0x308b,0x308c,0x308d,0x308e,0x308f,
+ 0x3090,0x3091,0x3092,0x3093,0x3094,0x3095,0x3096,0x3097,
+ 0x3098,0x3099,0x309a,0x309b,0x309c,0x309d,0x309e,0x309f,
+ 0x30a0,0x30a1,0x30a2,0x30a3,0x30a4,0x30a5,0x30a6,0x30a7,
+ 0x30a8,0x30a9,0x30aa,0x30ab,0x30ac,0x30ad,0x30ae,0x30af,
+ 0x30b0,0x30b1,0x30b2,0x30b3,0x30b4,0x30b5,0x30b6,0x30b7,
+ 0x30b8,0x30b9,0x30ba,0x30bb,0x30bc,0x30bd,0x30be,0x30bf,
+ 0x30c0,0x30c1,0x30c2,0x30c3,0x30c4,0x30c5,0x30c6,0x30c7,
+ 0x30c8,0x30c9,0x30ca,0x30cb,0x30cc,0x30cd,0x30ce,0x30cf,
+ 0x30d0,0x30d1,0x30d2,0x30d3,0x30d4,0x30d5,0x30d6,0x30d7,
+ 0x30d8,0x30d9,0x30da,0x30db,0x30dc,0x30dd,0x30de,0x30df,
+ 0x30e0,0x30e1,0x30e2,0x30e3,0x30e4,0x30e5,0x30e6,0x30e7,
+ 0x30e8,0x30e9,0x30ea,0x30eb,0x30ec,0x30ed,0x30ee,0x30ef,
+ 0x30f0,0x30f1,0x30f2,0x30f3,0x30f4,0x30f5,0x30f6,0x30f7,
+ 0x30f8,0x30f9,0x30fa,0x30fb,0x30fc,0x30fd,0x30fe,0x30ff,
+ 0x3100,0x3101,0x3102,0x3103,0x3104,0x3105,0x3106,0x3107,
+ 0x3108,0x3109,0x310a,0x310b,0x310c,0x310d,0x310e,0x310f,
+ 0x3110,0x3111,0x3112,0x3113,0x3114,0x3115,0x3116,0x3117,
+ 0x3118,0x3119,0x311a,0x311b,0x311c,0x311d,0x311e,0x311f,
+ 0x3120,0x3121,0x3122,0x3123,0x3124,0x3125,0x3126,0x3127,
+ 0x3128,0x3129,0x312a,0x312b,0x312c,0x312d,0x312e,0x312f,
+ 0x3130,0x3131,0x3132,0x3133,0x3134,0x3135,0x3136,0x3137,
+ 0x3138,0x3139,0x313a,0x313b,0x313c,0x313d,0x313e,0x313f,
+ 0x3140,0x3141,0x3142,0x3143,0x3144,0x3145,0x3146,0x3147,
+ 0x3148,0x3149,0x314a,0x314b,0x314c,0x314d,0x314e,0x314f,
+ 0x3150,0x3151,0x3152,0x3153,0x3154,0x3155,0x3156,0x3157,
+ 0x3158,0x3159,0x315a,0x315b,0x315c,0x315d,0x315e,0x315f,
+ 0x3160,0x3161,0x3162,0x3163,0x3164,0x3165,0x3166,0x3167,
+ 0x3168,0x3169,0x316a,0x316b,0x316c,0x316d,0x316e,0x316f,
+ 0x3170,0x3171,0x3172,0x3173,0x3174,0x3175,0x3176,0x3177,
+ 0x3178,0x3179,0x317a,0x317b,0x317c,0x317d,0x317e,0x317f,
+ 0x3180,0x3181,0x3182,0x3183,0x3184,0x3185,0x3186,0x3187,
+ 0x3188,0x3189,0x318a,0x318b,0x318c,0x318d,0x318e,0x318f,
+ 0x3190,0x3191,0x3192,0x3193,0x3194,0x3195,0x3196,0x3197,
+ 0x3198,0x3199,0x319a,0x319b,0x319c,0x319d,0x319e,0x319f,
+ 0x31a0,0x31a1,0x31a2,0x31a3,0x31a4,0x31a5,0x31a6,0x31a7,
+ 0x31a8,0x31a9,0x31aa,0x31ab,0x31ac,0x31ad,0x31ae,0x31af,
+ 0x31b0,0x31b1,0x31b2,0x31b3,0x31b4,0x31b5,0x31b6,0x31b7,
+ 0x31b8,0x31b9,0x31ba,0x31bb,0x31bc,0x31bd,0x31be,0x31bf,
+ 0x31c0,0x31c1,0x31c2,0x31c3,0x31c4,0x31c5,0x31c6,0x31c7,
+ 0x31c8,0x31c9,0x31ca,0x31cb,0x31cc,0x31cd,0x31ce,0x31cf,
+ 0x31d0,0x31d1,0x31d2,0x31d3,0x31d4,0x31d5,0x31d6,0x31d7,
+ 0x31d8,0x31d9,0x31da,0x31db,0x31dc,0x31dd,0x31de,0x31df,
+ 0x31e0,0x31e1,0x31e2,0x31e3,0x31e4,0x31e5,0x31e6,0x31e7,
+ 0x31e8,0x31e9,0x31ea,0x31eb,0x31ec,0x31ed,0x31ee,0x31ef,
+ 0x31f0,0x31f1,0x31f2,0x31f3,0x31f4,0x31f5,0x31f6,0x31f7,
+ 0x31f8,0x31f9,0x31fa,0x31fb,0x31fc,0x31fd,0x31fe,0x31ff,
+ 0x3200,0x3201,0x3202,0x3203,0x3204,0x3205,0x3206,0x3207,
+ 0x3208,0x3209,0x320a,0x320b,0x320c,0x320d,0x320e,0x320f,
+ 0x3210,0x3211,0x3212,0x3213,0x3214,0x3215,0x3216,0x3217,
+ 0x3218,0x3219,0x321a,0x321b,0x321c,0x321d,0x321e,0x321f,
+ 0x3220,0x3221,0x3222,0x3223,0x3224,0x3225,0x3226,0x3227,
+ 0x3228,0x3229,0x322a,0x322b,0x322c,0x322d,0x322e,0x322f,
+ 0x3230,0x3231,0x3232,0x3233,0x3234,0x3235,0x3236,0x3237,
+ 0x3238,0x3239,0x323a,0x323b,0x323c,0x323d,0x323e,0x323f,
+ 0x3240,0x3241,0x3242,0x3243,0x3244,0x3245,0x3246,0x3247,
+ 0x3248,0x3249,0x324a,0x324b,0x324c,0x324d,0x324e,0x324f,
+ 0x3250,0x3251,0x3252,0x3253,0x3254,0x3255,0x3256,0x3257,
+ 0x3258,0x3259,0x325a,0x325b,0x325c,0x325d,0x325e,0x325f,
+ 0x3260,0x3261,0x3262,0x3263,0x3264,0x3265,0x3266,0x3267,
+ 0x3268,0x3269,0x326a,0x326b,0x326c,0x326d,0x326e,0x326f,
+ 0x3270,0x3271,0x3272,0x3273,0x3274,0x3275,0x3276,0x3277,
+ 0x3278,0x3279,0x327a,0x327b,0x327c,0x327d,0x327e,0x327f,
+ 0x3280,0x3281,0x3282,0x3283,0x3284,0x3285,0x3286,0x3287,
+ 0x3288,0x3289,0x328a,0x328b,0x328c,0x328d,0x328e,0x328f,
+ 0x3290,0x3291,0x3292,0x3293,0x3294,0x3295,0x3296,0x3297,
+ 0x3298,0x3299,0x329a,0x329b,0x329c,0x329d,0x329e,0x329f,
+ 0x32a0,0x32a1,0x32a2,0x32a3,0x32a4,0x32a5,0x32a6,0x32a7,
+ 0x32a8,0x32a9,0x32aa,0x32ab,0x32ac,0x32ad,0x32ae,0x32af,
+ 0x32b0,0x32b1,0x32b2,0x32b3,0x32b4,0x32b5,0x32b6,0x32b7,
+ 0x32b8,0x32b9,0x32ba,0x32bb,0x32bc,0x32bd,0x32be,0x32bf,
+ 0x32c0,0x32c1,0x32c2,0x32c3,0x32c4,0x32c5,0x32c6,0x32c7,
+ 0x32c8,0x32c9,0x32ca,0x32cb,0x32cc,0x32cd,0x32ce,0x32cf,
+ 0x32d0,0x32d1,0x32d2,0x32d3,0x32d4,0x32d5,0x32d6,0x32d7,
+ 0x32d8,0x32d9,0x32da,0x32db,0x32dc,0x32dd,0x32de,0x32df,
+ 0x32e0,0x32e1,0x32e2,0x32e3,0x32e4,0x32e5,0x32e6,0x32e7,
+ 0x32e8,0x32e9,0x32ea,0x32eb,0x32ec,0x32ed,0x32ee,0x32ef,
+ 0x32f0,0x32f1,0x32f2,0x32f3,0x32f4,0x32f5,0x32f6,0x32f7,
+ 0x32f8,0x32f9,0x32fa,0x32fb,0x32fc,0x32fd,0x32fe,0x32ff,
+ 0x3300,0x3301,0x3302,0x3303,0x3304,0x3305,0x3306,0x3307,
+ 0x3308,0x3309,0x330a,0x330b,0x330c,0x330d,0x330e,0x330f,
+ 0x3310,0x3311,0x3312,0x3313,0x3314,0x3315,0x3316,0x3317,
+ 0x3318,0x3319,0x331a,0x331b,0x331c,0x331d,0x331e,0x331f,
+ 0x3320,0x3321,0x3322,0x3323,0x3324,0x3325,0x3326,0x3327,
+ 0x3328,0x3329,0x332a,0x332b,0x332c,0x332d,0x332e,0x332f,
+ 0x3330,0x3331,0x3332,0x3333,0x3334,0x3335,0x3336,0x3337,
+ 0x3338,0x3339,0x333a,0x333b,0x333c,0x333d,0x333e,0x333f,
+ 0x3340,0x3341,0x3342,0x3343,0x3344,0x3345,0x3346,0x3347,
+ 0x3348,0x3349,0x334a,0x334b,0x334c,0x334d,0x334e,0x334f,
+ 0x3350,0x3351,0x3352,0x3353,0x3354,0x3355,0x3356,0x3357,
+ 0x3358,0x3359,0x335a,0x335b,0x335c,0x335d,0x335e,0x335f,
+ 0x3360,0x3361,0x3362,0x3363,0x3364,0x3365,0x3366,0x3367,
+ 0x3368,0x3369,0x336a,0x336b,0x336c,0x336d,0x336e,0x336f,
+ 0x3370,0x3371,0x3372,0x3373,0x3374,0x3375,0x3376,0x3377,
+ 0x3378,0x3379,0x337a,0x337b,0x337c,0x337d,0x337e,0x337f,
+ 0x3380,0x3381,0x3382,0x3383,0x3384,0x3385,0x3386,0x3387,
+ 0x3388,0x3389,0x338a,0x338b,0x338c,0x338d,0x338e,0x338f,
+ 0x3390,0x3391,0x3392,0x3393,0x3394,0x3395,0x3396,0x3397,
+ 0x3398,0x3399,0x339a,0x339b,0x339c,0x339d,0x339e,0x339f,
+ 0x33a0,0x33a1,0x33a2,0x33a3,0x33a4,0x33a5,0x33a6,0x33a7,
+ 0x33a8,0x33a9,0x33aa,0x33ab,0x33ac,0x33ad,0x33ae,0x33af,
+ 0x33b0,0x33b1,0x33b2,0x33b3,0x33b4,0x33b5,0x33b6,0x33b7,
+ 0x33b8,0x33b9,0x33ba,0x33bb,0x33bc,0x33bd,0x33be,0x33bf,
+ 0x33c0,0x33c1,0x33c2,0x33c3,0x33c4,0x33c5,0x33c6,0x33c7,
+ 0x33c8,0x33c9,0x33ca,0x33cb,0x33cc,0x33cd,0x33ce,0x33cf,
+ 0x33d0,0x33d1,0x33d2,0x33d3,0x33d4,0x33d5,0x33d6,0x33d7,
+ 0x33d8,0x33d9,0x33da,0x33db,0x33dc,0x33dd,0x33de,0x33df,
+ 0x33e0,0x33e1,0x33e2,0x33e3,0x33e4,0x33e5,0x33e6,0x33e7,
+ 0x33e8,0x33e9,0x33ea,0x33eb,0x33ec,0x33ed,0x33ee,0x33ef,
+ 0x33f0,0x33f1,0x33f2,0x33f3,0x33f4,0x33f5,0x33f6,0x33f7,
+ 0x33f8,0x33f9,0x33fa,0x33fb,0x33fc,0x33fd,0x33fe,0x33ff,
+ 0x3400,0x3401,0x3402,0x3403,0x3404,0x3405,0x3406,0x3407,
+ 0x3408,0x3409,0x340a,0x340b,0x340c,0x340d,0x340e,0x340f,
+ 0x3410,0x3411,0x3412,0x3413,0x3414,0x3415,0x3416,0x3417,
+ 0x3418,0x3419,0x341a,0x341b,0x341c,0x341d,0x341e,0x341f,
+ 0x3420,0x3421,0x3422,0x3423,0x3424,0x3425,0x3426,0x3427,
+ 0x3428,0x3429,0x342a,0x342b,0x342c,0x342d,0x342e,0x342f,
+ 0x3430,0x3431,0x3432,0x3433,0x3434,0x3435,0x3436,0x3437,
+ 0x3438,0x3439,0x343a,0x343b,0x343c,0x343d,0x343e,0x343f,
+ 0x3440,0x3441,0x3442,0x3443,0x3444,0x3445,0x3446,0x3447,
+ 0x3448,0x3449,0x344a,0x344b,0x344c,0x344d,0x344e,0x344f,
+ 0x3450,0x3451,0x3452,0x3453,0x3454,0x3455,0x3456,0x3457,
+ 0x3458,0x3459,0x345a,0x345b,0x345c,0x345d,0x345e,0x345f,
+ 0x3460,0x3461,0x3462,0x3463,0x3464,0x3465,0x3466,0x3467,
+ 0x3468,0x3469,0x346a,0x346b,0x346c,0x346d,0x346e,0x346f,
+ 0x3470,0x3471,0x3472,0x3473,0x3474,0x3475,0x3476,0x3477,
+ 0x3478,0x3479,0x347a,0x347b,0x347c,0x347d,0x347e,0x347f,
+ 0x3480,0x3481,0x3482,0x3483,0x3484,0x3485,0x3486,0x3487,
+ 0x3488,0x3489,0x348a,0x348b,0x348c,0x348d,0x348e,0x348f,
+ 0x3490,0x3491,0x3492,0x3493,0x3494,0x3495,0x3496,0x3497,
+ 0x3498,0x3499,0x349a,0x349b,0x349c,0x349d,0x349e,0x349f,
+ 0x34a0,0x34a1,0x34a2,0x34a3,0x34a4,0x34a5,0x34a6,0x34a7,
+ 0x34a8,0x34a9,0x34aa,0x34ab,0x34ac,0x34ad,0x34ae,0x34af,
+ 0x34b0,0x34b1,0x34b2,0x34b3,0x34b4,0x34b5,0x34b6,0x34b7,
+ 0x34b8,0x34b9,0x34ba,0x34bb,0x34bc,0x34bd,0x34be,0x34bf,
+ 0x34c0,0x34c1,0x34c2,0x34c3,0x34c4,0x34c5,0x34c6,0x34c7,
+ 0x34c8,0x34c9,0x34ca,0x34cb,0x34cc,0x34cd,0x34ce,0x34cf,
+ 0x34d0,0x34d1,0x34d2,0x34d3,0x34d4,0x34d5,0x34d6,0x34d7,
+ 0x34d8,0x34d9,0x34da,0x34db,0x34dc,0x34dd,0x34de,0x34df,
+ 0x34e0,0x34e1,0x34e2,0x34e3,0x34e4,0x34e5,0x34e6,0x34e7,
+ 0x34e8,0x34e9,0x34ea,0x34eb,0x34ec,0x34ed,0x34ee,0x34ef,
+ 0x34f0,0x34f1,0x34f2,0x34f3,0x34f4,0x34f5,0x34f6,0x34f7,
+ 0x34f8,0x34f9,0x34fa,0x34fb,0x34fc,0x34fd,0x34fe,0x34ff,
+ 0x3500,0x3501,0x3502,0x3503,0x3504,0x3505,0x3506,0x3507,
+ 0x3508,0x3509,0x350a,0x350b,0x350c,0x350d,0x350e,0x350f,
+ 0x3510,0x3511,0x3512,0x3513,0x3514,0x3515,0x3516,0x3517,
+ 0x3518,0x3519,0x351a,0x351b,0x351c,0x351d,0x351e,0x351f,
+ 0x3520,0x3521,0x3522,0x3523,0x3524,0x3525,0x3526,0x3527,
+ 0x3528,0x3529,0x352a,0x352b,0x352c,0x352d,0x352e,0x352f,
+ 0x3530,0x3531,0x3532,0x3533,0x3534,0x3535,0x3536,0x3537,
+ 0x3538,0x3539,0x353a,0x353b,0x353c,0x353d,0x353e,0x353f,
+ 0x3540,0x3541,0x3542,0x3543,0x3544,0x3545,0x3546,0x3547,
+ 0x3548,0x3549,0x354a,0x354b,0x354c,0x354d,0x354e,0x354f,
+ 0x3550,0x3551,0x3552,0x3553,0x3554,0x3555,0x3556,0x3557,
+ 0x3558,0x3559,0x355a,0x355b,0x355c,0x355d,0x355e,0x355f,
+ 0x3560,0x3561,0x3562,0x3563,0x3564,0x3565,0x3566,0x3567,
+ 0x3568,0x3569,0x356a,0x356b,0x356c,0x356d,0x356e,0x356f,
+ 0x3570,0x3571,0x3572,0x3573,0x3574,0x3575,0x3576,0x3577,
+ 0x3578,0x3579,0x357a,0x357b,0x357c,0x357d,0x357e,0x357f,
+ 0x3580,0x3581,0x3582,0x3583,0x3584,0x3585,0x3586,0x3587,
+ 0x3588,0x3589,0x358a,0x358b,0x358c,0x358d,0x358e,0x358f,
+ 0x3590,0x3591,0x3592,0x3593,0x3594,0x3595,0x3596,0x3597,
+ 0x3598,0x3599,0x359a,0x359b,0x359c,0x359d,0x359e,0x359f,
+ 0x35a0,0x35a1,0x35a2,0x35a3,0x35a4,0x35a5,0x35a6,0x35a7,
+ 0x35a8,0x35a9,0x35aa,0x35ab,0x35ac,0x35ad,0x35ae,0x35af,
+ 0x35b0,0x35b1,0x35b2,0x35b3,0x35b4,0x35b5,0x35b6,0x35b7,
+ 0x35b8,0x35b9,0x35ba,0x35bb,0x35bc,0x35bd,0x35be,0x35bf,
+ 0x35c0,0x35c1,0x35c2,0x35c3,0x35c4,0x35c5,0x35c6,0x35c7,
+ 0x35c8,0x35c9,0x35ca,0x35cb,0x35cc,0x35cd,0x35ce,0x35cf,
+ 0x35d0,0x35d1,0x35d2,0x35d3,0x35d4,0x35d5,0x35d6,0x35d7,
+ 0x35d8,0x35d9,0x35da,0x35db,0x35dc,0x35dd,0x35de,0x35df,
+ 0x35e0,0x35e1,0x35e2,0x35e3,0x35e4,0x35e5,0x35e6,0x35e7,
+ 0x35e8,0x35e9,0x35ea,0x35eb,0x35ec,0x35ed,0x35ee,0x35ef,
+ 0x35f0,0x35f1,0x35f2,0x35f3,0x35f4,0x35f5,0x35f6,0x35f7,
+ 0x35f8,0x35f9,0x35fa,0x35fb,0x35fc,0x35fd,0x35fe,0x35ff,
+ 0x3600,0x3601,0x3602,0x3603,0x3604,0x3605,0x3606,0x3607,
+ 0x3608,0x3609,0x360a,0x360b,0x360c,0x360d,0x360e,0x360f,
+ 0x3610,0x3611,0x3612,0x3613,0x3614,0x3615,0x3616,0x3617,
+ 0x3618,0x3619,0x361a,0x361b,0x361c,0x361d,0x361e,0x361f,
+ 0x3620,0x3621,0x3622,0x3623,0x3624,0x3625,0x3626,0x3627,
+ 0x3628,0x3629,0x362a,0x362b,0x362c,0x362d,0x362e,0x362f,
+ 0x3630,0x3631,0x3632,0x3633,0x3634,0x3635,0x3636,0x3637,
+ 0x3638,0x3639,0x363a,0x363b,0x363c,0x363d,0x363e,0x363f,
+ 0x3640,0x3641,0x3642,0x3643,0x3644,0x3645,0x3646,0x3647,
+ 0x3648,0x3649,0x364a,0x364b,0x364c,0x364d,0x364e,0x364f,
+ 0x3650,0x3651,0x3652,0x3653,0x3654,0x3655,0x3656,0x3657,
+ 0x3658,0x3659,0x365a,0x365b,0x365c,0x365d,0x365e,0x365f,
+ 0x3660,0x3661,0x3662,0x3663,0x3664,0x3665,0x3666,0x3667,
+ 0x3668,0x3669,0x366a,0x366b,0x366c,0x366d,0x366e,0x366f,
+ 0x3670,0x3671,0x3672,0x3673,0x3674,0x3675,0x3676,0x3677,
+ 0x3678,0x3679,0x367a,0x367b,0x367c,0x367d,0x367e,0x367f,
+ 0x3680,0x3681,0x3682,0x3683,0x3684,0x3685,0x3686,0x3687,
+ 0x3688,0x3689,0x368a,0x368b,0x368c,0x368d,0x368e,0x368f,
+ 0x3690,0x3691,0x3692,0x3693,0x3694,0x3695,0x3696,0x3697,
+ 0x3698,0x3699,0x369a,0x369b,0x369c,0x369d,0x369e,0x369f,
+ 0x36a0,0x36a1,0x36a2,0x36a3,0x36a4,0x36a5,0x36a6,0x36a7,
+ 0x36a8,0x36a9,0x36aa,0x36ab,0x36ac,0x36ad,0x36ae,0x36af,
+ 0x36b0,0x36b1,0x36b2,0x36b3,0x36b4,0x36b5,0x36b6,0x36b7,
+ 0x36b8,0x36b9,0x36ba,0x36bb,0x36bc,0x36bd,0x36be,0x36bf,
+ 0x36c0,0x36c1,0x36c2,0x36c3,0x36c4,0x36c5,0x36c6,0x36c7,
+ 0x36c8,0x36c9,0x36ca,0x36cb,0x36cc,0x36cd,0x36ce,0x36cf,
+ 0x36d0,0x36d1,0x36d2,0x36d3,0x36d4,0x36d5,0x36d6,0x36d7,
+ 0x36d8,0x36d9,0x36da,0x36db,0x36dc,0x36dd,0x36de,0x36df,
+ 0x36e0,0x36e1,0x36e2,0x36e3,0x36e4,0x36e5,0x36e6,0x36e7,
+ 0x36e8,0x36e9,0x36ea,0x36eb,0x36ec,0x36ed,0x36ee,0x36ef,
+ 0x36f0,0x36f1,0x36f2,0x36f3,0x36f4,0x36f5,0x36f6,0x36f7,
+ 0x36f8,0x36f9,0x36fa,0x36fb,0x36fc,0x36fd,0x36fe,0x36ff,
+ 0x3700,0x3701,0x3702,0x3703,0x3704,0x3705,0x3706,0x3707,
+ 0x3708,0x3709,0x370a,0x370b,0x370c,0x370d,0x370e,0x370f,
+ 0x3710,0x3711,0x3712,0x3713,0x3714,0x3715,0x3716,0x3717,
+ 0x3718,0x3719,0x371a,0x371b,0x371c,0x371d,0x371e,0x371f,
+ 0x3720,0x3721,0x3722,0x3723,0x3724,0x3725,0x3726,0x3727,
+ 0x3728,0x3729,0x372a,0x372b,0x372c,0x372d,0x372e,0x372f,
+ 0x3730,0x3731,0x3732,0x3733,0x3734,0x3735,0x3736,0x3737,
+ 0x3738,0x3739,0x373a,0x373b,0x373c,0x373d,0x373e,0x373f,
+ 0x3740,0x3741,0x3742,0x3743,0x3744,0x3745,0x3746,0x3747,
+ 0x3748,0x3749,0x374a,0x374b,0x374c,0x374d,0x374e,0x374f,
+ 0x3750,0x3751,0x3752,0x3753,0x3754,0x3755,0x3756,0x3757,
+ 0x3758,0x3759,0x375a,0x375b,0x375c,0x375d,0x375e,0x375f,
+ 0x3760,0x3761,0x3762,0x3763,0x3764,0x3765,0x3766,0x3767,
+ 0x3768,0x3769,0x376a,0x376b,0x376c,0x376d,0x376e,0x376f,
+ 0x3770,0x3771,0x3772,0x3773,0x3774,0x3775,0x3776,0x3777,
+ 0x3778,0x3779,0x377a,0x377b,0x377c,0x377d,0x377e,0x377f,
+ 0x3780,0x3781,0x3782,0x3783,0x3784,0x3785,0x3786,0x3787,
+ 0x3788,0x3789,0x378a,0x378b,0x378c,0x378d,0x378e,0x378f,
+ 0x3790,0x3791,0x3792,0x3793,0x3794,0x3795,0x3796,0x3797,
+ 0x3798,0x3799,0x379a,0x379b,0x379c,0x379d,0x379e,0x379f,
+ 0x37a0,0x37a1,0x37a2,0x37a3,0x37a4,0x37a5,0x37a6,0x37a7,
+ 0x37a8,0x37a9,0x37aa,0x37ab,0x37ac,0x37ad,0x37ae,0x37af,
+ 0x37b0,0x37b1,0x37b2,0x37b3,0x37b4,0x37b5,0x37b6,0x37b7,
+ 0x37b8,0x37b9,0x37ba,0x37bb,0x37bc,0x37bd,0x37be,0x37bf,
+ 0x37c0,0x37c1,0x37c2,0x37c3,0x37c4,0x37c5,0x37c6,0x37c7,
+ 0x37c8,0x37c9,0x37ca,0x37cb,0x37cc,0x37cd,0x37ce,0x37cf,
+ 0x37d0,0x37d1,0x37d2,0x37d3,0x37d4,0x37d5,0x37d6,0x37d7,
+ 0x37d8,0x37d9,0x37da,0x37db,0x37dc,0x37dd,0x37de,0x37df,
+ 0x37e0,0x37e1,0x37e2,0x37e3,0x37e4,0x37e5,0x37e6,0x37e7,
+ 0x37e8,0x37e9,0x37ea,0x37eb,0x37ec,0x37ed,0x37ee,0x37ef,
+ 0x37f0,0x37f1,0x37f2,0x37f3,0x37f4,0x37f5,0x37f6,0x37f7,
+ 0x37f8,0x37f9,0x37fa,0x37fb,0x37fc,0x37fd,0x37fe,0x37ff,
+ 0x3800,0x3801,0x3802,0x3803,0x3804,0x3805,0x3806,0x3807,
+ 0x3808,0x3809,0x380a,0x380b,0x380c,0x380d,0x380e,0x380f,
+ 0x3810,0x3811,0x3812,0x3813,0x3814,0x3815,0x3816,0x3817,
+ 0x3818,0x3819,0x381a,0x381b,0x381c,0x381d,0x381e,0x381f,
+ 0x3820,0x3821,0x3822,0x3823,0x3824,0x3825,0x3826,0x3827,
+ 0x3828,0x3829,0x382a,0x382b,0x382c,0x382d,0x382e,0x382f,
+ 0x3830,0x3831,0x3832,0x3833,0x3834,0x3835,0x3836,0x3837,
+ 0x3838,0x3839,0x383a,0x383b,0x383c,0x383d,0x383e,0x383f,
+ 0x3840,0x3841,0x3842,0x3843,0x3844,0x3845,0x3846,0x3847,
+ 0x3848,0x3849,0x384a,0x384b,0x384c,0x384d,0x384e,0x384f,
+ 0x3850,0x3851,0x3852,0x3853,0x3854,0x3855,0x3856,0x3857,
+ 0x3858,0x3859,0x385a,0x385b,0x385c,0x385d,0x385e,0x385f,
+ 0x3860,0x3861,0x3862,0x3863,0x3864,0x3865,0x3866,0x3867,
+ 0x3868,0x3869,0x386a,0x386b,0x386c,0x386d,0x386e,0x386f,
+ 0x3870,0x3871,0x3872,0x3873,0x3874,0x3875,0x3876,0x3877,
+ 0x3878,0x3879,0x387a,0x387b,0x387c,0x387d,0x387e,0x387f,
+ 0x3880,0x3881,0x3882,0x3883,0x3884,0x3885,0x3886,0x3887,
+ 0x3888,0x3889,0x388a,0x388b,0x388c,0x388d,0x388e,0x388f,
+ 0x3890,0x3891,0x3892,0x3893,0x3894,0x3895,0x3896,0x3897,
+ 0x3898,0x3899,0x389a,0x389b,0x389c,0x389d,0x389e,0x389f,
+ 0x38a0,0x38a1,0x38a2,0x38a3,0x38a4,0x38a5,0x38a6,0x38a7,
+ 0x38a8,0x38a9,0x38aa,0x38ab,0x38ac,0x38ad,0x38ae,0x38af,
+ 0x38b0,0x38b1,0x38b2,0x38b3,0x38b4,0x38b5,0x38b6,0x38b7,
+ 0x38b8,0x38b9,0x38ba,0x38bb,0x38bc,0x38bd,0x38be,0x38bf,
+ 0x38c0,0x38c1,0x38c2,0x38c3,0x38c4,0x38c5,0x38c6,0x38c7,
+ 0x38c8,0x38c9,0x38ca,0x38cb,0x38cc,0x38cd,0x38ce,0x38cf,
+ 0x38d0,0x38d1,0x38d2,0x38d3,0x38d4,0x38d5,0x38d6,0x38d7,
+ 0x38d8,0x38d9,0x38da,0x38db,0x38dc,0x38dd,0x38de,0x38df,
+ 0x38e0,0x38e1,0x38e2,0x38e3,0x38e4,0x38e5,0x38e6,0x38e7,
+ 0x38e8,0x38e9,0x38ea,0x38eb,0x38ec,0x38ed,0x38ee,0x38ef,
+ 0x38f0,0x38f1,0x38f2,0x38f3,0x38f4,0x38f5,0x38f6,0x38f7,
+ 0x38f8,0x38f9,0x38fa,0x38fb,0x38fc,0x38fd,0x38fe,0x38ff,
+ 0x3900,0x3901,0x3902,0x3903,0x3904,0x3905,0x3906,0x3907,
+ 0x3908,0x3909,0x390a,0x390b,0x390c,0x390d,0x390e,0x390f,
+ 0x3910,0x3911,0x3912,0x3913,0x3914,0x3915,0x3916,0x3917,
+ 0x3918,0x3919,0x391a,0x391b,0x391c,0x391d,0x391e,0x391f,
+ 0x3920,0x3921,0x3922,0x3923,0x3924,0x3925,0x3926,0x3927,
+ 0x3928,0x3929,0x392a,0x392b,0x392c,0x392d,0x392e,0x392f,
+ 0x3930,0x3931,0x3932,0x3933,0x3934,0x3935,0x3936,0x3937,
+ 0x3938,0x3939,0x393a,0x393b,0x393c,0x393d,0x393e,0x393f,
+ 0x3940,0x3941,0x3942,0x3943,0x3944,0x3945,0x3946,0x3947,
+ 0x3948,0x3949,0x394a,0x394b,0x394c,0x394d,0x394e,0x394f,
+ 0x3950,0x3951,0x3952,0x3953,0x3954,0x3955,0x3956,0x3957,
+ 0x3958,0x3959,0x395a,0x395b,0x395c,0x395d,0x395e,0x395f,
+ 0x3960,0x3961,0x3962,0x3963,0x3964,0x3965,0x3966,0x3967,
+ 0x3968,0x3969,0x396a,0x396b,0x396c,0x396d,0x396e,0x396f,
+ 0x3970,0x3971,0x3972,0x3973,0x3974,0x3975,0x3976,0x3977,
+ 0x3978,0x3979,0x397a,0x397b,0x397c,0x397d,0x397e,0x397f,
+ 0x3980,0x3981,0x3982,0x3983,0x3984,0x3985,0x3986,0x3987,
+ 0x3988,0x3989,0x398a,0x398b,0x398c,0x398d,0x398e,0x398f,
+ 0x3990,0x3991,0x3992,0x3993,0x3994,0x3995,0x3996,0x3997,
+ 0x3998,0x3999,0x399a,0x399b,0x399c,0x399d,0x399e,0x399f,
+ 0x39a0,0x39a1,0x39a2,0x39a3,0x39a4,0x39a5,0x39a6,0x39a7,
+ 0x39a8,0x39a9,0x39aa,0x39ab,0x39ac,0x39ad,0x39ae,0x39af,
+ 0x39b0,0x39b1,0x39b2,0x39b3,0x39b4,0x39b5,0x39b6,0x39b7,
+ 0x39b8,0x39b9,0x39ba,0x39bb,0x39bc,0x39bd,0x39be,0x39bf,
+ 0x39c0,0x39c1,0x39c2,0x39c3,0x39c4,0x39c5,0x39c6,0x39c7,
+ 0x39c8,0x39c9,0x39ca,0x39cb,0x39cc,0x39cd,0x39ce,0x39cf,
+ 0x39d0,0x39d1,0x39d2,0x39d3,0x39d4,0x39d5,0x39d6,0x39d7,
+ 0x39d8,0x39d9,0x39da,0x39db,0x39dc,0x39dd,0x39de,0x39df,
+ 0x39e0,0x39e1,0x39e2,0x39e3,0x39e4,0x39e5,0x39e6,0x39e7,
+ 0x39e8,0x39e9,0x39ea,0x39eb,0x39ec,0x39ed,0x39ee,0x39ef,
+ 0x39f0,0x39f1,0x39f2,0x39f3,0x39f4,0x39f5,0x39f6,0x39f7,
+ 0x39f8,0x39f9,0x39fa,0x39fb,0x39fc,0x39fd,0x39fe,0x39ff,
+ 0x3a00,0x3a01,0x3a02,0x3a03,0x3a04,0x3a05,0x3a06,0x3a07,
+ 0x3a08,0x3a09,0x3a0a,0x3a0b,0x3a0c,0x3a0d,0x3a0e,0x3a0f,
+ 0x3a10,0x3a11,0x3a12,0x3a13,0x3a14,0x3a15,0x3a16,0x3a17,
+ 0x3a18,0x3a19,0x3a1a,0x3a1b,0x3a1c,0x3a1d,0x3a1e,0x3a1f,
+ 0x3a20,0x3a21,0x3a22,0x3a23,0x3a24,0x3a25,0x3a26,0x3a27,
+ 0x3a28,0x3a29,0x3a2a,0x3a2b,0x3a2c,0x3a2d,0x3a2e,0x3a2f,
+ 0x3a30,0x3a31,0x3a32,0x3a33,0x3a34,0x3a35,0x3a36,0x3a37,
+ 0x3a38,0x3a39,0x3a3a,0x3a3b,0x3a3c,0x3a3d,0x3a3e,0x3a3f,
+ 0x3a40,0x3a41,0x3a42,0x3a43,0x3a44,0x3a45,0x3a46,0x3a47,
+ 0x3a48,0x3a49,0x3a4a,0x3a4b,0x3a4c,0x3a4d,0x3a4e,0x3a4f,
+ 0x3a50,0x3a51,0x3a52,0x3a53,0x3a54,0x3a55,0x3a56,0x3a57,
+ 0x3a58,0x3a59,0x3a5a,0x3a5b,0x3a5c,0x3a5d,0x3a5e,0x3a5f,
+ 0x3a60,0x3a61,0x3a62,0x3a63,0x3a64,0x3a65,0x3a66,0x3a67,
+ 0x3a68,0x3a69,0x3a6a,0x3a6b,0x3a6c,0x3a6d,0x3a6e,0x3a6f,
+ 0x3a70,0x3a71,0x3a72,0x3a73,0x3a74,0x3a75,0x3a76,0x3a77,
+ 0x3a78,0x3a79,0x3a7a,0x3a7b,0x3a7c,0x3a7d,0x3a7e,0x3a7f,
+ 0x3a80,0x3a81,0x3a82,0x3a83,0x3a84,0x3a85,0x3a86,0x3a87,
+ 0x3a88,0x3a89,0x3a8a,0x3a8b,0x3a8c,0x3a8d,0x3a8e,0x3a8f,
+ 0x3a90,0x3a91,0x3a92,0x3a93,0x3a94,0x3a95,0x3a96,0x3a97,
+ 0x3a98,0x3a99,0x3a9a,0x3a9b,0x3a9c,0x3a9d,0x3a9e,0x3a9f,
+ 0x3aa0,0x3aa1,0x3aa2,0x3aa3,0x3aa4,0x3aa5,0x3aa6,0x3aa7,
+ 0x3aa8,0x3aa9,0x3aaa,0x3aab,0x3aac,0x3aad,0x3aae,0x3aaf,
+ 0x3ab0,0x3ab1,0x3ab2,0x3ab3,0x3ab4,0x3ab5,0x3ab6,0x3ab7,
+ 0x3ab8,0x3ab9,0x3aba,0x3abb,0x3abc,0x3abd,0x3abe,0x3abf,
+ 0x3ac0,0x3ac1,0x3ac2,0x3ac3,0x3ac4,0x3ac5,0x3ac6,0x3ac7,
+ 0x3ac8,0x3ac9,0x3aca,0x3acb,0x3acc,0x3acd,0x3ace,0x3acf,
+ 0x3ad0,0x3ad1,0x3ad2,0x3ad3,0x3ad4,0x3ad5,0x3ad6,0x3ad7,
+ 0x3ad8,0x3ad9,0x3ada,0x3adb,0x3adc,0x3add,0x3ade,0x3adf,
+ 0x3ae0,0x3ae1,0x3ae2,0x3ae3,0x3ae4,0x3ae5,0x3ae6,0x3ae7,
+ 0x3ae8,0x3ae9,0x3aea,0x3aeb,0x3aec,0x3aed,0x3aee,0x3aef,
+ 0x3af0,0x3af1,0x3af2,0x3af3,0x3af4,0x3af5,0x3af6,0x3af7,
+ 0x3af8,0x3af9,0x3afa,0x3afb,0x3afc,0x3afd,0x3afe,0x3aff,
+ 0x3b00,0x3b01,0x3b02,0x3b03,0x3b04,0x3b05,0x3b06,0x3b07,
+ 0x3b08,0x3b09,0x3b0a,0x3b0b,0x3b0c,0x3b0d,0x3b0e,0x3b0f,
+ 0x3b10,0x3b11,0x3b12,0x3b13,0x3b14,0x3b15,0x3b16,0x3b17,
+ 0x3b18,0x3b19,0x3b1a,0x3b1b,0x3b1c,0x3b1d,0x3b1e,0x3b1f,
+ 0x3b20,0x3b21,0x3b22,0x3b23,0x3b24,0x3b25,0x3b26,0x3b27,
+ 0x3b28,0x3b29,0x3b2a,0x3b2b,0x3b2c,0x3b2d,0x3b2e,0x3b2f,
+ 0x3b30,0x3b31,0x3b32,0x3b33,0x3b34,0x3b35,0x3b36,0x3b37,
+ 0x3b38,0x3b39,0x3b3a,0x3b3b,0x3b3c,0x3b3d,0x3b3e,0x3b3f,
+ 0x3b40,0x3b41,0x3b42,0x3b43,0x3b44,0x3b45,0x3b46,0x3b47,
+ 0x3b48,0x3b49,0x3b4a,0x3b4b,0x3b4c,0x3b4d,0x3b4e,0x3b4f,
+ 0x3b50,0x3b51,0x3b52,0x3b53,0x3b54,0x3b55,0x3b56,0x3b57,
+ 0x3b58,0x3b59,0x3b5a,0x3b5b,0x3b5c,0x3b5d,0x3b5e,0x3b5f,
+ 0x3b60,0x3b61,0x3b62,0x3b63,0x3b64,0x3b65,0x3b66,0x3b67,
+ 0x3b68,0x3b69,0x3b6a,0x3b6b,0x3b6c,0x3b6d,0x3b6e,0x3b6f,
+ 0x3b70,0x3b71,0x3b72,0x3b73,0x3b74,0x3b75,0x3b76,0x3b77,
+ 0x3b78,0x3b79,0x3b7a,0x3b7b,0x3b7c,0x3b7d,0x3b7e,0x3b7f,
+ 0x3b80,0x3b81,0x3b82,0x3b83,0x3b84,0x3b85,0x3b86,0x3b87,
+ 0x3b88,0x3b89,0x3b8a,0x3b8b,0x3b8c,0x3b8d,0x3b8e,0x3b8f,
+ 0x3b90,0x3b91,0x3b92,0x3b93,0x3b94,0x3b95,0x3b96,0x3b97,
+ 0x3b98,0x3b99,0x3b9a,0x3b9b,0x3b9c,0x3b9d,0x3b9e,0x3b9f,
+ 0x3ba0,0x3ba1,0x3ba2,0x3ba3,0x3ba4,0x3ba5,0x3ba6,0x3ba7,
+ 0x3ba8,0x3ba9,0x3baa,0x3bab,0x3bac,0x3bad,0x3bae,0x3baf,
+ 0x3bb0,0x3bb1,0x3bb2,0x3bb3,0x3bb4,0x3bb5,0x3bb6,0x3bb7,
+ 0x3bb8,0x3bb9,0x3bba,0x3bbb,0x3bbc,0x3bbd,0x3bbe,0x3bbf,
+ 0x3bc0,0x3bc1,0x3bc2,0x3bc3,0x3bc4,0x3bc5,0x3bc6,0x3bc7,
+ 0x3bc8,0x3bc9,0x3bca,0x3bcb,0x3bcc,0x3bcd,0x3bce,0x3bcf,
+ 0x3bd0,0x3bd1,0x3bd2,0x3bd3,0x3bd4,0x3bd5,0x3bd6,0x3bd7,
+ 0x3bd8,0x3bd9,0x3bda,0x3bdb,0x3bdc,0x3bdd,0x3bde,0x3bdf,
+ 0x3be0,0x3be1,0x3be2,0x3be3,0x3be4,0x3be5,0x3be6,0x3be7,
+ 0x3be8,0x3be9,0x3bea,0x3beb,0x3bec,0x3bed,0x3bee,0x3bef,
+ 0x3bf0,0x3bf1,0x3bf2,0x3bf3,0x3bf4,0x3bf5,0x3bf6,0x3bf7,
+ 0x3bf8,0x3bf9,0x3bfa,0x3bfb,0x3bfc,0x3bfd,0x3bfe,0x3bff,
+ 0x3c00,0x3c01,0x3c02,0x3c03,0x3c04,0x3c05,0x3c06,0x3c07,
+ 0x3c08,0x3c09,0x3c0a,0x3c0b,0x3c0c,0x3c0d,0x3c0e,0x3c0f,
+ 0x3c10,0x3c11,0x3c12,0x3c13,0x3c14,0x3c15,0x3c16,0x3c17,
+ 0x3c18,0x3c19,0x3c1a,0x3c1b,0x3c1c,0x3c1d,0x3c1e,0x3c1f,
+ 0x3c20,0x3c21,0x3c22,0x3c23,0x3c24,0x3c25,0x3c26,0x3c27,
+ 0x3c28,0x3c29,0x3c2a,0x3c2b,0x3c2c,0x3c2d,0x3c2e,0x3c2f,
+ 0x3c30,0x3c31,0x3c32,0x3c33,0x3c34,0x3c35,0x3c36,0x3c37,
+ 0x3c38,0x3c39,0x3c3a,0x3c3b,0x3c3c,0x3c3d,0x3c3e,0x3c3f,
+ 0x3c40,0x3c41,0x3c42,0x3c43,0x3c44,0x3c45,0x3c46,0x3c47,
+ 0x3c48,0x3c49,0x3c4a,0x3c4b,0x3c4c,0x3c4d,0x3c4e,0x3c4f,
+ 0x3c50,0x3c51,0x3c52,0x3c53,0x3c54,0x3c55,0x3c56,0x3c57,
+ 0x3c58,0x3c59,0x3c5a,0x3c5b,0x3c5c,0x3c5d,0x3c5e,0x3c5f,
+ 0x3c60,0x3c61,0x3c62,0x3c63,0x3c64,0x3c65,0x3c66,0x3c67,
+ 0x3c68,0x3c69,0x3c6a,0x3c6b,0x3c6c,0x3c6d,0x3c6e,0x3c6f,
+ 0x3c70,0x3c71,0x3c72,0x3c73,0x3c74,0x3c75,0x3c76,0x3c77,
+ 0x3c78,0x3c79,0x3c7a,0x3c7b,0x3c7c,0x3c7d,0x3c7e,0x3c7f,
+ 0x3c80,0x3c81,0x3c82,0x3c83,0x3c84,0x3c85,0x3c86,0x3c87,
+ 0x3c88,0x3c89,0x3c8a,0x3c8b,0x3c8c,0x3c8d,0x3c8e,0x3c8f,
+ 0x3c90,0x3c91,0x3c92,0x3c93,0x3c94,0x3c95,0x3c96,0x3c97,
+ 0x3c98,0x3c99,0x3c9a,0x3c9b,0x3c9c,0x3c9d,0x3c9e,0x3c9f,
+ 0x3ca0,0x3ca1,0x3ca2,0x3ca3,0x3ca4,0x3ca5,0x3ca6,0x3ca7,
+ 0x3ca8,0x3ca9,0x3caa,0x3cab,0x3cac,0x3cad,0x3cae,0x3caf,
+ 0x3cb0,0x3cb1,0x3cb2,0x3cb3,0x3cb4,0x3cb5,0x3cb6,0x3cb7,
+ 0x3cb8,0x3cb9,0x3cba,0x3cbb,0x3cbc,0x3cbd,0x3cbe,0x3cbf,
+ 0x3cc0,0x3cc1,0x3cc2,0x3cc3,0x3cc4,0x3cc5,0x3cc6,0x3cc7,
+ 0x3cc8,0x3cc9,0x3cca,0x3ccb,0x3ccc,0x3ccd,0x3cce,0x3ccf,
+ 0x3cd0,0x3cd1,0x3cd2,0x3cd3,0x3cd4,0x3cd5,0x3cd6,0x3cd7,
+ 0x3cd8,0x3cd9,0x3cda,0x3cdb,0x3cdc,0x3cdd,0x3cde,0x3cdf,
+ 0x3ce0,0x3ce1,0x3ce2,0x3ce3,0x3ce4,0x3ce5,0x3ce6,0x3ce7,
+ 0x3ce8,0x3ce9,0x3cea,0x3ceb,0x3cec,0x3ced,0x3cee,0x3cef,
+ 0x3cf0,0x3cf1,0x3cf2,0x3cf3,0x3cf4,0x3cf5,0x3cf6,0x3cf7,
+ 0x3cf8,0x3cf9,0x3cfa,0x3cfb,0x3cfc,0x3cfd,0x3cfe,0x3cff,
+ 0x3d00,0x3d01,0x3d02,0x3d03,0x3d04,0x3d05,0x3d06,0x3d07,
+ 0x3d08,0x3d09,0x3d0a,0x3d0b,0x3d0c,0x3d0d,0x3d0e,0x3d0f,
+ 0x3d10,0x3d11,0x3d12,0x3d13,0x3d14,0x3d15,0x3d16,0x3d17,
+ 0x3d18,0x3d19,0x3d1a,0x3d1b,0x3d1c,0x3d1d,0x3d1e,0x3d1f,
+ 0x3d20,0x3d21,0x3d22,0x3d23,0x3d24,0x3d25,0x3d26,0x3d27,
+ 0x3d28,0x3d29,0x3d2a,0x3d2b,0x3d2c,0x3d2d,0x3d2e,0x3d2f,
+ 0x3d30,0x3d31,0x3d32,0x3d33,0x3d34,0x3d35,0x3d36,0x3d37,
+ 0x3d38,0x3d39,0x3d3a,0x3d3b,0x3d3c,0x3d3d,0x3d3e,0x3d3f,
+ 0x3d40,0x3d41,0x3d42,0x3d43,0x3d44,0x3d45,0x3d46,0x3d47,
+ 0x3d48,0x3d49,0x3d4a,0x3d4b,0x3d4c,0x3d4d,0x3d4e,0x3d4f,
+ 0x3d50,0x3d51,0x3d52,0x3d53,0x3d54,0x3d55,0x3d56,0x3d57,
+ 0x3d58,0x3d59,0x3d5a,0x3d5b,0x3d5c,0x3d5d,0x3d5e,0x3d5f,
+ 0x3d60,0x3d61,0x3d62,0x3d63,0x3d64,0x3d65,0x3d66,0x3d67,
+ 0x3d68,0x3d69,0x3d6a,0x3d6b,0x3d6c,0x3d6d,0x3d6e,0x3d6f,
+ 0x3d70,0x3d71,0x3d72,0x3d73,0x3d74,0x3d75,0x3d76,0x3d77,
+ 0x3d78,0x3d79,0x3d7a,0x3d7b,0x3d7c,0x3d7d,0x3d7e,0x3d7f,
+ 0x3d80,0x3d81,0x3d82,0x3d83,0x3d84,0x3d85,0x3d86,0x3d87,
+ 0x3d88,0x3d89,0x3d8a,0x3d8b,0x3d8c,0x3d8d,0x3d8e,0x3d8f,
+ 0x3d90,0x3d91,0x3d92,0x3d93,0x3d94,0x3d95,0x3d96,0x3d97,
+ 0x3d98,0x3d99,0x3d9a,0x3d9b,0x3d9c,0x3d9d,0x3d9e,0x3d9f,
+ 0x3da0,0x3da1,0x3da2,0x3da3,0x3da4,0x3da5,0x3da6,0x3da7,
+ 0x3da8,0x3da9,0x3daa,0x3dab,0x3dac,0x3dad,0x3dae,0x3daf,
+ 0x3db0,0x3db1,0x3db2,0x3db3,0x3db4,0x3db5,0x3db6,0x3db7,
+ 0x3db8,0x3db9,0x3dba,0x3dbb,0x3dbc,0x3dbd,0x3dbe,0x3dbf,
+ 0x3dc0,0x3dc1,0x3dc2,0x3dc3,0x3dc4,0x3dc5,0x3dc6,0x3dc7,
+ 0x3dc8,0x3dc9,0x3dca,0x3dcb,0x3dcc,0x3dcd,0x3dce,0x3dcf,
+ 0x3dd0,0x3dd1,0x3dd2,0x3dd3,0x3dd4,0x3dd5,0x3dd6,0x3dd7,
+ 0x3dd8,0x3dd9,0x3dda,0x3ddb,0x3ddc,0x3ddd,0x3dde,0x3ddf,
+ 0x3de0,0x3de1,0x3de2,0x3de3,0x3de4,0x3de5,0x3de6,0x3de7,
+ 0x3de8,0x3de9,0x3dea,0x3deb,0x3dec,0x3ded,0x3dee,0x3def,
+ 0x3df0,0x3df1,0x3df2,0x3df3,0x3df4,0x3df5,0x3df6,0x3df7,
+ 0x3df8,0x3df9,0x3dfa,0x3dfb,0x3dfc,0x3dfd,0x3dfe,0x3dff,
+ 0x3e00,0x3e01,0x3e02,0x3e03,0x3e04,0x3e05,0x3e06,0x3e07,
+ 0x3e08,0x3e09,0x3e0a,0x3e0b,0x3e0c,0x3e0d,0x3e0e,0x3e0f,
+ 0x3e10,0x3e11,0x3e12,0x3e13,0x3e14,0x3e15,0x3e16,0x3e17,
+ 0x3e18,0x3e19,0x3e1a,0x3e1b,0x3e1c,0x3e1d,0x3e1e,0x3e1f,
+ 0x3e20,0x3e21,0x3e22,0x3e23,0x3e24,0x3e25,0x3e26,0x3e27,
+ 0x3e28,0x3e29,0x3e2a,0x3e2b,0x3e2c,0x3e2d,0x3e2e,0x3e2f,
+ 0x3e30,0x3e31,0x3e32,0x3e33,0x3e34,0x3e35,0x3e36,0x3e37,
+ 0x3e38,0x3e39,0x3e3a,0x3e3b,0x3e3c,0x3e3d,0x3e3e,0x3e3f,
+ 0x3e40,0x3e41,0x3e42,0x3e43,0x3e44,0x3e45,0x3e46,0x3e47,
+ 0x3e48,0x3e49,0x3e4a,0x3e4b,0x3e4c,0x3e4d,0x3e4e,0x3e4f,
+ 0x3e50,0x3e51,0x3e52,0x3e53,0x3e54,0x3e55,0x3e56,0x3e57,
+ 0x3e58,0x3e59,0x3e5a,0x3e5b,0x3e5c,0x3e5d,0x3e5e,0x3e5f,
+ 0x3e60,0x3e61,0x3e62,0x3e63,0x3e64,0x3e65,0x3e66,0x3e67,
+ 0x3e68,0x3e69,0x3e6a,0x3e6b,0x3e6c,0x3e6d,0x3e6e,0x3e6f,
+ 0x3e70,0x3e71,0x3e72,0x3e73,0x3e74,0x3e75,0x3e76,0x3e77,
+ 0x3e78,0x3e79,0x3e7a,0x3e7b,0x3e7c,0x3e7d,0x3e7e,0x3e7f,
+ 0x3e80,0x3e81,0x3e82,0x3e83,0x3e84,0x3e85,0x3e86,0x3e87,
+ 0x3e88,0x3e89,0x3e8a,0x3e8b,0x3e8c,0x3e8d,0x3e8e,0x3e8f,
+ 0x3e90,0x3e91,0x3e92,0x3e93,0x3e94,0x3e95,0x3e96,0x3e97,
+ 0x3e98,0x3e99,0x3e9a,0x3e9b,0x3e9c,0x3e9d,0x3e9e,0x3e9f,
+ 0x3ea0,0x3ea1,0x3ea2,0x3ea3,0x3ea4,0x3ea5,0x3ea6,0x3ea7,
+ 0x3ea8,0x3ea9,0x3eaa,0x3eab,0x3eac,0x3ead,0x3eae,0x3eaf,
+ 0x3eb0,0x3eb1,0x3eb2,0x3eb3,0x3eb4,0x3eb5,0x3eb6,0x3eb7,
+ 0x3eb8,0x3eb9,0x3eba,0x3ebb,0x3ebc,0x3ebd,0x3ebe,0x3ebf,
+ 0x3ec0,0x3ec1,0x3ec2,0x3ec3,0x3ec4,0x3ec5,0x3ec6,0x3ec7,
+ 0x3ec8,0x3ec9,0x3eca,0x3ecb,0x3ecc,0x3ecd,0x3ece,0x3ecf,
+ 0x3ed0,0x3ed1,0x3ed2,0x3ed3,0x3ed4,0x3ed5,0x3ed6,0x3ed7,
+ 0x3ed8,0x3ed9,0x3eda,0x3edb,0x3edc,0x3edd,0x3ede,0x3edf,
+ 0x3ee0,0x3ee1,0x3ee2,0x3ee3,0x3ee4,0x3ee5,0x3ee6,0x3ee7,
+ 0x3ee8,0x3ee9,0x3eea,0x3eeb,0x3eec,0x3eed,0x3eee,0x3eef,
+ 0x3ef0,0x3ef1,0x3ef2,0x3ef3,0x3ef4,0x3ef5,0x3ef6,0x3ef7,
+ 0x3ef8,0x3ef9,0x3efa,0x3efb,0x3efc,0x3efd,0x3efe,0x3eff,
+ 0x3f00,0x3f01,0x3f02,0x3f03,0x3f04,0x3f05,0x3f06,0x3f07,
+ 0x3f08,0x3f09,0x3f0a,0x3f0b,0x3f0c,0x3f0d,0x3f0e,0x3f0f,
+ 0x3f10,0x3f11,0x3f12,0x3f13,0x3f14,0x3f15,0x3f16,0x3f17,
+ 0x3f18,0x3f19,0x3f1a,0x3f1b,0x3f1c,0x3f1d,0x3f1e,0x3f1f,
+ 0x3f20,0x3f21,0x3f22,0x3f23,0x3f24,0x3f25,0x3f26,0x3f27,
+ 0x3f28,0x3f29,0x3f2a,0x3f2b,0x3f2c,0x3f2d,0x3f2e,0x3f2f,
+ 0x3f30,0x3f31,0x3f32,0x3f33,0x3f34,0x3f35,0x3f36,0x3f37,
+ 0x3f38,0x3f39,0x3f3a,0x3f3b,0x3f3c,0x3f3d,0x3f3e,0x3f3f,
+ 0x3f40,0x3f41,0x3f42,0x3f43,0x3f44,0x3f45,0x3f46,0x3f47,
+ 0x3f48,0x3f49,0x3f4a,0x3f4b,0x3f4c,0x3f4d,0x3f4e,0x3f4f,
+ 0x3f50,0x3f51,0x3f52,0x3f53,0x3f54,0x3f55,0x3f56,0x3f57,
+ 0x3f58,0x3f59,0x3f5a,0x3f5b,0x3f5c,0x3f5d,0x3f5e,0x3f5f,
+ 0x3f60,0x3f61,0x3f62,0x3f63,0x3f64,0x3f65,0x3f66,0x3f67,
+ 0x3f68,0x3f69,0x3f6a,0x3f6b,0x3f6c,0x3f6d,0x3f6e,0x3f6f,
+ 0x3f70,0x3f71,0x3f72,0x3f73,0x3f74,0x3f75,0x3f76,0x3f77,
+ 0x3f78,0x3f79,0x3f7a,0x3f7b,0x3f7c,0x3f7d,0x3f7e,0x3f7f,
+ 0x3f80,0x3f81,0x3f82,0x3f83,0x3f84,0x3f85,0x3f86,0x3f87,
+ 0x3f88,0x3f89,0x3f8a,0x3f8b,0x3f8c,0x3f8d,0x3f8e,0x3f8f,
+ 0x3f90,0x3f91,0x3f92,0x3f93,0x3f94,0x3f95,0x3f96,0x3f97,
+ 0x3f98,0x3f99,0x3f9a,0x3f9b,0x3f9c,0x3f9d,0x3f9e,0x3f9f,
+ 0x3fa0,0x3fa1,0x3fa2,0x3fa3,0x3fa4,0x3fa5,0x3fa6,0x3fa7,
+ 0x3fa8,0x3fa9,0x3faa,0x3fab,0x3fac,0x3fad,0x3fae,0x3faf,
+ 0x3fb0,0x3fb1,0x3fb2,0x3fb3,0x3fb4,0x3fb5,0x3fb6,0x3fb7,
+ 0x3fb8,0x3fb9,0x3fba,0x3fbb,0x3fbc,0x3fbd,0x3fbe,0x3fbf,
+ 0x3fc0,0x3fc1,0x3fc2,0x3fc3,0x3fc4,0x3fc5,0x3fc6,0x3fc7,
+ 0x3fc8,0x3fc9,0x3fca,0x3fcb,0x3fcc,0x3fcd,0x3fce,0x3fcf,
+ 0x3fd0,0x3fd1,0x3fd2,0x3fd3,0x3fd4,0x3fd5,0x3fd6,0x3fd7,
+ 0x3fd8,0x3fd9,0x3fda,0x3fdb,0x3fdc,0x3fdd,0x3fde,0x3fdf,
+ 0x3fe0,0x3fe1,0x3fe2,0x3fe3,0x3fe4,0x3fe5,0x3fe6,0x3fe7,
+ 0x3fe8,0x3fe9,0x3fea,0x3feb,0x3fec,0x3fed,0x3fee,0x3fef,
+ 0x3ff0,0x3ff1,0x3ff2,0x3ff3,0x3ff4,0x3ff5,0x3ff6,0x3ff7,
+ 0x3ff8,0x3ff9,0x3ffa,0x3ffb,0x3ffc,0x3ffd,0x3ffe,0x3fff,
+ 0x4000,0x4001,0x4002,0x4003,0x4004,0x4005,0x4006,0x4007,
+ 0x4008,0x4009,0x400a,0x400b,0x400c,0x400d,0x400e,0x400f,
+ 0x4010,0x4011,0x4012,0x4013,0x4014,0x4015,0x4016,0x4017,
+ 0x4018,0x4019,0x401a,0x401b,0x401c,0x401d,0x401e,0x401f,
+ 0x4020,0x4021,0x4022,0x4023,0x4024,0x4025,0x4026,0x4027,
+ 0x4028,0x4029,0x402a,0x402b,0x402c,0x402d,0x402e,0x402f,
+ 0x4030,0x4031,0x4032,0x4033,0x4034,0x4035,0x4036,0x4037,
+ 0x4038,0x4039,0x403a,0x403b,0x403c,0x403d,0x403e,0x403f,
+ 0x4040,0x4041,0x4042,0x4043,0x4044,0x4045,0x4046,0x4047,
+ 0x4048,0x4049,0x404a,0x404b,0x404c,0x404d,0x404e,0x404f,
+ 0x4050,0x4051,0x4052,0x4053,0x4054,0x4055,0x4056,0x4057,
+ 0x4058,0x4059,0x405a,0x405b,0x405c,0x405d,0x405e,0x405f,
+ 0x4060,0x4061,0x4062,0x4063,0x4064,0x4065,0x4066,0x4067,
+ 0x4068,0x4069,0x406a,0x406b,0x406c,0x406d,0x406e,0x406f,
+ 0x4070,0x4071,0x4072,0x4073,0x4074,0x4075,0x4076,0x4077,
+ 0x4078,0x4079,0x407a,0x407b,0x407c,0x407d,0x407e,0x407f,
+ 0x4080,0x4081,0x4082,0x4083,0x4084,0x4085,0x4086,0x4087,
+ 0x4088,0x4089,0x408a,0x408b,0x408c,0x408d,0x408e,0x408f,
+ 0x4090,0x4091,0x4092,0x4093,0x4094,0x4095,0x4096,0x4097,
+ 0x4098,0x4099,0x409a,0x409b,0x409c,0x409d,0x409e,0x409f,
+ 0x40a0,0x40a1,0x40a2,0x40a3,0x40a4,0x40a5,0x40a6,0x40a7,
+ 0x40a8,0x40a9,0x40aa,0x40ab,0x40ac,0x40ad,0x40ae,0x40af,
+ 0x40b0,0x40b1,0x40b2,0x40b3,0x40b4,0x40b5,0x40b6,0x40b7,
+ 0x40b8,0x40b9,0x40ba,0x40bb,0x40bc,0x40bd,0x40be,0x40bf,
+ 0x40c0,0x40c1,0x40c2,0x40c3,0x40c4,0x40c5,0x40c6,0x40c7,
+ 0x40c8,0x40c9,0x40ca,0x40cb,0x40cc,0x40cd,0x40ce,0x40cf,
+ 0x40d0,0x40d1,0x40d2,0x40d3,0x40d4,0x40d5,0x40d6,0x40d7,
+ 0x40d8,0x40d9,0x40da,0x40db,0x40dc,0x40dd,0x40de,0x40df,
+ 0x40e0,0x40e1,0x40e2,0x40e3,0x40e4,0x40e5,0x40e6,0x40e7,
+ 0x40e8,0x40e9,0x40ea,0x40eb,0x40ec,0x40ed,0x40ee,0x40ef,
+ 0x40f0,0x40f1,0x40f2,0x40f3,0x40f4,0x40f5,0x40f6,0x40f7,
+ 0x40f8,0x40f9,0x40fa,0x40fb,0x40fc,0x40fd,0x40fe,0x40ff,
+ 0x4100,0x4101,0x4102,0x4103,0x4104,0x4105,0x4106,0x4107,
+ 0x4108,0x4109,0x410a,0x410b,0x410c,0x410d,0x410e,0x410f,
+ 0x4110,0x4111,0x4112,0x4113,0x4114,0x4115,0x4116,0x4117,
+ 0x4118,0x4119,0x411a,0x411b,0x411c,0x411d,0x411e,0x411f,
+ 0x4120,0x4121,0x4122,0x4123,0x4124,0x4125,0x4126,0x4127,
+ 0x4128,0x4129,0x412a,0x412b,0x412c,0x412d,0x412e,0x412f,
+ 0x4130,0x4131,0x4132,0x4133,0x4134,0x4135,0x4136,0x4137,
+ 0x4138,0x4139,0x413a,0x413b,0x413c,0x413d,0x413e,0x413f,
+ 0x4140,0x4141,0x4142,0x4143,0x4144,0x4145,0x4146,0x4147,
+ 0x4148,0x4149,0x414a,0x414b,0x414c,0x414d,0x414e,0x414f,
+ 0x4150,0x4151,0x4152,0x4153,0x4154,0x4155,0x4156,0x4157,
+ 0x4158,0x4159,0x415a,0x415b,0x415c,0x415d,0x415e,0x415f,
+ 0x4160,0x4161,0x4162,0x4163,0x4164,0x4165,0x4166,0x4167,
+ 0x4168,0x4169,0x416a,0x416b,0x416c,0x416d,0x416e,0x416f,
+ 0x4170,0x4171,0x4172,0x4173,0x4174,0x4175,0x4176,0x4177,
+ 0x4178,0x4179,0x417a,0x417b,0x417c,0x417d,0x417e,0x417f,
+ 0x4180,0x4181,0x4182,0x4183,0x4184,0x4185,0x4186,0x4187,
+ 0x4188,0x4189,0x418a,0x418b,0x418c,0x418d,0x418e,0x418f,
+ 0x4190,0x4191,0x4192,0x4193,0x4194,0x4195,0x4196,0x4197,
+ 0x4198,0x4199,0x419a,0x419b,0x419c,0x419d,0x419e,0x419f,
+ 0x41a0,0x41a1,0x41a2,0x41a3,0x41a4,0x41a5,0x41a6,0x41a7,
+ 0x41a8,0x41a9,0x41aa,0x41ab,0x41ac,0x41ad,0x41ae,0x41af,
+ 0x41b0,0x41b1,0x41b2,0x41b3,0x41b4,0x41b5,0x41b6,0x41b7,
+ 0x41b8,0x41b9,0x41ba,0x41bb,0x41bc,0x41bd,0x41be,0x41bf,
+ 0x41c0,0x41c1,0x41c2,0x41c3,0x41c4,0x41c5,0x41c6,0x41c7,
+ 0x41c8,0x41c9,0x41ca,0x41cb,0x41cc,0x41cd,0x41ce,0x41cf,
+ 0x41d0,0x41d1,0x41d2,0x41d3,0x41d4,0x41d5,0x41d6,0x41d7,
+ 0x41d8,0x41d9,0x41da,0x41db,0x41dc,0x41dd,0x41de,0x41df,
+ 0x41e0,0x41e1,0x41e2,0x41e3,0x41e4,0x41e5,0x41e6,0x41e7,
+ 0x41e8,0x41e9,0x41ea,0x41eb,0x41ec,0x41ed,0x41ee,0x41ef,
+ 0x41f0,0x41f1,0x41f2,0x41f3,0x41f4,0x41f5,0x41f6,0x41f7,
+ 0x41f8,0x41f9,0x41fa,0x41fb,0x41fc,0x41fd,0x41fe,0x41ff,
+ 0x4200,0x4201,0x4202,0x4203,0x4204,0x4205,0x4206,0x4207,
+ 0x4208,0x4209,0x420a,0x420b,0x420c,0x420d,0x420e,0x420f,
+ 0x4210,0x4211,0x4212,0x4213,0x4214,0x4215,0x4216,0x4217,
+ 0x4218,0x4219,0x421a,0x421b,0x421c,0x421d,0x421e,0x421f,
+ 0x4220,0x4221,0x4222,0x4223,0x4224,0x4225,0x4226,0x4227,
+ 0x4228,0x4229,0x422a,0x422b,0x422c,0x422d,0x422e,0x422f,
+ 0x4230,0x4231,0x4232,0x4233,0x4234,0x4235,0x4236,0x4237,
+ 0x4238,0x4239,0x423a,0x423b,0x423c,0x423d,0x423e,0x423f,
+ 0x4240,0x4241,0x4242,0x4243,0x4244,0x4245,0x4246,0x4247,
+ 0x4248,0x4249,0x424a,0x424b,0x424c,0x424d,0x424e,0x424f,
+ 0x4250,0x4251,0x4252,0x4253,0x4254,0x4255,0x4256,0x4257,
+ 0x4258,0x4259,0x425a,0x425b,0x425c,0x425d,0x425e,0x425f,
+ 0x4260,0x4261,0x4262,0x4263,0x4264,0x4265,0x4266,0x4267,
+ 0x4268,0x4269,0x426a,0x426b,0x426c,0x426d,0x426e,0x426f,
+ 0x4270,0x4271,0x4272,0x4273,0x4274,0x4275,0x4276,0x4277,
+ 0x4278,0x4279,0x427a,0x427b,0x427c,0x427d,0x427e,0x427f,
+ 0x4280,0x4281,0x4282,0x4283,0x4284,0x4285,0x4286,0x4287,
+ 0x4288,0x4289,0x428a,0x428b,0x428c,0x428d,0x428e,0x428f,
+ 0x4290,0x4291,0x4292,0x4293,0x4294,0x4295,0x4296,0x4297,
+ 0x4298,0x4299,0x429a,0x429b,0x429c,0x429d,0x429e,0x429f,
+ 0x42a0,0x42a1,0x42a2,0x42a3,0x42a4,0x42a5,0x42a6,0x42a7,
+ 0x42a8,0x42a9,0x42aa,0x42ab,0x42ac,0x42ad,0x42ae,0x42af,
+ 0x42b0,0x42b1,0x42b2,0x42b3,0x42b4,0x42b5,0x42b6,0x42b7,
+ 0x42b8,0x42b9,0x42ba,0x42bb,0x42bc,0x42bd,0x42be,0x42bf,
+ 0x42c0,0x42c1,0x42c2,0x42c3,0x42c4,0x42c5,0x42c6,0x42c7,
+ 0x42c8,0x42c9,0x42ca,0x42cb,0x42cc,0x42cd,0x42ce,0x42cf,
+ 0x42d0,0x42d1,0x42d2,0x42d3,0x42d4,0x42d5,0x42d6,0x42d7,
+ 0x42d8,0x42d9,0x42da,0x42db,0x42dc,0x42dd,0x42de,0x42df,
+ 0x42e0,0x42e1,0x42e2,0x42e3,0x42e4,0x42e5,0x42e6,0x42e7,
+ 0x42e8,0x42e9,0x42ea,0x42eb,0x42ec,0x42ed,0x42ee,0x42ef,
+ 0x42f0,0x42f1,0x42f2,0x42f3,0x42f4,0x42f5,0x42f6,0x42f7,
+ 0x42f8,0x42f9,0x42fa,0x42fb,0x42fc,0x42fd,0x42fe,0x42ff,
+ 0x4300,0x4301,0x4302,0x4303,0x4304,0x4305,0x4306,0x4307,
+ 0x4308,0x4309,0x430a,0x430b,0x430c,0x430d,0x430e,0x430f,
+ 0x4310,0x4311,0x4312,0x4313,0x4314,0x4315,0x4316,0x4317,
+ 0x4318,0x4319,0x431a,0x431b,0x431c,0x431d,0x431e,0x431f,
+ 0x4320,0x4321,0x4322,0x4323,0x4324,0x4325,0x4326,0x4327,
+ 0x4328,0x4329,0x432a,0x432b,0x432c,0x432d,0x432e,0x432f,
+ 0x4330,0x4331,0x4332,0x4333,0x4334,0x4335,0x4336,0x4337,
+ 0x4338,0x4339,0x433a,0x433b,0x433c,0x433d,0x433e,0x433f,
+ 0x4340,0x4341,0x4342,0x4343,0x4344,0x4345,0x4346,0x4347,
+ 0x4348,0x4349,0x434a,0x434b,0x434c,0x434d,0x434e,0x434f,
+ 0x4350,0x4351,0x4352,0x4353,0x4354,0x4355,0x4356,0x4357,
+ 0x4358,0x4359,0x435a,0x435b,0x435c,0x435d,0x435e,0x435f,
+ 0x4360,0x4361,0x4362,0x4363,0x4364,0x4365,0x4366,0x4367,
+ 0x4368,0x4369,0x436a,0x436b,0x436c,0x436d,0x436e,0x436f,
+ 0x4370,0x4371,0x4372,0x4373,0x4374,0x4375,0x4376,0x4377,
+ 0x4378,0x4379,0x437a,0x437b,0x437c,0x437d,0x437e,0x437f,
+ 0x4380,0x4381,0x4382,0x4383,0x4384,0x4385,0x4386,0x4387,
+ 0x4388,0x4389,0x438a,0x438b,0x438c,0x438d,0x438e,0x438f,
+ 0x4390,0x4391,0x4392,0x4393,0x4394,0x4395,0x4396,0x4397,
+ 0x4398,0x4399,0x439a,0x439b,0x439c,0x439d,0x439e,0x439f,
+ 0x43a0,0x43a1,0x43a2,0x43a3,0x43a4,0x43a5,0x43a6,0x43a7,
+ 0x43a8,0x43a9,0x43aa,0x43ab,0x43ac,0x43ad,0x43ae,0x43af,
+ 0x43b0,0x43b1,0x43b2,0x43b3,0x43b4,0x43b5,0x43b6,0x43b7,
+ 0x43b8,0x43b9,0x43ba,0x43bb,0x43bc,0x43bd,0x43be,0x43bf,
+ 0x43c0,0x43c1,0x43c2,0x43c3,0x43c4,0x43c5,0x43c6,0x43c7,
+ 0x43c8,0x43c9,0x43ca,0x43cb,0x43cc,0x43cd,0x43ce,0x43cf,
+ 0x43d0,0x43d1,0x43d2,0x43d3,0x43d4,0x43d5,0x43d6,0x43d7,
+ 0x43d8,0x43d9,0x43da,0x43db,0x43dc,0x43dd,0x43de,0x43df,
+ 0x43e0,0x43e1,0x43e2,0x43e3,0x43e4,0x43e5,0x43e6,0x43e7,
+ 0x43e8,0x43e9,0x43ea,0x43eb,0x43ec,0x43ed,0x43ee,0x43ef,
+ 0x43f0,0x43f1,0x43f2,0x43f3,0x43f4,0x43f5,0x43f6,0x43f7,
+ 0x43f8,0x43f9,0x43fa,0x43fb,0x43fc,0x43fd,0x43fe,0x43ff,
+ 0x4400,0x4401,0x4402,0x4403,0x4404,0x4405,0x4406,0x4407,
+ 0x4408,0x4409,0x440a,0x440b,0x440c,0x440d,0x440e,0x440f,
+ 0x4410,0x4411,0x4412,0x4413,0x4414,0x4415,0x4416,0x4417,
+ 0x4418,0x4419,0x441a,0x441b,0x441c,0x441d,0x441e,0x441f,
+ 0x4420,0x4421,0x4422,0x4423,0x4424,0x4425,0x4426,0x4427,
+ 0x4428,0x4429,0x442a,0x442b,0x442c,0x442d,0x442e,0x442f,
+ 0x4430,0x4431,0x4432,0x4433,0x4434,0x4435,0x4436,0x4437,
+ 0x4438,0x4439,0x443a,0x443b,0x443c,0x443d,0x443e,0x443f,
+ 0x4440,0x4441,0x4442,0x4443,0x4444,0x4445,0x4446,0x4447,
+ 0x4448,0x4449,0x444a,0x444b,0x444c,0x444d,0x444e,0x444f,
+ 0x4450,0x4451,0x4452,0x4453,0x4454,0x4455,0x4456,0x4457,
+ 0x4458,0x4459,0x445a,0x445b,0x445c,0x445d,0x445e,0x445f,
+ 0x4460,0x4461,0x4462,0x4463,0x4464,0x4465,0x4466,0x4467,
+ 0x4468,0x4469,0x446a,0x446b,0x446c,0x446d,0x446e,0x446f,
+ 0x4470,0x4471,0x4472,0x4473,0x4474,0x4475,0x4476,0x4477,
+ 0x4478,0x4479,0x447a,0x447b,0x447c,0x447d,0x447e,0x447f,
+ 0x4480,0x4481,0x4482,0x4483,0x4484,0x4485,0x4486,0x4487,
+ 0x4488,0x4489,0x448a,0x448b,0x448c,0x448d,0x448e,0x448f,
+ 0x4490,0x4491,0x4492,0x4493,0x4494,0x4495,0x4496,0x4497,
+ 0x4498,0x4499,0x449a,0x449b,0x449c,0x449d,0x449e,0x449f,
+ 0x44a0,0x44a1,0x44a2,0x44a3,0x44a4,0x44a5,0x44a6,0x44a7,
+ 0x44a8,0x44a9,0x44aa,0x44ab,0x44ac,0x44ad,0x44ae,0x44af,
+ 0x44b0,0x44b1,0x44b2,0x44b3,0x44b4,0x44b5,0x44b6,0x44b7,
+ 0x44b8,0x44b9,0x44ba,0x44bb,0x44bc,0x44bd,0x44be,0x44bf,
+ 0x44c0,0x44c1,0x44c2,0x44c3,0x44c4,0x44c5,0x44c6,0x44c7,
+ 0x44c8,0x44c9,0x44ca,0x44cb,0x44cc,0x44cd,0x44ce,0x44cf,
+ 0x44d0,0x44d1,0x44d2,0x44d3,0x44d4,0x44d5,0x44d6,0x44d7,
+ 0x44d8,0x44d9,0x44da,0x44db,0x44dc,0x44dd,0x44de,0x44df,
+ 0x44e0,0x44e1,0x44e2,0x44e3,0x44e4,0x44e5,0x44e6,0x44e7,
+ 0x44e8,0x44e9,0x44ea,0x44eb,0x44ec,0x44ed,0x44ee,0x44ef,
+ 0x44f0,0x44f1,0x44f2,0x44f3,0x44f4,0x44f5,0x44f6,0x44f7,
+ 0x44f8,0x44f9,0x44fa,0x44fb,0x44fc,0x44fd,0x44fe,0x44ff,
+ 0x4500,0x4501,0x4502,0x4503,0x4504,0x4505,0x4506,0x4507,
+ 0x4508,0x4509,0x450a,0x450b,0x450c,0x450d,0x450e,0x450f,
+ 0x4510,0x4511,0x4512,0x4513,0x4514,0x4515,0x4516,0x4517,
+ 0x4518,0x4519,0x451a,0x451b,0x451c,0x451d,0x451e,0x451f,
+ 0x4520,0x4521,0x4522,0x4523,0x4524,0x4525,0x4526,0x4527,
+ 0x4528,0x4529,0x452a,0x452b,0x452c,0x452d,0x452e,0x452f,
+ 0x4530,0x4531,0x4532,0x4533,0x4534,0x4535,0x4536,0x4537,
+ 0x4538,0x4539,0x453a,0x453b,0x453c,0x453d,0x453e,0x453f,
+ 0x4540,0x4541,0x4542,0x4543,0x4544,0x4545,0x4546,0x4547,
+ 0x4548,0x4549,0x454a,0x454b,0x454c,0x454d,0x454e,0x454f,
+ 0x4550,0x4551,0x4552,0x4553,0x4554,0x4555,0x4556,0x4557,
+ 0x4558,0x4559,0x455a,0x455b,0x455c,0x455d,0x455e,0x455f,
+ 0x4560,0x4561,0x4562,0x4563,0x4564,0x4565,0x4566,0x4567,
+ 0x4568,0x4569,0x456a,0x456b,0x456c,0x456d,0x456e,0x456f,
+ 0x4570,0x4571,0x4572,0x4573,0x4574,0x4575,0x4576,0x4577,
+ 0x4578,0x4579,0x457a,0x457b,0x457c,0x457d,0x457e,0x457f,
+ 0x4580,0x4581,0x4582,0x4583,0x4584,0x4585,0x4586,0x4587,
+ 0x4588,0x4589,0x458a,0x458b,0x458c,0x458d,0x458e,0x458f,
+ 0x4590,0x4591,0x4592,0x4593,0x4594,0x4595,0x4596,0x4597,
+ 0x4598,0x4599,0x459a,0x459b,0x459c,0x459d,0x459e,0x459f,
+ 0x45a0,0x45a1,0x45a2,0x45a3,0x45a4,0x45a5,0x45a6,0x45a7,
+ 0x45a8,0x45a9,0x45aa,0x45ab,0x45ac,0x45ad,0x45ae,0x45af,
+ 0x45b0,0x45b1,0x45b2,0x45b3,0x45b4,0x45b5,0x45b6,0x45b7,
+ 0x45b8,0x45b9,0x45ba,0x45bb,0x45bc,0x45bd,0x45be,0x45bf,
+ 0x45c0,0x45c1,0x45c2,0x45c3,0x45c4,0x45c5,0x45c6,0x45c7,
+ 0x45c8,0x45c9,0x45ca,0x45cb,0x45cc,0x45cd,0x45ce,0x45cf,
+ 0x45d0,0x45d1,0x45d2,0x45d3,0x45d4,0x45d5,0x45d6,0x45d7,
+ 0x45d8,0x45d9,0x45da,0x45db,0x45dc,0x45dd,0x45de,0x45df,
+ 0x45e0,0x45e1,0x45e2,0x45e3,0x45e4,0x45e5,0x45e6,0x45e7,
+ 0x45e8,0x45e9,0x45ea,0x45eb,0x45ec,0x45ed,0x45ee,0x45ef,
+ 0x45f0,0x45f1,0x45f2,0x45f3,0x45f4,0x45f5,0x45f6,0x45f7,
+ 0x45f8,0x45f9,0x45fa,0x45fb,0x45fc,0x45fd,0x45fe,0x45ff,
+ 0x4600,0x4601,0x4602,0x4603,0x4604,0x4605,0x4606,0x4607,
+ 0x4608,0x4609,0x460a,0x460b,0x460c,0x460d,0x460e,0x460f,
+ 0x4610,0x4611,0x4612,0x4613,0x4614,0x4615,0x4616,0x4617,
+ 0x4618,0x4619,0x461a,0x461b,0x461c,0x461d,0x461e,0x461f,
+ 0x4620,0x4621,0x4622,0x4623,0x4624,0x4625,0x4626,0x4627,
+ 0x4628,0x4629,0x462a,0x462b,0x462c,0x462d,0x462e,0x462f,
+ 0x4630,0x4631,0x4632,0x4633,0x4634,0x4635,0x4636,0x4637,
+ 0x4638,0x4639,0x463a,0x463b,0x463c,0x463d,0x463e,0x463f,
+ 0x4640,0x4641,0x4642,0x4643,0x4644,0x4645,0x4646,0x4647,
+ 0x4648,0x4649,0x464a,0x464b,0x464c,0x464d,0x464e,0x464f,
+ 0x4650,0x4651,0x4652,0x4653,0x4654,0x4655,0x4656,0x4657,
+ 0x4658,0x4659,0x465a,0x465b,0x465c,0x465d,0x465e,0x465f,
+ 0x4660,0x4661,0x4662,0x4663,0x4664,0x4665,0x4666,0x4667,
+ 0x4668,0x4669,0x466a,0x466b,0x466c,0x466d,0x466e,0x466f,
+ 0x4670,0x4671,0x4672,0x4673,0x4674,0x4675,0x4676,0x4677,
+ 0x4678,0x4679,0x467a,0x467b,0x467c,0x467d,0x467e,0x467f,
+ 0x4680,0x4681,0x4682,0x4683,0x4684,0x4685,0x4686,0x4687,
+ 0x4688,0x4689,0x468a,0x468b,0x468c,0x468d,0x468e,0x468f,
+ 0x4690,0x4691,0x4692,0x4693,0x4694,0x4695,0x4696,0x4697,
+ 0x4698,0x4699,0x469a,0x469b,0x469c,0x469d,0x469e,0x469f,
+ 0x46a0,0x46a1,0x46a2,0x46a3,0x46a4,0x46a5,0x46a6,0x46a7,
+ 0x46a8,0x46a9,0x46aa,0x46ab,0x46ac,0x46ad,0x46ae,0x46af,
+ 0x46b0,0x46b1,0x46b2,0x46b3,0x46b4,0x46b5,0x46b6,0x46b7,
+ 0x46b8,0x46b9,0x46ba,0x46bb,0x46bc,0x46bd,0x46be,0x46bf,
+ 0x46c0,0x46c1,0x46c2,0x46c3,0x46c4,0x46c5,0x46c6,0x46c7,
+ 0x46c8,0x46c9,0x46ca,0x46cb,0x46cc,0x46cd,0x46ce,0x46cf,
+ 0x46d0,0x46d1,0x46d2,0x46d3,0x46d4,0x46d5,0x46d6,0x46d7,
+ 0x46d8,0x46d9,0x46da,0x46db,0x46dc,0x46dd,0x46de,0x46df,
+ 0x46e0,0x46e1,0x46e2,0x46e3,0x46e4,0x46e5,0x46e6,0x46e7,
+ 0x46e8,0x46e9,0x46ea,0x46eb,0x46ec,0x46ed,0x46ee,0x46ef,
+ 0x46f0,0x46f1,0x46f2,0x46f3,0x46f4,0x46f5,0x46f6,0x46f7,
+ 0x46f8,0x46f9,0x46fa,0x46fb,0x46fc,0x46fd,0x46fe,0x46ff,
+ 0x4700,0x4701,0x4702,0x4703,0x4704,0x4705,0x4706,0x4707,
+ 0x4708,0x4709,0x470a,0x470b,0x470c,0x470d,0x470e,0x470f,
+ 0x4710,0x4711,0x4712,0x4713,0x4714,0x4715,0x4716,0x4717,
+ 0x4718,0x4719,0x471a,0x471b,0x471c,0x471d,0x471e,0x471f,
+ 0x4720,0x4721,0x4722,0x4723,0x4724,0x4725,0x4726,0x4727,
+ 0x4728,0x4729,0x472a,0x472b,0x472c,0x472d,0x472e,0x472f,
+ 0x4730,0x4731,0x4732,0x4733,0x4734,0x4735,0x4736,0x4737,
+ 0x4738,0x4739,0x473a,0x473b,0x473c,0x473d,0x473e,0x473f,
+ 0x4740,0x4741,0x4742,0x4743,0x4744,0x4745,0x4746,0x4747,
+ 0x4748,0x4749,0x474a,0x474b,0x474c,0x474d,0x474e,0x474f,
+ 0x4750,0x4751,0x4752,0x4753,0x4754,0x4755,0x4756,0x4757,
+ 0x4758,0x4759,0x475a,0x475b,0x475c,0x475d,0x475e,0x475f,
+ 0x4760,0x4761,0x4762,0x4763,0x4764,0x4765,0x4766,0x4767,
+ 0x4768,0x4769,0x476a,0x476b,0x476c,0x476d,0x476e,0x476f,
+ 0x4770,0x4771,0x4772,0x4773,0x4774,0x4775,0x4776,0x4777,
+ 0x4778,0x4779,0x477a,0x477b,0x477c,0x477d,0x477e,0x477f,
+ 0x4780,0x4781,0x4782,0x4783,0x4784,0x4785,0x4786,0x4787,
+ 0x4788,0x4789,0x478a,0x478b,0x478c,0x478d,0x478e,0x478f,
+ 0x4790,0x4791,0x4792,0x4793,0x4794,0x4795,0x4796,0x4797,
+ 0x4798,0x4799,0x479a,0x479b,0x479c,0x479d,0x479e,0x479f,
+ 0x47a0,0x47a1,0x47a2,0x47a3,0x47a4,0x47a5,0x47a6,0x47a7,
+ 0x47a8,0x47a9,0x47aa,0x47ab,0x47ac,0x47ad,0x47ae,0x47af,
+ 0x47b0,0x47b1,0x47b2,0x47b3,0x47b4,0x47b5,0x47b6,0x47b7,
+ 0x47b8,0x47b9,0x47ba,0x47bb,0x47bc,0x47bd,0x47be,0x47bf,
+ 0x47c0,0x47c1,0x47c2,0x47c3,0x47c4,0x47c5,0x47c6,0x47c7,
+ 0x47c8,0x47c9,0x47ca,0x47cb,0x47cc,0x47cd,0x47ce,0x47cf,
+ 0x47d0,0x47d1,0x47d2,0x47d3,0x47d4,0x47d5,0x47d6,0x47d7,
+ 0x47d8,0x47d9,0x47da,0x47db,0x47dc,0x47dd,0x47de,0x47df,
+ 0x47e0,0x47e1,0x47e2,0x47e3,0x47e4,0x47e5,0x47e6,0x47e7,
+ 0x47e8,0x47e9,0x47ea,0x47eb,0x47ec,0x47ed,0x47ee,0x47ef,
+ 0x47f0,0x47f1,0x47f2,0x47f3,0x47f4,0x47f5,0x47f6,0x47f7,
+ 0x47f8,0x47f9,0x47fa,0x47fb,0x47fc,0x47fd,0x47fe,0x47ff,
+ 0x4800,0x4801,0x4802,0x4803,0x4804,0x4805,0x4806,0x4807,
+ 0x4808,0x4809,0x480a,0x480b,0x480c,0x480d,0x480e,0x480f,
+ 0x4810,0x4811,0x4812,0x4813,0x4814,0x4815,0x4816,0x4817,
+ 0x4818,0x4819,0x481a,0x481b,0x481c,0x481d,0x481e,0x481f,
+ 0x4820,0x4821,0x4822,0x4823,0x4824,0x4825,0x4826,0x4827,
+ 0x4828,0x4829,0x482a,0x482b,0x482c,0x482d,0x482e,0x482f,
+ 0x4830,0x4831,0x4832,0x4833,0x4834,0x4835,0x4836,0x4837,
+ 0x4838,0x4839,0x483a,0x483b,0x483c,0x483d,0x483e,0x483f,
+ 0x4840,0x4841,0x4842,0x4843,0x4844,0x4845,0x4846,0x4847,
+ 0x4848,0x4849,0x484a,0x484b,0x484c,0x484d,0x484e,0x484f,
+ 0x4850,0x4851,0x4852,0x4853,0x4854,0x4855,0x4856,0x4857,
+ 0x4858,0x4859,0x485a,0x485b,0x485c,0x485d,0x485e,0x485f,
+ 0x4860,0x4861,0x4862,0x4863,0x4864,0x4865,0x4866,0x4867,
+ 0x4868,0x4869,0x486a,0x486b,0x486c,0x486d,0x486e,0x486f,
+ 0x4870,0x4871,0x4872,0x4873,0x4874,0x4875,0x4876,0x4877,
+ 0x4878,0x4879,0x487a,0x487b,0x487c,0x487d,0x487e,0x487f,
+ 0x4880,0x4881,0x4882,0x4883,0x4884,0x4885,0x4886,0x4887,
+ 0x4888,0x4889,0x488a,0x488b,0x488c,0x488d,0x488e,0x488f,
+ 0x4890,0x4891,0x4892,0x4893,0x4894,0x4895,0x4896,0x4897,
+ 0x4898,0x4899,0x489a,0x489b,0x489c,0x489d,0x489e,0x489f,
+ 0x48a0,0x48a1,0x48a2,0x48a3,0x48a4,0x48a5,0x48a6,0x48a7,
+ 0x48a8,0x48a9,0x48aa,0x48ab,0x48ac,0x48ad,0x48ae,0x48af,
+ 0x48b0,0x48b1,0x48b2,0x48b3,0x48b4,0x48b5,0x48b6,0x48b7,
+ 0x48b8,0x48b9,0x48ba,0x48bb,0x48bc,0x48bd,0x48be,0x48bf,
+ 0x48c0,0x48c1,0x48c2,0x48c3,0x48c4,0x48c5,0x48c6,0x48c7,
+ 0x48c8,0x48c9,0x48ca,0x48cb,0x48cc,0x48cd,0x48ce,0x48cf,
+ 0x48d0,0x48d1,0x48d2,0x48d3,0x48d4,0x48d5,0x48d6,0x48d7,
+ 0x48d8,0x48d9,0x48da,0x48db,0x48dc,0x48dd,0x48de,0x48df,
+ 0x48e0,0x48e1,0x48e2,0x48e3,0x48e4,0x48e5,0x48e6,0x48e7,
+ 0x48e8,0x48e9,0x48ea,0x48eb,0x48ec,0x48ed,0x48ee,0x48ef,
+ 0x48f0,0x48f1,0x48f2,0x48f3,0x48f4,0x48f5,0x48f6,0x48f7,
+ 0x48f8,0x48f9,0x48fa,0x48fb,0x48fc,0x48fd,0x48fe,0x48ff,
+ 0x4900,0x4901,0x4902,0x4903,0x4904,0x4905,0x4906,0x4907,
+ 0x4908,0x4909,0x490a,0x490b,0x490c,0x490d,0x490e,0x490f,
+ 0x4910,0x4911,0x4912,0x4913,0x4914,0x4915,0x4916,0x4917,
+ 0x4918,0x4919,0x491a,0x491b,0x491c,0x491d,0x491e,0x491f,
+ 0x4920,0x4921,0x4922,0x4923,0x4924,0x4925,0x4926,0x4927,
+ 0x4928,0x4929,0x492a,0x492b,0x492c,0x492d,0x492e,0x492f,
+ 0x4930,0x4931,0x4932,0x4933,0x4934,0x4935,0x4936,0x4937,
+ 0x4938,0x4939,0x493a,0x493b,0x493c,0x493d,0x493e,0x493f,
+ 0x4940,0x4941,0x4942,0x4943,0x4944,0x4945,0x4946,0x4947,
+ 0x4948,0x4949,0x494a,0x494b,0x494c,0x494d,0x494e,0x494f,
+ 0x4950,0x4951,0x4952,0x4953,0x4954,0x4955,0x4956,0x4957,
+ 0x4958,0x4959,0x495a,0x495b,0x495c,0x495d,0x495e,0x495f,
+ 0x4960,0x4961,0x4962,0x4963,0x4964,0x4965,0x4966,0x4967,
+ 0x4968,0x4969,0x496a,0x496b,0x496c,0x496d,0x496e,0x496f,
+ 0x4970,0x4971,0x4972,0x4973,0x4974,0x4975,0x4976,0x4977,
+ 0x4978,0x4979,0x497a,0x497b,0x497c,0x497d,0x497e,0x497f,
+ 0x4980,0x4981,0x4982,0x4983,0x4984,0x4985,0x4986,0x4987,
+ 0x4988,0x4989,0x498a,0x498b,0x498c,0x498d,0x498e,0x498f,
+ 0x4990,0x4991,0x4992,0x4993,0x4994,0x4995,0x4996,0x4997,
+ 0x4998,0x4999,0x499a,0x499b,0x499c,0x499d,0x499e,0x499f,
+ 0x49a0,0x49a1,0x49a2,0x49a3,0x49a4,0x49a5,0x49a6,0x49a7,
+ 0x49a8,0x49a9,0x49aa,0x49ab,0x49ac,0x49ad,0x49ae,0x49af,
+ 0x49b0,0x49b1,0x49b2,0x49b3,0x49b4,0x49b5,0x49b6,0x49b7,
+ 0x49b8,0x49b9,0x49ba,0x49bb,0x49bc,0x49bd,0x49be,0x49bf,
+ 0x49c0,0x49c1,0x49c2,0x49c3,0x49c4,0x49c5,0x49c6,0x49c7,
+ 0x49c8,0x49c9,0x49ca,0x49cb,0x49cc,0x49cd,0x49ce,0x49cf,
+ 0x49d0,0x49d1,0x49d2,0x49d3,0x49d4,0x49d5,0x49d6,0x49d7,
+ 0x49d8,0x49d9,0x49da,0x49db,0x49dc,0x49dd,0x49de,0x49df,
+ 0x49e0,0x49e1,0x49e2,0x49e3,0x49e4,0x49e5,0x49e6,0x49e7,
+ 0x49e8,0x49e9,0x49ea,0x49eb,0x49ec,0x49ed,0x49ee,0x49ef,
+ 0x49f0,0x49f1,0x49f2,0x49f3,0x49f4,0x49f5,0x49f6,0x49f7,
+ 0x49f8,0x49f9,0x49fa,0x49fb,0x49fc,0x49fd,0x49fe,0x49ff,
+ 0x4a00,0x4a01,0x4a02,0x4a03,0x4a04,0x4a05,0x4a06,0x4a07,
+ 0x4a08,0x4a09,0x4a0a,0x4a0b,0x4a0c,0x4a0d,0x4a0e,0x4a0f,
+ 0x4a10,0x4a11,0x4a12,0x4a13,0x4a14,0x4a15,0x4a16,0x4a17,
+ 0x4a18,0x4a19,0x4a1a,0x4a1b,0x4a1c,0x4a1d,0x4a1e,0x4a1f,
+ 0x4a20,0x4a21,0x4a22,0x4a23,0x4a24,0x4a25,0x4a26,0x4a27,
+ 0x4a28,0x4a29,0x4a2a,0x4a2b,0x4a2c,0x4a2d,0x4a2e,0x4a2f,
+ 0x4a30,0x4a31,0x4a32,0x4a33,0x4a34,0x4a35,0x4a36,0x4a37,
+ 0x4a38,0x4a39,0x4a3a,0x4a3b,0x4a3c,0x4a3d,0x4a3e,0x4a3f,
+ 0x4a40,0x4a41,0x4a42,0x4a43,0x4a44,0x4a45,0x4a46,0x4a47,
+ 0x4a48,0x4a49,0x4a4a,0x4a4b,0x4a4c,0x4a4d,0x4a4e,0x4a4f,
+ 0x4a50,0x4a51,0x4a52,0x4a53,0x4a54,0x4a55,0x4a56,0x4a57,
+ 0x4a58,0x4a59,0x4a5a,0x4a5b,0x4a5c,0x4a5d,0x4a5e,0x4a5f,
+ 0x4a60,0x4a61,0x4a62,0x4a63,0x4a64,0x4a65,0x4a66,0x4a67,
+ 0x4a68,0x4a69,0x4a6a,0x4a6b,0x4a6c,0x4a6d,0x4a6e,0x4a6f,
+ 0x4a70,0x4a71,0x4a72,0x4a73,0x4a74,0x4a75,0x4a76,0x4a77,
+ 0x4a78,0x4a79,0x4a7a,0x4a7b,0x4a7c,0x4a7d,0x4a7e,0x4a7f,
+ 0x4a80,0x4a81,0x4a82,0x4a83,0x4a84,0x4a85,0x4a86,0x4a87,
+ 0x4a88,0x4a89,0x4a8a,0x4a8b,0x4a8c,0x4a8d,0x4a8e,0x4a8f,
+ 0x4a90,0x4a91,0x4a92,0x4a93,0x4a94,0x4a95,0x4a96,0x4a97,
+ 0x4a98,0x4a99,0x4a9a,0x4a9b,0x4a9c,0x4a9d,0x4a9e,0x4a9f,
+ 0x4aa0,0x4aa1,0x4aa2,0x4aa3,0x4aa4,0x4aa5,0x4aa6,0x4aa7,
+ 0x4aa8,0x4aa9,0x4aaa,0x4aab,0x4aac,0x4aad,0x4aae,0x4aaf,
+ 0x4ab0,0x4ab1,0x4ab2,0x4ab3,0x4ab4,0x4ab5,0x4ab6,0x4ab7,
+ 0x4ab8,0x4ab9,0x4aba,0x4abb,0x4abc,0x4abd,0x4abe,0x4abf,
+ 0x4ac0,0x4ac1,0x4ac2,0x4ac3,0x4ac4,0x4ac5,0x4ac6,0x4ac7,
+ 0x4ac8,0x4ac9,0x4aca,0x4acb,0x4acc,0x4acd,0x4ace,0x4acf,
+ 0x4ad0,0x4ad1,0x4ad2,0x4ad3,0x4ad4,0x4ad5,0x4ad6,0x4ad7,
+ 0x4ad8,0x4ad9,0x4ada,0x4adb,0x4adc,0x4add,0x4ade,0x4adf,
+ 0x4ae0,0x4ae1,0x4ae2,0x4ae3,0x4ae4,0x4ae5,0x4ae6,0x4ae7,
+ 0x4ae8,0x4ae9,0x4aea,0x4aeb,0x4aec,0x4aed,0x4aee,0x4aef,
+ 0x4af0,0x4af1,0x4af2,0x4af3,0x4af4,0x4af5,0x4af6,0x4af7,
+ 0x4af8,0x4af9,0x4afa,0x4afb,0x4afc,0x4afd,0x4afe,0x4aff,
+ 0x4b00,0x4b01,0x4b02,0x4b03,0x4b04,0x4b05,0x4b06,0x4b07,
+ 0x4b08,0x4b09,0x4b0a,0x4b0b,0x4b0c,0x4b0d,0x4b0e,0x4b0f,
+ 0x4b10,0x4b11,0x4b12,0x4b13,0x4b14,0x4b15,0x4b16,0x4b17,
+ 0x4b18,0x4b19,0x4b1a,0x4b1b,0x4b1c,0x4b1d,0x4b1e,0x4b1f,
+ 0x4b20,0x4b21,0x4b22,0x4b23,0x4b24,0x4b25,0x4b26,0x4b27,
+ 0x4b28,0x4b29,0x4b2a,0x4b2b,0x4b2c,0x4b2d,0x4b2e,0x4b2f,
+ 0x4b30,0x4b31,0x4b32,0x4b33,0x4b34,0x4b35,0x4b36,0x4b37,
+ 0x4b38,0x4b39,0x4b3a,0x4b3b,0x4b3c,0x4b3d,0x4b3e,0x4b3f,
+ 0x4b40,0x4b41,0x4b42,0x4b43,0x4b44,0x4b45,0x4b46,0x4b47,
+ 0x4b48,0x4b49,0x4b4a,0x4b4b,0x4b4c,0x4b4d,0x4b4e,0x4b4f,
+ 0x4b50,0x4b51,0x4b52,0x4b53,0x4b54,0x4b55,0x4b56,0x4b57,
+ 0x4b58,0x4b59,0x4b5a,0x4b5b,0x4b5c,0x4b5d,0x4b5e,0x4b5f,
+ 0x4b60,0x4b61,0x4b62,0x4b63,0x4b64,0x4b65,0x4b66,0x4b67,
+ 0x4b68,0x4b69,0x4b6a,0x4b6b,0x4b6c,0x4b6d,0x4b6e,0x4b6f,
+ 0x4b70,0x4b71,0x4b72,0x4b73,0x4b74,0x4b75,0x4b76,0x4b77,
+ 0x4b78,0x4b79,0x4b7a,0x4b7b,0x4b7c,0x4b7d,0x4b7e,0x4b7f,
+ 0x4b80,0x4b81,0x4b82,0x4b83,0x4b84,0x4b85,0x4b86,0x4b87,
+ 0x4b88,0x4b89,0x4b8a,0x4b8b,0x4b8c,0x4b8d,0x4b8e,0x4b8f,
+ 0x4b90,0x4b91,0x4b92,0x4b93,0x4b94,0x4b95,0x4b96,0x4b97,
+ 0x4b98,0x4b99,0x4b9a,0x4b9b,0x4b9c,0x4b9d,0x4b9e,0x4b9f,
+ 0x4ba0,0x4ba1,0x4ba2,0x4ba3,0x4ba4,0x4ba5,0x4ba6,0x4ba7,
+ 0x4ba8,0x4ba9,0x4baa,0x4bab,0x4bac,0x4bad,0x4bae,0x4baf,
+ 0x4bb0,0x4bb1,0x4bb2,0x4bb3,0x4bb4,0x4bb5,0x4bb6,0x4bb7,
+ 0x4bb8,0x4bb9,0x4bba,0x4bbb,0x4bbc,0x4bbd,0x4bbe,0x4bbf,
+ 0x4bc0,0x4bc1,0x4bc2,0x4bc3,0x4bc4,0x4bc5,0x4bc6,0x4bc7,
+ 0x4bc8,0x4bc9,0x4bca,0x4bcb,0x4bcc,0x4bcd,0x4bce,0x4bcf,
+ 0x4bd0,0x4bd1,0x4bd2,0x4bd3,0x4bd4,0x4bd5,0x4bd6,0x4bd7,
+ 0x4bd8,0x4bd9,0x4bda,0x4bdb,0x4bdc,0x4bdd,0x4bde,0x4bdf,
+ 0x4be0,0x4be1,0x4be2,0x4be3,0x4be4,0x4be5,0x4be6,0x4be7,
+ 0x4be8,0x4be9,0x4bea,0x4beb,0x4bec,0x4bed,0x4bee,0x4bef,
+ 0x4bf0,0x4bf1,0x4bf2,0x4bf3,0x4bf4,0x4bf5,0x4bf6,0x4bf7,
+ 0x4bf8,0x4bf9,0x4bfa,0x4bfb,0x4bfc,0x4bfd,0x4bfe,0x4bff,
+ 0x4c00,0x4c01,0x4c02,0x4c03,0x4c04,0x4c05,0x4c06,0x4c07,
+ 0x4c08,0x4c09,0x4c0a,0x4c0b,0x4c0c,0x4c0d,0x4c0e,0x4c0f,
+ 0x4c10,0x4c11,0x4c12,0x4c13,0x4c14,0x4c15,0x4c16,0x4c17,
+ 0x4c18,0x4c19,0x4c1a,0x4c1b,0x4c1c,0x4c1d,0x4c1e,0x4c1f,
+ 0x4c20,0x4c21,0x4c22,0x4c23,0x4c24,0x4c25,0x4c26,0x4c27,
+ 0x4c28,0x4c29,0x4c2a,0x4c2b,0x4c2c,0x4c2d,0x4c2e,0x4c2f,
+ 0x4c30,0x4c31,0x4c32,0x4c33,0x4c34,0x4c35,0x4c36,0x4c37,
+ 0x4c38,0x4c39,0x4c3a,0x4c3b,0x4c3c,0x4c3d,0x4c3e,0x4c3f,
+ 0x4c40,0x4c41,0x4c42,0x4c43,0x4c44,0x4c45,0x4c46,0x4c47,
+ 0x4c48,0x4c49,0x4c4a,0x4c4b,0x4c4c,0x4c4d,0x4c4e,0x4c4f,
+ 0x4c50,0x4c51,0x4c52,0x4c53,0x4c54,0x4c55,0x4c56,0x4c57,
+ 0x4c58,0x4c59,0x4c5a,0x4c5b,0x4c5c,0x4c5d,0x4c5e,0x4c5f,
+ 0x4c60,0x4c61,0x4c62,0x4c63,0x4c64,0x4c65,0x4c66,0x4c67,
+ 0x4c68,0x4c69,0x4c6a,0x4c6b,0x4c6c,0x4c6d,0x4c6e,0x4c6f,
+ 0x4c70,0x4c71,0x4c72,0x4c73,0x4c74,0x4c75,0x4c76,0x4c77,
+ 0x4c78,0x4c79,0x4c7a,0x4c7b,0x4c7c,0x4c7d,0x4c7e,0x4c7f,
+ 0x4c80,0x4c81,0x4c82,0x4c83,0x4c84,0x4c85,0x4c86,0x4c87,
+ 0x4c88,0x4c89,0x4c8a,0x4c8b,0x4c8c,0x4c8d,0x4c8e,0x4c8f,
+ 0x4c90,0x4c91,0x4c92,0x4c93,0x4c94,0x4c95,0x4c96,0x4c97,
+ 0x4c98,0x4c99,0x4c9a,0x4c9b,0x4c9c,0x4c9d,0x4c9e,0x4c9f,
+ 0x4ca0,0x4ca1,0x4ca2,0x4ca3,0x4ca4,0x4ca5,0x4ca6,0x4ca7,
+ 0x4ca8,0x4ca9,0x4caa,0x4cab,0x4cac,0x4cad,0x4cae,0x4caf,
+ 0x4cb0,0x4cb1,0x4cb2,0x4cb3,0x4cb4,0x4cb5,0x4cb6,0x4cb7,
+ 0x4cb8,0x4cb9,0x4cba,0x4cbb,0x4cbc,0x4cbd,0x4cbe,0x4cbf,
+ 0x4cc0,0x4cc1,0x4cc2,0x4cc3,0x4cc4,0x4cc5,0x4cc6,0x4cc7,
+ 0x4cc8,0x4cc9,0x4cca,0x4ccb,0x4ccc,0x4ccd,0x4cce,0x4ccf,
+ 0x4cd0,0x4cd1,0x4cd2,0x4cd3,0x4cd4,0x4cd5,0x4cd6,0x4cd7,
+ 0x4cd8,0x4cd9,0x4cda,0x4cdb,0x4cdc,0x4cdd,0x4cde,0x4cdf,
+ 0x4ce0,0x4ce1,0x4ce2,0x4ce3,0x4ce4,0x4ce5,0x4ce6,0x4ce7,
+ 0x4ce8,0x4ce9,0x4cea,0x4ceb,0x4cec,0x4ced,0x4cee,0x4cef,
+ 0x4cf0,0x4cf1,0x4cf2,0x4cf3,0x4cf4,0x4cf5,0x4cf6,0x4cf7,
+ 0x4cf8,0x4cf9,0x4cfa,0x4cfb,0x4cfc,0x4cfd,0x4cfe,0x4cff,
+ 0x4d00,0x4d01,0x4d02,0x4d03,0x4d04,0x4d05,0x4d06,0x4d07,
+ 0x4d08,0x4d09,0x4d0a,0x4d0b,0x4d0c,0x4d0d,0x4d0e,0x4d0f,
+ 0x4d10,0x4d11,0x4d12,0x4d13,0x4d14,0x4d15,0x4d16,0x4d17,
+ 0x4d18,0x4d19,0x4d1a,0x4d1b,0x4d1c,0x4d1d,0x4d1e,0x4d1f,
+ 0x4d20,0x4d21,0x4d22,0x4d23,0x4d24,0x4d25,0x4d26,0x4d27,
+ 0x4d28,0x4d29,0x4d2a,0x4d2b,0x4d2c,0x4d2d,0x4d2e,0x4d2f,
+ 0x4d30,0x4d31,0x4d32,0x4d33,0x4d34,0x4d35,0x4d36,0x4d37,
+ 0x4d38,0x4d39,0x4d3a,0x4d3b,0x4d3c,0x4d3d,0x4d3e,0x4d3f,
+ 0x4d40,0x4d41,0x4d42,0x4d43,0x4d44,0x4d45,0x4d46,0x4d47,
+ 0x4d48,0x4d49,0x4d4a,0x4d4b,0x4d4c,0x4d4d,0x4d4e,0x4d4f,
+ 0x4d50,0x4d51,0x4d52,0x4d53,0x4d54,0x4d55,0x4d56,0x4d57,
+ 0x4d58,0x4d59,0x4d5a,0x4d5b,0x4d5c,0x4d5d,0x4d5e,0x4d5f,
+ 0x4d60,0x4d61,0x4d62,0x4d63,0x4d64,0x4d65,0x4d66,0x4d67,
+ 0x4d68,0x4d69,0x4d6a,0x4d6b,0x4d6c,0x4d6d,0x4d6e,0x4d6f,
+ 0x4d70,0x4d71,0x4d72,0x4d73,0x4d74,0x4d75,0x4d76,0x4d77,
+ 0x4d78,0x4d79,0x4d7a,0x4d7b,0x4d7c,0x4d7d,0x4d7e,0x4d7f,
+ 0x4d80,0x4d81,0x4d82,0x4d83,0x4d84,0x4d85,0x4d86,0x4d87,
+ 0x4d88,0x4d89,0x4d8a,0x4d8b,0x4d8c,0x4d8d,0x4d8e,0x4d8f,
+ 0x4d90,0x4d91,0x4d92,0x4d93,0x4d94,0x4d95,0x4d96,0x4d97,
+ 0x4d98,0x4d99,0x4d9a,0x4d9b,0x4d9c,0x4d9d,0x4d9e,0x4d9f,
+ 0x4da0,0x4da1,0x4da2,0x4da3,0x4da4,0x4da5,0x4da6,0x4da7,
+ 0x4da8,0x4da9,0x4daa,0x4dab,0x4dac,0x4dad,0x4dae,0x4daf,
+ 0x4db0,0x4db1,0x4db2,0x4db3,0x4db4,0x4db5,0x4db6,0x4db7,
+ 0x4db8,0x4db9,0x4dba,0x4dbb,0x4dbc,0x4dbd,0x4dbe,0x4dbf,
+ 0x4dc0,0x4dc1,0x4dc2,0x4dc3,0x4dc4,0x4dc5,0x4dc6,0x4dc7,
+ 0x4dc8,0x4dc9,0x4dca,0x4dcb,0x4dcc,0x4dcd,0x4dce,0x4dcf,
+ 0x4dd0,0x4dd1,0x4dd2,0x4dd3,0x4dd4,0x4dd5,0x4dd6,0x4dd7,
+ 0x4dd8,0x4dd9,0x4dda,0x4ddb,0x4ddc,0x4ddd,0x4dde,0x4ddf,
+ 0x4de0,0x4de1,0x4de2,0x4de3,0x4de4,0x4de5,0x4de6,0x4de7,
+ 0x4de8,0x4de9,0x4dea,0x4deb,0x4dec,0x4ded,0x4dee,0x4def,
+ 0x4df0,0x4df1,0x4df2,0x4df3,0x4df4,0x4df5,0x4df6,0x4df7,
+ 0x4df8,0x4df9,0x4dfa,0x4dfb,0x4dfc,0x4dfd,0x4dfe,0x4dff,
+ 0x4e00,0x4e01,0x4e02,0x4e03,0x4e04,0x4e05,0x4e06,0x4e07,
+ 0x4e08,0x4e09,0x4e0a,0x4e0b,0x4e0c,0x4e0d,0x4e0e,0x4e0f,
+ 0x4e10,0x4e11,0x4e12,0x4e13,0x4e14,0x4e15,0x4e16,0x4e17,
+ 0x4e18,0x4e19,0x4e1a,0x4e1b,0x4e1c,0x4e1d,0x4e1e,0x4e1f,
+ 0x4e20,0x4e21,0x4e22,0x4e23,0x4e24,0x4e25,0x4e26,0x4e27,
+ 0x4e28,0x4e29,0x4e2a,0x4e2b,0x4e2c,0x4e2d,0x4e2e,0x4e2f,
+ 0x4e30,0x4e31,0x4e32,0x4e33,0x4e34,0x4e35,0x4e36,0x4e37,
+ 0x4e38,0x4e39,0x4e3a,0x4e3b,0x4e3c,0x4e3d,0x4e3e,0x4e3f,
+ 0x4e40,0x4e41,0x4e42,0x4e43,0x4e44,0x4e45,0x4e46,0x4e47,
+ 0x4e48,0x4e49,0x4e4a,0x4e4b,0x4e4c,0x4e4d,0x4e4e,0x4e4f,
+ 0x4e50,0x4e51,0x4e52,0x4e53,0x4e54,0x4e55,0x4e56,0x4e57,
+ 0x4e58,0x4e59,0x4e5a,0x4e5b,0x4e5c,0x4e5d,0x4e5e,0x4e5f,
+ 0x4e60,0x4e61,0x4e62,0x4e63,0x4e64,0x4e65,0x4e66,0x4e67,
+ 0x4e68,0x4e69,0x4e6a,0x4e6b,0x4e6c,0x4e6d,0x4e6e,0x4e6f,
+ 0x4e70,0x4e71,0x4e72,0x4e73,0x4e74,0x4e75,0x4e76,0x4e77,
+ 0x4e78,0x4e79,0x4e7a,0x4e7b,0x4e7c,0x4e7d,0x4e7e,0x4e7f,
+ 0x4e80,0x4e81,0x4e82,0x4e83,0x4e84,0x4e85,0x4e86,0x4e87,
+ 0x4e88,0x4e89,0x4e8a,0x4e8b,0x4e8c,0x4e8d,0x4e8e,0x4e8f,
+ 0x4e90,0x4e91,0x4e92,0x4e93,0x4e94,0x4e95,0x4e96,0x4e97,
+ 0x4e98,0x4e99,0x4e9a,0x4e9b,0x4e9c,0x4e9d,0x4e9e,0x4e9f,
+ 0x4ea0,0x4ea1,0x4ea2,0x4ea3,0x4ea4,0x4ea5,0x4ea6,0x4ea7,
+ 0x4ea8,0x4ea9,0x4eaa,0x4eab,0x4eac,0x4ead,0x4eae,0x4eaf,
+ 0x4eb0,0x4eb1,0x4eb2,0x4eb3,0x4eb4,0x4eb5,0x4eb6,0x4eb7,
+ 0x4eb8,0x4eb9,0x4eba,0x4ebb,0x4ebc,0x4ebd,0x4ebe,0x4ebf,
+ 0x4ec0,0x4ec1,0x4ec2,0x4ec3,0x4ec4,0x4ec5,0x4ec6,0x4ec7,
+ 0x4ec8,0x4ec9,0x4eca,0x4ecb,0x4ecc,0x4ecd,0x4ece,0x4ecf,
+ 0x4ed0,0x4ed1,0x4ed2,0x4ed3,0x4ed4,0x4ed5,0x4ed6,0x4ed7,
+ 0x4ed8,0x4ed9,0x4eda,0x4edb,0x4edc,0x4edd,0x4ede,0x4edf,
+ 0x4ee0,0x4ee1,0x4ee2,0x4ee3,0x4ee4,0x4ee5,0x4ee6,0x4ee7,
+ 0x4ee8,0x4ee9,0x4eea,0x4eeb,0x4eec,0x4eed,0x4eee,0x4eef,
+ 0x4ef0,0x4ef1,0x4ef2,0x4ef3,0x4ef4,0x4ef5,0x4ef6,0x4ef7,
+ 0x4ef8,0x4ef9,0x4efa,0x4efb,0x4efc,0x4efd,0x4efe,0x4eff,
+ 0x4f00,0x4f01,0x4f02,0x4f03,0x4f04,0x4f05,0x4f06,0x4f07,
+ 0x4f08,0x4f09,0x4f0a,0x4f0b,0x4f0c,0x4f0d,0x4f0e,0x4f0f,
+ 0x4f10,0x4f11,0x4f12,0x4f13,0x4f14,0x4f15,0x4f16,0x4f17,
+ 0x4f18,0x4f19,0x4f1a,0x4f1b,0x4f1c,0x4f1d,0x4f1e,0x4f1f,
+ 0x4f20,0x4f21,0x4f22,0x4f23,0x4f24,0x4f25,0x4f26,0x4f27,
+ 0x4f28,0x4f29,0x4f2a,0x4f2b,0x4f2c,0x4f2d,0x4f2e,0x4f2f,
+ 0x4f30,0x4f31,0x4f32,0x4f33,0x4f34,0x4f35,0x4f36,0x4f37,
+ 0x4f38,0x4f39,0x4f3a,0x4f3b,0x4f3c,0x4f3d,0x4f3e,0x4f3f,
+ 0x4f40,0x4f41,0x4f42,0x4f43,0x4f44,0x4f45,0x4f46,0x4f47,
+ 0x4f48,0x4f49,0x4f4a,0x4f4b,0x4f4c,0x4f4d,0x4f4e,0x4f4f,
+ 0x4f50,0x4f51,0x4f52,0x4f53,0x4f54,0x4f55,0x4f56,0x4f57,
+ 0x4f58,0x4f59,0x4f5a,0x4f5b,0x4f5c,0x4f5d,0x4f5e,0x4f5f,
+ 0x4f60,0x4f61,0x4f62,0x4f63,0x4f64,0x4f65,0x4f66,0x4f67,
+ 0x4f68,0x4f69,0x4f6a,0x4f6b,0x4f6c,0x4f6d,0x4f6e,0x4f6f,
+ 0x4f70,0x4f71,0x4f72,0x4f73,0x4f74,0x4f75,0x4f76,0x4f77,
+ 0x4f78,0x4f79,0x4f7a,0x4f7b,0x4f7c,0x4f7d,0x4f7e,0x4f7f,
+ 0x4f80,0x4f81,0x4f82,0x4f83,0x4f84,0x4f85,0x4f86,0x4f87,
+ 0x4f88,0x4f89,0x4f8a,0x4f8b,0x4f8c,0x4f8d,0x4f8e,0x4f8f,
+ 0x4f90,0x4f91,0x4f92,0x4f93,0x4f94,0x4f95,0x4f96,0x4f97,
+ 0x4f98,0x4f99,0x4f9a,0x4f9b,0x4f9c,0x4f9d,0x4f9e,0x4f9f,
+ 0x4fa0,0x4fa1,0x4fa2,0x4fa3,0x4fa4,0x4fa5,0x4fa6,0x4fa7,
+ 0x4fa8,0x4fa9,0x4faa,0x4fab,0x4fac,0x4fad,0x4fae,0x4faf,
+ 0x4fb0,0x4fb1,0x4fb2,0x4fb3,0x4fb4,0x4fb5,0x4fb6,0x4fb7,
+ 0x4fb8,0x4fb9,0x4fba,0x4fbb,0x4fbc,0x4fbd,0x4fbe,0x4fbf,
+ 0x4fc0,0x4fc1,0x4fc2,0x4fc3,0x4fc4,0x4fc5,0x4fc6,0x4fc7,
+ 0x4fc8,0x4fc9,0x4fca,0x4fcb,0x4fcc,0x4fcd,0x4fce,0x4fcf,
+ 0x4fd0,0x4fd1,0x4fd2,0x4fd3,0x4fd4,0x4fd5,0x4fd6,0x4fd7,
+ 0x4fd8,0x4fd9,0x4fda,0x4fdb,0x4fdc,0x4fdd,0x4fde,0x4fdf,
+ 0x4fe0,0x4fe1,0x4fe2,0x4fe3,0x4fe4,0x4fe5,0x4fe6,0x4fe7,
+ 0x4fe8,0x4fe9,0x4fea,0x4feb,0x4fec,0x4fed,0x4fee,0x4fef,
+ 0x4ff0,0x4ff1,0x4ff2,0x4ff3,0x4ff4,0x4ff5,0x4ff6,0x4ff7,
+ 0x4ff8,0x4ff9,0x4ffa,0x4ffb,0x4ffc,0x4ffd,0x4ffe,0x4fff,
+ 0x5000,0x5001,0x5002,0x5003,0x5004,0x5005,0x5006,0x5007,
+ 0x5008,0x5009,0x500a,0x500b,0x500c,0x500d,0x500e,0x500f,
+ 0x5010,0x5011,0x5012,0x5013,0x5014,0x5015,0x5016,0x5017,
+ 0x5018,0x5019,0x501a,0x501b,0x501c,0x501d,0x501e,0x501f,
+ 0x5020,0x5021,0x5022,0x5023,0x5024,0x5025,0x5026,0x5027,
+ 0x5028,0x5029,0x502a,0x502b,0x502c,0x502d,0x502e,0x502f,
+ 0x5030,0x5031,0x5032,0x5033,0x5034,0x5035,0x5036,0x5037,
+ 0x5038,0x5039,0x503a,0x503b,0x503c,0x503d,0x503e,0x503f,
+ 0x5040,0x5041,0x5042,0x5043,0x5044,0x5045,0x5046,0x5047,
+ 0x5048,0x5049,0x504a,0x504b,0x504c,0x504d,0x504e,0x504f,
+ 0x5050,0x5051,0x5052,0x5053,0x5054,0x5055,0x5056,0x5057,
+ 0x5058,0x5059,0x505a,0x505b,0x505c,0x505d,0x505e,0x505f,
+ 0x5060,0x5061,0x5062,0x5063,0x5064,0x5065,0x5066,0x5067,
+ 0x5068,0x5069,0x506a,0x506b,0x506c,0x506d,0x506e,0x506f,
+ 0x5070,0x5071,0x5072,0x5073,0x5074,0x5075,0x5076,0x5077,
+ 0x5078,0x5079,0x507a,0x507b,0x507c,0x507d,0x507e,0x507f,
+ 0x5080,0x5081,0x5082,0x5083,0x5084,0x5085,0x5086,0x5087,
+ 0x5088,0x5089,0x508a,0x508b,0x508c,0x508d,0x508e,0x508f,
+ 0x5090,0x5091,0x5092,0x5093,0x5094,0x5095,0x5096,0x5097,
+ 0x5098,0x5099,0x509a,0x509b,0x509c,0x509d,0x509e,0x509f,
+ 0x50a0,0x50a1,0x50a2,0x50a3,0x50a4,0x50a5,0x50a6,0x50a7,
+ 0x50a8,0x50a9,0x50aa,0x50ab,0x50ac,0x50ad,0x50ae,0x50af,
+ 0x50b0,0x50b1,0x50b2,0x50b3,0x50b4,0x50b5,0x50b6,0x50b7,
+ 0x50b8,0x50b9,0x50ba,0x50bb,0x50bc,0x50bd,0x50be,0x50bf,
+ 0x50c0,0x50c1,0x50c2,0x50c3,0x50c4,0x50c5,0x50c6,0x50c7,
+ 0x50c8,0x50c9,0x50ca,0x50cb,0x50cc,0x50cd,0x50ce,0x50cf,
+ 0x50d0,0x50d1,0x50d2,0x50d3,0x50d4,0x50d5,0x50d6,0x50d7,
+ 0x50d8,0x50d9,0x50da,0x50db,0x50dc,0x50dd,0x50de,0x50df,
+ 0x50e0,0x50e1,0x50e2,0x50e3,0x50e4,0x50e5,0x50e6,0x50e7,
+ 0x50e8,0x50e9,0x50ea,0x50eb,0x50ec,0x50ed,0x50ee,0x50ef,
+ 0x50f0,0x50f1,0x50f2,0x50f3,0x50f4,0x50f5,0x50f6,0x50f7,
+ 0x50f8,0x50f9,0x50fa,0x50fb,0x50fc,0x50fd,0x50fe,0x50ff,
+ 0x5100,0x5101,0x5102,0x5103,0x5104,0x5105,0x5106,0x5107,
+ 0x5108,0x5109,0x510a,0x510b,0x510c,0x510d,0x510e,0x510f,
+ 0x5110,0x5111,0x5112,0x5113,0x5114,0x5115,0x5116,0x5117,
+ 0x5118,0x5119,0x511a,0x511b,0x511c,0x511d,0x511e,0x511f,
+ 0x5120,0x5121,0x5122,0x5123,0x5124,0x5125,0x5126,0x5127,
+ 0x5128,0x5129,0x512a,0x512b,0x512c,0x512d,0x512e,0x512f,
+ 0x5130,0x5131,0x5132,0x5133,0x5134,0x5135,0x5136,0x5137,
+ 0x5138,0x5139,0x513a,0x513b,0x513c,0x513d,0x513e,0x513f,
+ 0x5140,0x5141,0x5142,0x5143,0x5144,0x5145,0x5146,0x5147,
+ 0x5148,0x5149,0x514a,0x514b,0x514c,0x514d,0x514e,0x514f,
+ 0x5150,0x5151,0x5152,0x5153,0x5154,0x5155,0x5156,0x5157,
+ 0x5158,0x5159,0x515a,0x515b,0x515c,0x515d,0x515e,0x515f,
+ 0x5160,0x5161,0x5162,0x5163,0x5164,0x5165,0x5166,0x5167,
+ 0x5168,0x5169,0x516a,0x516b,0x516c,0x516d,0x516e,0x516f,
+ 0x5170,0x5171,0x5172,0x5173,0x5174,0x5175,0x5176,0x5177,
+ 0x5178,0x5179,0x517a,0x517b,0x517c,0x517d,0x517e,0x517f,
+ 0x5180,0x5181,0x5182,0x5183,0x5184,0x5185,0x5186,0x5187,
+ 0x5188,0x5189,0x518a,0x518b,0x518c,0x518d,0x518e,0x518f,
+ 0x5190,0x5191,0x5192,0x5193,0x5194,0x5195,0x5196,0x5197,
+ 0x5198,0x5199,0x519a,0x519b,0x519c,0x519d,0x519e,0x519f,
+ 0x51a0,0x51a1,0x51a2,0x51a3,0x51a4,0x51a5,0x51a6,0x51a7,
+ 0x51a8,0x51a9,0x51aa,0x51ab,0x51ac,0x51ad,0x51ae,0x51af,
+ 0x51b0,0x51b1,0x51b2,0x51b3,0x51b4,0x51b5,0x51b6,0x51b7,
+ 0x51b8,0x51b9,0x51ba,0x51bb,0x51bc,0x51bd,0x51be,0x51bf,
+ 0x51c0,0x51c1,0x51c2,0x51c3,0x51c4,0x51c5,0x51c6,0x51c7,
+ 0x51c8,0x51c9,0x51ca,0x51cb,0x51cc,0x51cd,0x51ce,0x51cf,
+ 0x51d0,0x51d1,0x51d2,0x51d3,0x51d4,0x51d5,0x51d6,0x51d7,
+ 0x51d8,0x51d9,0x51da,0x51db,0x51dc,0x51dd,0x51de,0x51df,
+ 0x51e0,0x51e1,0x51e2,0x51e3,0x51e4,0x51e5,0x51e6,0x51e7,
+ 0x51e8,0x51e9,0x51ea,0x51eb,0x51ec,0x51ed,0x51ee,0x51ef,
+ 0x51f0,0x51f1,0x51f2,0x51f3,0x51f4,0x51f5,0x51f6,0x51f7,
+ 0x51f8,0x51f9,0x51fa,0x51fb,0x51fc,0x51fd,0x51fe,0x51ff,
+ 0x5200,0x5201,0x5202,0x5203,0x5204,0x5205,0x5206,0x5207,
+ 0x5208,0x5209,0x520a,0x520b,0x520c,0x520d,0x520e,0x520f,
+ 0x5210,0x5211,0x5212,0x5213,0x5214,0x5215,0x5216,0x5217,
+ 0x5218,0x5219,0x521a,0x521b,0x521c,0x521d,0x521e,0x521f,
+ 0x5220,0x5221,0x5222,0x5223,0x5224,0x5225,0x5226,0x5227,
+ 0x5228,0x5229,0x522a,0x522b,0x522c,0x522d,0x522e,0x522f,
+ 0x5230,0x5231,0x5232,0x5233,0x5234,0x5235,0x5236,0x5237,
+ 0x5238,0x5239,0x523a,0x523b,0x523c,0x523d,0x523e,0x523f,
+ 0x5240,0x5241,0x5242,0x5243,0x5244,0x5245,0x5246,0x5247,
+ 0x5248,0x5249,0x524a,0x524b,0x524c,0x524d,0x524e,0x524f,
+ 0x5250,0x5251,0x5252,0x5253,0x5254,0x5255,0x5256,0x5257,
+ 0x5258,0x5259,0x525a,0x525b,0x525c,0x525d,0x525e,0x525f,
+ 0x5260,0x5261,0x5262,0x5263,0x5264,0x5265,0x5266,0x5267,
+ 0x5268,0x5269,0x526a,0x526b,0x526c,0x526d,0x526e,0x526f,
+ 0x5270,0x5271,0x5272,0x5273,0x5274,0x5275,0x5276,0x5277,
+ 0x5278,0x5279,0x527a,0x527b,0x527c,0x527d,0x527e,0x527f,
+ 0x5280,0x5281,0x5282,0x5283,0x5284,0x5285,0x5286,0x5287,
+ 0x5288,0x5289,0x528a,0x528b,0x528c,0x528d,0x528e,0x528f,
+ 0x5290,0x5291,0x5292,0x5293,0x5294,0x5295,0x5296,0x5297,
+ 0x5298,0x5299,0x529a,0x529b,0x529c,0x529d,0x529e,0x529f,
+ 0x52a0,0x52a1,0x52a2,0x52a3,0x52a4,0x52a5,0x52a6,0x52a7,
+ 0x52a8,0x52a9,0x52aa,0x52ab,0x52ac,0x52ad,0x52ae,0x52af,
+ 0x52b0,0x52b1,0x52b2,0x52b3,0x52b4,0x52b5,0x52b6,0x52b7,
+ 0x52b8,0x52b9,0x52ba,0x52bb,0x52bc,0x52bd,0x52be,0x52bf,
+ 0x52c0,0x52c1,0x52c2,0x52c3,0x52c4,0x52c5,0x52c6,0x52c7,
+ 0x52c8,0x52c9,0x52ca,0x52cb,0x52cc,0x52cd,0x52ce,0x52cf,
+ 0x52d0,0x52d1,0x52d2,0x52d3,0x52d4,0x52d5,0x52d6,0x52d7,
+ 0x52d8,0x52d9,0x52da,0x52db,0x52dc,0x52dd,0x52de,0x52df,
+ 0x52e0,0x52e1,0x52e2,0x52e3,0x52e4,0x52e5,0x52e6,0x52e7,
+ 0x52e8,0x52e9,0x52ea,0x52eb,0x52ec,0x52ed,0x52ee,0x52ef,
+ 0x52f0,0x52f1,0x52f2,0x52f3,0x52f4,0x52f5,0x52f6,0x52f7,
+ 0x52f8,0x52f9,0x52fa,0x52fb,0x52fc,0x52fd,0x52fe,0x52ff,
+ 0x5300,0x5301,0x5302,0x5303,0x5304,0x5305,0x5306,0x5307,
+ 0x5308,0x5309,0x530a,0x530b,0x530c,0x530d,0x530e,0x530f,
+ 0x5310,0x5311,0x5312,0x5313,0x5314,0x5315,0x5316,0x5317,
+ 0x5318,0x5319,0x531a,0x531b,0x531c,0x531d,0x531e,0x531f,
+ 0x5320,0x5321,0x5322,0x5323,0x5324,0x5325,0x5326,0x5327,
+ 0x5328,0x5329,0x532a,0x532b,0x532c,0x532d,0x532e,0x532f,
+ 0x5330,0x5331,0x5332,0x5333,0x5334,0x5335,0x5336,0x5337,
+ 0x5338,0x5339,0x533a,0x533b,0x533c,0x533d,0x533e,0x533f,
+ 0x5340,0x5341,0x5342,0x5343,0x5344,0x5345,0x5346,0x5347,
+ 0x5348,0x5349,0x534a,0x534b,0x534c,0x534d,0x534e,0x534f,
+ 0x5350,0x5351,0x5352,0x5353,0x5354,0x5355,0x5356,0x5357,
+ 0x5358,0x5359,0x535a,0x535b,0x535c,0x535d,0x535e,0x535f,
+ 0x5360,0x5361,0x5362,0x5363,0x5364,0x5365,0x5366,0x5367,
+ 0x5368,0x5369,0x536a,0x536b,0x536c,0x536d,0x536e,0x536f,
+ 0x5370,0x5371,0x5372,0x5373,0x5374,0x5375,0x5376,0x5377,
+ 0x5378,0x5379,0x537a,0x537b,0x537c,0x537d,0x537e,0x537f,
+ 0x5380,0x5381,0x5382,0x5383,0x5384,0x5385,0x5386,0x5387,
+ 0x5388,0x5389,0x538a,0x538b,0x538c,0x538d,0x538e,0x538f,
+ 0x5390,0x5391,0x5392,0x5393,0x5394,0x5395,0x5396,0x5397,
+ 0x5398,0x5399,0x539a,0x539b,0x539c,0x539d,0x539e,0x539f,
+ 0x53a0,0x53a1,0x53a2,0x53a3,0x53a4,0x53a5,0x53a6,0x53a7,
+ 0x53a8,0x53a9,0x53aa,0x53ab,0x53ac,0x53ad,0x53ae,0x53af,
+ 0x53b0,0x53b1,0x53b2,0x53b3,0x53b4,0x53b5,0x53b6,0x53b7,
+ 0x53b8,0x53b9,0x53ba,0x53bb,0x53bc,0x53bd,0x53be,0x53bf,
+ 0x53c0,0x53c1,0x53c2,0x53c3,0x53c4,0x53c5,0x53c6,0x53c7,
+ 0x53c8,0x53c9,0x53ca,0x53cb,0x53cc,0x53cd,0x53ce,0x53cf,
+ 0x53d0,0x53d1,0x53d2,0x53d3,0x53d4,0x53d5,0x53d6,0x53d7,
+ 0x53d8,0x53d9,0x53da,0x53db,0x53dc,0x53dd,0x53de,0x53df,
+ 0x53e0,0x53e1,0x53e2,0x53e3,0x53e4,0x53e5,0x53e6,0x53e7,
+ 0x53e8,0x53e9,0x53ea,0x53eb,0x53ec,0x53ed,0x53ee,0x53ef,
+ 0x53f0,0x53f1,0x53f2,0x53f3,0x53f4,0x53f5,0x53f6,0x53f7,
+ 0x53f8,0x53f9,0x53fa,0x53fb,0x53fc,0x53fd,0x53fe,0x53ff,
+ 0x5400,0x5401,0x5402,0x5403,0x5404,0x5405,0x5406,0x5407,
+ 0x5408,0x5409,0x540a,0x540b,0x540c,0x540d,0x540e,0x540f,
+ 0x5410,0x5411,0x5412,0x5413,0x5414,0x5415,0x5416,0x5417,
+ 0x5418,0x5419,0x541a,0x541b,0x541c,0x541d,0x541e,0x541f,
+ 0x5420,0x5421,0x5422,0x5423,0x5424,0x5425,0x5426,0x5427,
+ 0x5428,0x5429,0x542a,0x542b,0x542c,0x542d,0x542e,0x542f,
+ 0x5430,0x5431,0x5432,0x5433,0x5434,0x5435,0x5436,0x5437,
+ 0x5438,0x5439,0x543a,0x543b,0x543c,0x543d,0x543e,0x543f,
+ 0x5440,0x5441,0x5442,0x5443,0x5444,0x5445,0x5446,0x5447,
+ 0x5448,0x5449,0x544a,0x544b,0x544c,0x544d,0x544e,0x544f,
+ 0x5450,0x5451,0x5452,0x5453,0x5454,0x5455,0x5456,0x5457,
+ 0x5458,0x5459,0x545a,0x545b,0x545c,0x545d,0x545e,0x545f,
+ 0x5460,0x5461,0x5462,0x5463,0x5464,0x5465,0x5466,0x5467,
+ 0x5468,0x5469,0x546a,0x546b,0x546c,0x546d,0x546e,0x546f,
+ 0x5470,0x5471,0x5472,0x5473,0x5474,0x5475,0x5476,0x5477,
+ 0x5478,0x5479,0x547a,0x547b,0x547c,0x547d,0x547e,0x547f,
+ 0x5480,0x5481,0x5482,0x5483,0x5484,0x5485,0x5486,0x5487,
+ 0x5488,0x5489,0x548a,0x548b,0x548c,0x548d,0x548e,0x548f,
+ 0x5490,0x5491,0x5492,0x5493,0x5494,0x5495,0x5496,0x5497,
+ 0x5498,0x5499,0x549a,0x549b,0x549c,0x549d,0x549e,0x549f,
+ 0x54a0,0x54a1,0x54a2,0x54a3,0x54a4,0x54a5,0x54a6,0x54a7,
+ 0x54a8,0x54a9,0x54aa,0x54ab,0x54ac,0x54ad,0x54ae,0x54af,
+ 0x54b0,0x54b1,0x54b2,0x54b3,0x54b4,0x54b5,0x54b6,0x54b7,
+ 0x54b8,0x54b9,0x54ba,0x54bb,0x54bc,0x54bd,0x54be,0x54bf,
+ 0x54c0,0x54c1,0x54c2,0x54c3,0x54c4,0x54c5,0x54c6,0x54c7,
+ 0x54c8,0x54c9,0x54ca,0x54cb,0x54cc,0x54cd,0x54ce,0x54cf,
+ 0x54d0,0x54d1,0x54d2,0x54d3,0x54d4,0x54d5,0x54d6,0x54d7,
+ 0x54d8,0x54d9,0x54da,0x54db,0x54dc,0x54dd,0x54de,0x54df,
+ 0x54e0,0x54e1,0x54e2,0x54e3,0x54e4,0x54e5,0x54e6,0x54e7,
+ 0x54e8,0x54e9,0x54ea,0x54eb,0x54ec,0x54ed,0x54ee,0x54ef,
+ 0x54f0,0x54f1,0x54f2,0x54f3,0x54f4,0x54f5,0x54f6,0x54f7,
+ 0x54f8,0x54f9,0x54fa,0x54fb,0x54fc,0x54fd,0x54fe,0x54ff,
+ 0x5500,0x5501,0x5502,0x5503,0x5504,0x5505,0x5506,0x5507,
+ 0x5508,0x5509,0x550a,0x550b,0x550c,0x550d,0x550e,0x550f,
+ 0x5510,0x5511,0x5512,0x5513,0x5514,0x5515,0x5516,0x5517,
+ 0x5518,0x5519,0x551a,0x551b,0x551c,0x551d,0x551e,0x551f,
+ 0x5520,0x5521,0x5522,0x5523,0x5524,0x5525,0x5526,0x5527,
+ 0x5528,0x5529,0x552a,0x552b,0x552c,0x552d,0x552e,0x552f,
+ 0x5530,0x5531,0x5532,0x5533,0x5534,0x5535,0x5536,0x5537,
+ 0x5538,0x5539,0x553a,0x553b,0x553c,0x553d,0x553e,0x553f,
+ 0x5540,0x5541,0x5542,0x5543,0x5544,0x5545,0x5546,0x5547,
+ 0x5548,0x5549,0x554a,0x554b,0x554c,0x554d,0x554e,0x554f,
+ 0x5550,0x5551,0x5552,0x5553,0x5554,0x5555,0x5556,0x5557,
+ 0x5558,0x5559,0x555a,0x555b,0x555c,0x555d,0x555e,0x555f,
+ 0x5560,0x5561,0x5562,0x5563,0x5564,0x5565,0x5566,0x5567,
+ 0x5568,0x5569,0x556a,0x556b,0x556c,0x556d,0x556e,0x556f,
+ 0x5570,0x5571,0x5572,0x5573,0x5574,0x5575,0x5576,0x5577,
+ 0x5578,0x5579,0x557a,0x557b,0x557c,0x557d,0x557e,0x557f,
+ 0x5580,0x5581,0x5582,0x5583,0x5584,0x5585,0x5586,0x5587,
+ 0x5588,0x5589,0x558a,0x558b,0x558c,0x558d,0x558e,0x558f,
+ 0x5590,0x5591,0x5592,0x5593,0x5594,0x5595,0x5596,0x5597,
+ 0x5598,0x5599,0x559a,0x559b,0x559c,0x559d,0x559e,0x559f,
+ 0x55a0,0x55a1,0x55a2,0x55a3,0x55a4,0x55a5,0x55a6,0x55a7,
+ 0x55a8,0x55a9,0x55aa,0x55ab,0x55ac,0x55ad,0x55ae,0x55af,
+ 0x55b0,0x55b1,0x55b2,0x55b3,0x55b4,0x55b5,0x55b6,0x55b7,
+ 0x55b8,0x55b9,0x55ba,0x55bb,0x55bc,0x55bd,0x55be,0x55bf,
+ 0x55c0,0x55c1,0x55c2,0x55c3,0x55c4,0x55c5,0x55c6,0x55c7,
+ 0x55c8,0x55c9,0x55ca,0x55cb,0x55cc,0x55cd,0x55ce,0x55cf,
+ 0x55d0,0x55d1,0x55d2,0x55d3,0x55d4,0x55d5,0x55d6,0x55d7,
+ 0x55d8,0x55d9,0x55da,0x55db,0x55dc,0x55dd,0x55de,0x55df,
+ 0x55e0,0x55e1,0x55e2,0x55e3,0x55e4,0x55e5,0x55e6,0x55e7,
+ 0x55e8,0x55e9,0x55ea,0x55eb,0x55ec,0x55ed,0x55ee,0x55ef,
+ 0x55f0,0x55f1,0x55f2,0x55f3,0x55f4,0x55f5,0x55f6,0x55f7,
+ 0x55f8,0x55f9,0x55fa,0x55fb,0x55fc,0x55fd,0x55fe,0x55ff,
+ 0x5600,0x5601,0x5602,0x5603,0x5604,0x5605,0x5606,0x5607,
+ 0x5608,0x5609,0x560a,0x560b,0x560c,0x560d,0x560e,0x560f,
+ 0x5610,0x5611,0x5612,0x5613,0x5614,0x5615,0x5616,0x5617,
+ 0x5618,0x5619,0x561a,0x561b,0x561c,0x561d,0x561e,0x561f,
+ 0x5620,0x5621,0x5622,0x5623,0x5624,0x5625,0x5626,0x5627,
+ 0x5628,0x5629,0x562a,0x562b,0x562c,0x562d,0x562e,0x562f,
+ 0x5630,0x5631,0x5632,0x5633,0x5634,0x5635,0x5636,0x5637,
+ 0x5638,0x5639,0x563a,0x563b,0x563c,0x563d,0x563e,0x563f,
+ 0x5640,0x5641,0x5642,0x5643,0x5644,0x5645,0x5646,0x5647,
+ 0x5648,0x5649,0x564a,0x564b,0x564c,0x564d,0x564e,0x564f,
+ 0x5650,0x5651,0x5652,0x5653,0x5654,0x5655,0x5656,0x5657,
+ 0x5658,0x5659,0x565a,0x565b,0x565c,0x565d,0x565e,0x565f,
+ 0x5660,0x5661,0x5662,0x5663,0x5664,0x5665,0x5666,0x5667,
+ 0x5668,0x5669,0x566a,0x566b,0x566c,0x566d,0x566e,0x566f,
+ 0x5670,0x5671,0x5672,0x5673,0x5674,0x5675,0x5676,0x5677,
+ 0x5678,0x5679,0x567a,0x567b,0x567c,0x567d,0x567e,0x567f,
+ 0x5680,0x5681,0x5682,0x5683,0x5684,0x5685,0x5686,0x5687,
+ 0x5688,0x5689,0x568a,0x568b,0x568c,0x568d,0x568e,0x568f,
+ 0x5690,0x5691,0x5692,0x5693,0x5694,0x5695,0x5696,0x5697,
+ 0x5698,0x5699,0x569a,0x569b,0x569c,0x569d,0x569e,0x569f,
+ 0x56a0,0x56a1,0x56a2,0x56a3,0x56a4,0x56a5,0x56a6,0x56a7,
+ 0x56a8,0x56a9,0x56aa,0x56ab,0x56ac,0x56ad,0x56ae,0x56af,
+ 0x56b0,0x56b1,0x56b2,0x56b3,0x56b4,0x56b5,0x56b6,0x56b7,
+ 0x56b8,0x56b9,0x56ba,0x56bb,0x56bc,0x56bd,0x56be,0x56bf,
+ 0x56c0,0x56c1,0x56c2,0x56c3,0x56c4,0x56c5,0x56c6,0x56c7,
+ 0x56c8,0x56c9,0x56ca,0x56cb,0x56cc,0x56cd,0x56ce,0x56cf,
+ 0x56d0,0x56d1,0x56d2,0x56d3,0x56d4,0x56d5,0x56d6,0x56d7,
+ 0x56d8,0x56d9,0x56da,0x56db,0x56dc,0x56dd,0x56de,0x56df,
+ 0x56e0,0x56e1,0x56e2,0x56e3,0x56e4,0x56e5,0x56e6,0x56e7,
+ 0x56e8,0x56e9,0x56ea,0x56eb,0x56ec,0x56ed,0x56ee,0x56ef,
+ 0x56f0,0x56f1,0x56f2,0x56f3,0x56f4,0x56f5,0x56f6,0x56f7,
+ 0x56f8,0x56f9,0x56fa,0x56fb,0x56fc,0x56fd,0x56fe,0x56ff,
+ 0x5700,0x5701,0x5702,0x5703,0x5704,0x5705,0x5706,0x5707,
+ 0x5708,0x5709,0x570a,0x570b,0x570c,0x570d,0x570e,0x570f,
+ 0x5710,0x5711,0x5712,0x5713,0x5714,0x5715,0x5716,0x5717,
+ 0x5718,0x5719,0x571a,0x571b,0x571c,0x571d,0x571e,0x571f,
+ 0x5720,0x5721,0x5722,0x5723,0x5724,0x5725,0x5726,0x5727,
+ 0x5728,0x5729,0x572a,0x572b,0x572c,0x572d,0x572e,0x572f,
+ 0x5730,0x5731,0x5732,0x5733,0x5734,0x5735,0x5736,0x5737,
+ 0x5738,0x5739,0x573a,0x573b,0x573c,0x573d,0x573e,0x573f,
+ 0x5740,0x5741,0x5742,0x5743,0x5744,0x5745,0x5746,0x5747,
+ 0x5748,0x5749,0x574a,0x574b,0x574c,0x574d,0x574e,0x574f,
+ 0x5750,0x5751,0x5752,0x5753,0x5754,0x5755,0x5756,0x5757,
+ 0x5758,0x5759,0x575a,0x575b,0x575c,0x575d,0x575e,0x575f,
+ 0x5760,0x5761,0x5762,0x5763,0x5764,0x5765,0x5766,0x5767,
+ 0x5768,0x5769,0x576a,0x576b,0x576c,0x576d,0x576e,0x576f,
+ 0x5770,0x5771,0x5772,0x5773,0x5774,0x5775,0x5776,0x5777,
+ 0x5778,0x5779,0x577a,0x577b,0x577c,0x577d,0x577e,0x577f,
+ 0x5780,0x5781,0x5782,0x5783,0x5784,0x5785,0x5786,0x5787,
+ 0x5788,0x5789,0x578a,0x578b,0x578c,0x578d,0x578e,0x578f,
+ 0x5790,0x5791,0x5792,0x5793,0x5794,0x5795,0x5796,0x5797,
+ 0x5798,0x5799,0x579a,0x579b,0x579c,0x579d,0x579e,0x579f,
+ 0x57a0,0x57a1,0x57a2,0x57a3,0x57a4,0x57a5,0x57a6,0x57a7,
+ 0x57a8,0x57a9,0x57aa,0x57ab,0x57ac,0x57ad,0x57ae,0x57af,
+ 0x57b0,0x57b1,0x57b2,0x57b3,0x57b4,0x57b5,0x57b6,0x57b7,
+ 0x57b8,0x57b9,0x57ba,0x57bb,0x57bc,0x57bd,0x57be,0x57bf,
+ 0x57c0,0x57c1,0x57c2,0x57c3,0x57c4,0x57c5,0x57c6,0x57c7,
+ 0x57c8,0x57c9,0x57ca,0x57cb,0x57cc,0x57cd,0x57ce,0x57cf,
+ 0x57d0,0x57d1,0x57d2,0x57d3,0x57d4,0x57d5,0x57d6,0x57d7,
+ 0x57d8,0x57d9,0x57da,0x57db,0x57dc,0x57dd,0x57de,0x57df,
+ 0x57e0,0x57e1,0x57e2,0x57e3,0x57e4,0x57e5,0x57e6,0x57e7,
+ 0x57e8,0x57e9,0x57ea,0x57eb,0x57ec,0x57ed,0x57ee,0x57ef,
+ 0x57f0,0x57f1,0x57f2,0x57f3,0x57f4,0x57f5,0x57f6,0x57f7,
+ 0x57f8,0x57f9,0x57fa,0x57fb,0x57fc,0x57fd,0x57fe,0x57ff,
+ 0x5800,0x5801,0x5802,0x5803,0x5804,0x5805,0x5806,0x5807,
+ 0x5808,0x5809,0x580a,0x580b,0x580c,0x580d,0x580e,0x580f,
+ 0x5810,0x5811,0x5812,0x5813,0x5814,0x5815,0x5816,0x5817,
+ 0x5818,0x5819,0x581a,0x581b,0x581c,0x581d,0x581e,0x581f,
+ 0x5820,0x5821,0x5822,0x5823,0x5824,0x5825,0x5826,0x5827,
+ 0x5828,0x5829,0x582a,0x582b,0x582c,0x582d,0x582e,0x582f,
+ 0x5830,0x5831,0x5832,0x5833,0x5834,0x5835,0x5836,0x5837,
+ 0x5838,0x5839,0x583a,0x583b,0x583c,0x583d,0x583e,0x583f,
+ 0x5840,0x5841,0x5842,0x5843,0x5844,0x5845,0x5846,0x5847,
+ 0x5848,0x5849,0x584a,0x584b,0x584c,0x584d,0x584e,0x584f,
+ 0x5850,0x5851,0x5852,0x5853,0x5854,0x5855,0x5856,0x5857,
+ 0x5858,0x5859,0x585a,0x585b,0x585c,0x585d,0x585e,0x585f,
+ 0x5860,0x5861,0x5862,0x5863,0x5864,0x5865,0x5866,0x5867,
+ 0x5868,0x5869,0x586a,0x586b,0x586c,0x586d,0x586e,0x586f,
+ 0x5870,0x5871,0x5872,0x5873,0x5874,0x5875,0x5876,0x5877,
+ 0x5878,0x5879,0x587a,0x587b,0x587c,0x587d,0x587e,0x587f,
+ 0x5880,0x5881,0x5882,0x5883,0x5884,0x5885,0x5886,0x5887,
+ 0x5888,0x5889,0x588a,0x588b,0x588c,0x588d,0x588e,0x588f,
+ 0x5890,0x5891,0x5892,0x5893,0x5894,0x5895,0x5896,0x5897,
+ 0x5898,0x5899,0x589a,0x589b,0x589c,0x589d,0x589e,0x589f,
+ 0x58a0,0x58a1,0x58a2,0x58a3,0x58a4,0x58a5,0x58a6,0x58a7,
+ 0x58a8,0x58a9,0x58aa,0x58ab,0x58ac,0x58ad,0x58ae,0x58af,
+ 0x58b0,0x58b1,0x58b2,0x58b3,0x58b4,0x58b5,0x58b6,0x58b7,
+ 0x58b8,0x58b9,0x58ba,0x58bb,0x58bc,0x58bd,0x58be,0x58bf,
+ 0x58c0,0x58c1,0x58c2,0x58c3,0x58c4,0x58c5,0x58c6,0x58c7,
+ 0x58c8,0x58c9,0x58ca,0x58cb,0x58cc,0x58cd,0x58ce,0x58cf,
+ 0x58d0,0x58d1,0x58d2,0x58d3,0x58d4,0x58d5,0x58d6,0x58d7,
+ 0x58d8,0x58d9,0x58da,0x58db,0x58dc,0x58dd,0x58de,0x58df,
+ 0x58e0,0x58e1,0x58e2,0x58e3,0x58e4,0x58e5,0x58e6,0x58e7,
+ 0x58e8,0x58e9,0x58ea,0x58eb,0x58ec,0x58ed,0x58ee,0x58ef,
+ 0x58f0,0x58f1,0x58f2,0x58f3,0x58f4,0x58f5,0x58f6,0x58f7,
+ 0x58f8,0x58f9,0x58fa,0x58fb,0x58fc,0x58fd,0x58fe,0x58ff,
+ 0x5900,0x5901,0x5902,0x5903,0x5904,0x5905,0x5906,0x5907,
+ 0x5908,0x5909,0x590a,0x590b,0x590c,0x590d,0x590e,0x590f,
+ 0x5910,0x5911,0x5912,0x5913,0x5914,0x5915,0x5916,0x5917,
+ 0x5918,0x5919,0x591a,0x591b,0x591c,0x591d,0x591e,0x591f,
+ 0x5920,0x5921,0x5922,0x5923,0x5924,0x5925,0x5926,0x5927,
+ 0x5928,0x5929,0x592a,0x592b,0x592c,0x592d,0x592e,0x592f,
+ 0x5930,0x5931,0x5932,0x5933,0x5934,0x5935,0x5936,0x5937,
+ 0x5938,0x5939,0x593a,0x593b,0x593c,0x593d,0x593e,0x593f,
+ 0x5940,0x5941,0x5942,0x5943,0x5944,0x5945,0x5946,0x5947,
+ 0x5948,0x5949,0x594a,0x594b,0x594c,0x594d,0x594e,0x594f,
+ 0x5950,0x5951,0x5952,0x5953,0x5954,0x5955,0x5956,0x5957,
+ 0x5958,0x5959,0x595a,0x595b,0x595c,0x595d,0x595e,0x595f,
+ 0x5960,0x5961,0x5962,0x5963,0x5964,0x5965,0x5966,0x5967,
+ 0x5968,0x5969,0x596a,0x596b,0x596c,0x596d,0x596e,0x596f,
+ 0x5970,0x5971,0x5972,0x5973,0x5974,0x5975,0x5976,0x5977,
+ 0x5978,0x5979,0x597a,0x597b,0x597c,0x597d,0x597e,0x597f,
+ 0x5980,0x5981,0x5982,0x5983,0x5984,0x5985,0x5986,0x5987,
+ 0x5988,0x5989,0x598a,0x598b,0x598c,0x598d,0x598e,0x598f,
+ 0x5990,0x5991,0x5992,0x5993,0x5994,0x5995,0x5996,0x5997,
+ 0x5998,0x5999,0x599a,0x599b,0x599c,0x599d,0x599e,0x599f,
+ 0x59a0,0x59a1,0x59a2,0x59a3,0x59a4,0x59a5,0x59a6,0x59a7,
+ 0x59a8,0x59a9,0x59aa,0x59ab,0x59ac,0x59ad,0x59ae,0x59af,
+ 0x59b0,0x59b1,0x59b2,0x59b3,0x59b4,0x59b5,0x59b6,0x59b7,
+ 0x59b8,0x59b9,0x59ba,0x59bb,0x59bc,0x59bd,0x59be,0x59bf,
+ 0x59c0,0x59c1,0x59c2,0x59c3,0x59c4,0x59c5,0x59c6,0x59c7,
+ 0x59c8,0x59c9,0x59ca,0x59cb,0x59cc,0x59cd,0x59ce,0x59cf,
+ 0x59d0,0x59d1,0x59d2,0x59d3,0x59d4,0x59d5,0x59d6,0x59d7,
+ 0x59d8,0x59d9,0x59da,0x59db,0x59dc,0x59dd,0x59de,0x59df,
+ 0x59e0,0x59e1,0x59e2,0x59e3,0x59e4,0x59e5,0x59e6,0x59e7,
+ 0x59e8,0x59e9,0x59ea,0x59eb,0x59ec,0x59ed,0x59ee,0x59ef,
+ 0x59f0,0x59f1,0x59f2,0x59f3,0x59f4,0x59f5,0x59f6,0x59f7,
+ 0x59f8,0x59f9,0x59fa,0x59fb,0x59fc,0x59fd,0x59fe,0x59ff,
+ 0x5a00,0x5a01,0x5a02,0x5a03,0x5a04,0x5a05,0x5a06,0x5a07,
+ 0x5a08,0x5a09,0x5a0a,0x5a0b,0x5a0c,0x5a0d,0x5a0e,0x5a0f,
+ 0x5a10,0x5a11,0x5a12,0x5a13,0x5a14,0x5a15,0x5a16,0x5a17,
+ 0x5a18,0x5a19,0x5a1a,0x5a1b,0x5a1c,0x5a1d,0x5a1e,0x5a1f,
+ 0x5a20,0x5a21,0x5a22,0x5a23,0x5a24,0x5a25,0x5a26,0x5a27,
+ 0x5a28,0x5a29,0x5a2a,0x5a2b,0x5a2c,0x5a2d,0x5a2e,0x5a2f,
+ 0x5a30,0x5a31,0x5a32,0x5a33,0x5a34,0x5a35,0x5a36,0x5a37,
+ 0x5a38,0x5a39,0x5a3a,0x5a3b,0x5a3c,0x5a3d,0x5a3e,0x5a3f,
+ 0x5a40,0x5a41,0x5a42,0x5a43,0x5a44,0x5a45,0x5a46,0x5a47,
+ 0x5a48,0x5a49,0x5a4a,0x5a4b,0x5a4c,0x5a4d,0x5a4e,0x5a4f,
+ 0x5a50,0x5a51,0x5a52,0x5a53,0x5a54,0x5a55,0x5a56,0x5a57,
+ 0x5a58,0x5a59,0x5a5a,0x5a5b,0x5a5c,0x5a5d,0x5a5e,0x5a5f,
+ 0x5a60,0x5a61,0x5a62,0x5a63,0x5a64,0x5a65,0x5a66,0x5a67,
+ 0x5a68,0x5a69,0x5a6a,0x5a6b,0x5a6c,0x5a6d,0x5a6e,0x5a6f,
+ 0x5a70,0x5a71,0x5a72,0x5a73,0x5a74,0x5a75,0x5a76,0x5a77,
+ 0x5a78,0x5a79,0x5a7a,0x5a7b,0x5a7c,0x5a7d,0x5a7e,0x5a7f,
+ 0x5a80,0x5a81,0x5a82,0x5a83,0x5a84,0x5a85,0x5a86,0x5a87,
+ 0x5a88,0x5a89,0x5a8a,0x5a8b,0x5a8c,0x5a8d,0x5a8e,0x5a8f,
+ 0x5a90,0x5a91,0x5a92,0x5a93,0x5a94,0x5a95,0x5a96,0x5a97,
+ 0x5a98,0x5a99,0x5a9a,0x5a9b,0x5a9c,0x5a9d,0x5a9e,0x5a9f,
+ 0x5aa0,0x5aa1,0x5aa2,0x5aa3,0x5aa4,0x5aa5,0x5aa6,0x5aa7,
+ 0x5aa8,0x5aa9,0x5aaa,0x5aab,0x5aac,0x5aad,0x5aae,0x5aaf,
+ 0x5ab0,0x5ab1,0x5ab2,0x5ab3,0x5ab4,0x5ab5,0x5ab6,0x5ab7,
+ 0x5ab8,0x5ab9,0x5aba,0x5abb,0x5abc,0x5abd,0x5abe,0x5abf,
+ 0x5ac0,0x5ac1,0x5ac2,0x5ac3,0x5ac4,0x5ac5,0x5ac6,0x5ac7,
+ 0x5ac8,0x5ac9,0x5aca,0x5acb,0x5acc,0x5acd,0x5ace,0x5acf,
+ 0x5ad0,0x5ad1,0x5ad2,0x5ad3,0x5ad4,0x5ad5,0x5ad6,0x5ad7,
+ 0x5ad8,0x5ad9,0x5ada,0x5adb,0x5adc,0x5add,0x5ade,0x5adf,
+ 0x5ae0,0x5ae1,0x5ae2,0x5ae3,0x5ae4,0x5ae5,0x5ae6,0x5ae7,
+ 0x5ae8,0x5ae9,0x5aea,0x5aeb,0x5aec,0x5aed,0x5aee,0x5aef,
+ 0x5af0,0x5af1,0x5af2,0x5af3,0x5af4,0x5af5,0x5af6,0x5af7,
+ 0x5af8,0x5af9,0x5afa,0x5afb,0x5afc,0x5afd,0x5afe,0x5aff,
+ 0x5b00,0x5b01,0x5b02,0x5b03,0x5b04,0x5b05,0x5b06,0x5b07,
+ 0x5b08,0x5b09,0x5b0a,0x5b0b,0x5b0c,0x5b0d,0x5b0e,0x5b0f,
+ 0x5b10,0x5b11,0x5b12,0x5b13,0x5b14,0x5b15,0x5b16,0x5b17,
+ 0x5b18,0x5b19,0x5b1a,0x5b1b,0x5b1c,0x5b1d,0x5b1e,0x5b1f,
+ 0x5b20,0x5b21,0x5b22,0x5b23,0x5b24,0x5b25,0x5b26,0x5b27,
+ 0x5b28,0x5b29,0x5b2a,0x5b2b,0x5b2c,0x5b2d,0x5b2e,0x5b2f,
+ 0x5b30,0x5b31,0x5b32,0x5b33,0x5b34,0x5b35,0x5b36,0x5b37,
+ 0x5b38,0x5b39,0x5b3a,0x5b3b,0x5b3c,0x5b3d,0x5b3e,0x5b3f,
+ 0x5b40,0x5b41,0x5b42,0x5b43,0x5b44,0x5b45,0x5b46,0x5b47,
+ 0x5b48,0x5b49,0x5b4a,0x5b4b,0x5b4c,0x5b4d,0x5b4e,0x5b4f,
+ 0x5b50,0x5b51,0x5b52,0x5b53,0x5b54,0x5b55,0x5b56,0x5b57,
+ 0x5b58,0x5b59,0x5b5a,0x5b5b,0x5b5c,0x5b5d,0x5b5e,0x5b5f,
+ 0x5b60,0x5b61,0x5b62,0x5b63,0x5b64,0x5b65,0x5b66,0x5b67,
+ 0x5b68,0x5b69,0x5b6a,0x5b6b,0x5b6c,0x5b6d,0x5b6e,0x5b6f,
+ 0x5b70,0x5b71,0x5b72,0x5b73,0x5b74,0x5b75,0x5b76,0x5b77,
+ 0x5b78,0x5b79,0x5b7a,0x5b7b,0x5b7c,0x5b7d,0x5b7e,0x5b7f,
+ 0x5b80,0x5b81,0x5b82,0x5b83,0x5b84,0x5b85,0x5b86,0x5b87,
+ 0x5b88,0x5b89,0x5b8a,0x5b8b,0x5b8c,0x5b8d,0x5b8e,0x5b8f,
+ 0x5b90,0x5b91,0x5b92,0x5b93,0x5b94,0x5b95,0x5b96,0x5b97,
+ 0x5b98,0x5b99,0x5b9a,0x5b9b,0x5b9c,0x5b9d,0x5b9e,0x5b9f,
+ 0x5ba0,0x5ba1,0x5ba2,0x5ba3,0x5ba4,0x5ba5,0x5ba6,0x5ba7,
+ 0x5ba8,0x5ba9,0x5baa,0x5bab,0x5bac,0x5bad,0x5bae,0x5baf,
+ 0x5bb0,0x5bb1,0x5bb2,0x5bb3,0x5bb4,0x5bb5,0x5bb6,0x5bb7,
+ 0x5bb8,0x5bb9,0x5bba,0x5bbb,0x5bbc,0x5bbd,0x5bbe,0x5bbf,
+ 0x5bc0,0x5bc1,0x5bc2,0x5bc3,0x5bc4,0x5bc5,0x5bc6,0x5bc7,
+ 0x5bc8,0x5bc9,0x5bca,0x5bcb,0x5bcc,0x5bcd,0x5bce,0x5bcf,
+ 0x5bd0,0x5bd1,0x5bd2,0x5bd3,0x5bd4,0x5bd5,0x5bd6,0x5bd7,
+ 0x5bd8,0x5bd9,0x5bda,0x5bdb,0x5bdc,0x5bdd,0x5bde,0x5bdf,
+ 0x5be0,0x5be1,0x5be2,0x5be3,0x5be4,0x5be5,0x5be6,0x5be7,
+ 0x5be8,0x5be9,0x5bea,0x5beb,0x5bec,0x5bed,0x5bee,0x5bef,
+ 0x5bf0,0x5bf1,0x5bf2,0x5bf3,0x5bf4,0x5bf5,0x5bf6,0x5bf7,
+ 0x5bf8,0x5bf9,0x5bfa,0x5bfb,0x5bfc,0x5bfd,0x5bfe,0x5bff,
+ 0x5c00,0x5c01,0x5c02,0x5c03,0x5c04,0x5c05,0x5c06,0x5c07,
+ 0x5c08,0x5c09,0x5c0a,0x5c0b,0x5c0c,0x5c0d,0x5c0e,0x5c0f,
+ 0x5c10,0x5c11,0x5c12,0x5c13,0x5c14,0x5c15,0x5c16,0x5c17,
+ 0x5c18,0x5c19,0x5c1a,0x5c1b,0x5c1c,0x5c1d,0x5c1e,0x5c1f,
+ 0x5c20,0x5c21,0x5c22,0x5c23,0x5c24,0x5c25,0x5c26,0x5c27,
+ 0x5c28,0x5c29,0x5c2a,0x5c2b,0x5c2c,0x5c2d,0x5c2e,0x5c2f,
+ 0x5c30,0x5c31,0x5c32,0x5c33,0x5c34,0x5c35,0x5c36,0x5c37,
+ 0x5c38,0x5c39,0x5c3a,0x5c3b,0x5c3c,0x5c3d,0x5c3e,0x5c3f,
+ 0x5c40,0x5c41,0x5c42,0x5c43,0x5c44,0x5c45,0x5c46,0x5c47,
+ 0x5c48,0x5c49,0x5c4a,0x5c4b,0x5c4c,0x5c4d,0x5c4e,0x5c4f,
+ 0x5c50,0x5c51,0x5c52,0x5c53,0x5c54,0x5c55,0x5c56,0x5c57,
+ 0x5c58,0x5c59,0x5c5a,0x5c5b,0x5c5c,0x5c5d,0x5c5e,0x5c5f,
+ 0x5c60,0x5c61,0x5c62,0x5c63,0x5c64,0x5c65,0x5c66,0x5c67,
+ 0x5c68,0x5c69,0x5c6a,0x5c6b,0x5c6c,0x5c6d,0x5c6e,0x5c6f,
+ 0x5c70,0x5c71,0x5c72,0x5c73,0x5c74,0x5c75,0x5c76,0x5c77,
+ 0x5c78,0x5c79,0x5c7a,0x5c7b,0x5c7c,0x5c7d,0x5c7e,0x5c7f,
+ 0x5c80,0x5c81,0x5c82,0x5c83,0x5c84,0x5c85,0x5c86,0x5c87,
+ 0x5c88,0x5c89,0x5c8a,0x5c8b,0x5c8c,0x5c8d,0x5c8e,0x5c8f,
+ 0x5c90,0x5c91,0x5c92,0x5c93,0x5c94,0x5c95,0x5c96,0x5c97,
+ 0x5c98,0x5c99,0x5c9a,0x5c9b,0x5c9c,0x5c9d,0x5c9e,0x5c9f,
+ 0x5ca0,0x5ca1,0x5ca2,0x5ca3,0x5ca4,0x5ca5,0x5ca6,0x5ca7,
+ 0x5ca8,0x5ca9,0x5caa,0x5cab,0x5cac,0x5cad,0x5cae,0x5caf,
+ 0x5cb0,0x5cb1,0x5cb2,0x5cb3,0x5cb4,0x5cb5,0x5cb6,0x5cb7,
+ 0x5cb8,0x5cb9,0x5cba,0x5cbb,0x5cbc,0x5cbd,0x5cbe,0x5cbf,
+ 0x5cc0,0x5cc1,0x5cc2,0x5cc3,0x5cc4,0x5cc5,0x5cc6,0x5cc7,
+ 0x5cc8,0x5cc9,0x5cca,0x5ccb,0x5ccc,0x5ccd,0x5cce,0x5ccf,
+ 0x5cd0,0x5cd1,0x5cd2,0x5cd3,0x5cd4,0x5cd5,0x5cd6,0x5cd7,
+ 0x5cd8,0x5cd9,0x5cda,0x5cdb,0x5cdc,0x5cdd,0x5cde,0x5cdf,
+ 0x5ce0,0x5ce1,0x5ce2,0x5ce3,0x5ce4,0x5ce5,0x5ce6,0x5ce7,
+ 0x5ce8,0x5ce9,0x5cea,0x5ceb,0x5cec,0x5ced,0x5cee,0x5cef,
+ 0x5cf0,0x5cf1,0x5cf2,0x5cf3,0x5cf4,0x5cf5,0x5cf6,0x5cf7,
+ 0x5cf8,0x5cf9,0x5cfa,0x5cfb,0x5cfc,0x5cfd,0x5cfe,0x5cff,
+ 0x5d00,0x5d01,0x5d02,0x5d03,0x5d04,0x5d05,0x5d06,0x5d07,
+ 0x5d08,0x5d09,0x5d0a,0x5d0b,0x5d0c,0x5d0d,0x5d0e,0x5d0f,
+ 0x5d10,0x5d11,0x5d12,0x5d13,0x5d14,0x5d15,0x5d16,0x5d17,
+ 0x5d18,0x5d19,0x5d1a,0x5d1b,0x5d1c,0x5d1d,0x5d1e,0x5d1f,
+ 0x5d20,0x5d21,0x5d22,0x5d23,0x5d24,0x5d25,0x5d26,0x5d27,
+ 0x5d28,0x5d29,0x5d2a,0x5d2b,0x5d2c,0x5d2d,0x5d2e,0x5d2f,
+ 0x5d30,0x5d31,0x5d32,0x5d33,0x5d34,0x5d35,0x5d36,0x5d37,
+ 0x5d38,0x5d39,0x5d3a,0x5d3b,0x5d3c,0x5d3d,0x5d3e,0x5d3f,
+ 0x5d40,0x5d41,0x5d42,0x5d43,0x5d44,0x5d45,0x5d46,0x5d47,
+ 0x5d48,0x5d49,0x5d4a,0x5d4b,0x5d4c,0x5d4d,0x5d4e,0x5d4f,
+ 0x5d50,0x5d51,0x5d52,0x5d53,0x5d54,0x5d55,0x5d56,0x5d57,
+ 0x5d58,0x5d59,0x5d5a,0x5d5b,0x5d5c,0x5d5d,0x5d5e,0x5d5f,
+ 0x5d60,0x5d61,0x5d62,0x5d63,0x5d64,0x5d65,0x5d66,0x5d67,
+ 0x5d68,0x5d69,0x5d6a,0x5d6b,0x5d6c,0x5d6d,0x5d6e,0x5d6f,
+ 0x5d70,0x5d71,0x5d72,0x5d73,0x5d74,0x5d75,0x5d76,0x5d77,
+ 0x5d78,0x5d79,0x5d7a,0x5d7b,0x5d7c,0x5d7d,0x5d7e,0x5d7f,
+ 0x5d80,0x5d81,0x5d82,0x5d83,0x5d84,0x5d85,0x5d86,0x5d87,
+ 0x5d88,0x5d89,0x5d8a,0x5d8b,0x5d8c,0x5d8d,0x5d8e,0x5d8f,
+ 0x5d90,0x5d91,0x5d92,0x5d93,0x5d94,0x5d95,0x5d96,0x5d97,
+ 0x5d98,0x5d99,0x5d9a,0x5d9b,0x5d9c,0x5d9d,0x5d9e,0x5d9f,
+ 0x5da0,0x5da1,0x5da2,0x5da3,0x5da4,0x5da5,0x5da6,0x5da7,
+ 0x5da8,0x5da9,0x5daa,0x5dab,0x5dac,0x5dad,0x5dae,0x5daf,
+ 0x5db0,0x5db1,0x5db2,0x5db3,0x5db4,0x5db5,0x5db6,0x5db7,
+ 0x5db8,0x5db9,0x5dba,0x5dbb,0x5dbc,0x5dbd,0x5dbe,0x5dbf,
+ 0x5dc0,0x5dc1,0x5dc2,0x5dc3,0x5dc4,0x5dc5,0x5dc6,0x5dc7,
+ 0x5dc8,0x5dc9,0x5dca,0x5dcb,0x5dcc,0x5dcd,0x5dce,0x5dcf,
+ 0x5dd0,0x5dd1,0x5dd2,0x5dd3,0x5dd4,0x5dd5,0x5dd6,0x5dd7,
+ 0x5dd8,0x5dd9,0x5dda,0x5ddb,0x5ddc,0x5ddd,0x5dde,0x5ddf,
+ 0x5de0,0x5de1,0x5de2,0x5de3,0x5de4,0x5de5,0x5de6,0x5de7,
+ 0x5de8,0x5de9,0x5dea,0x5deb,0x5dec,0x5ded,0x5dee,0x5def,
+ 0x5df0,0x5df1,0x5df2,0x5df3,0x5df4,0x5df5,0x5df6,0x5df7,
+ 0x5df8,0x5df9,0x5dfa,0x5dfb,0x5dfc,0x5dfd,0x5dfe,0x5dff,
+ 0x5e00,0x5e01,0x5e02,0x5e03,0x5e04,0x5e05,0x5e06,0x5e07,
+ 0x5e08,0x5e09,0x5e0a,0x5e0b,0x5e0c,0x5e0d,0x5e0e,0x5e0f,
+ 0x5e10,0x5e11,0x5e12,0x5e13,0x5e14,0x5e15,0x5e16,0x5e17,
+ 0x5e18,0x5e19,0x5e1a,0x5e1b,0x5e1c,0x5e1d,0x5e1e,0x5e1f,
+ 0x5e20,0x5e21,0x5e22,0x5e23,0x5e24,0x5e25,0x5e26,0x5e27,
+ 0x5e28,0x5e29,0x5e2a,0x5e2b,0x5e2c,0x5e2d,0x5e2e,0x5e2f,
+ 0x5e30,0x5e31,0x5e32,0x5e33,0x5e34,0x5e35,0x5e36,0x5e37,
+ 0x5e38,0x5e39,0x5e3a,0x5e3b,0x5e3c,0x5e3d,0x5e3e,0x5e3f,
+ 0x5e40,0x5e41,0x5e42,0x5e43,0x5e44,0x5e45,0x5e46,0x5e47,
+ 0x5e48,0x5e49,0x5e4a,0x5e4b,0x5e4c,0x5e4d,0x5e4e,0x5e4f,
+ 0x5e50,0x5e51,0x5e52,0x5e53,0x5e54,0x5e55,0x5e56,0x5e57,
+ 0x5e58,0x5e59,0x5e5a,0x5e5b,0x5e5c,0x5e5d,0x5e5e,0x5e5f,
+ 0x5e60,0x5e61,0x5e62,0x5e63,0x5e64,0x5e65,0x5e66,0x5e67,
+ 0x5e68,0x5e69,0x5e6a,0x5e6b,0x5e6c,0x5e6d,0x5e6e,0x5e6f,
+ 0x5e70,0x5e71,0x5e72,0x5e73,0x5e74,0x5e75,0x5e76,0x5e77,
+ 0x5e78,0x5e79,0x5e7a,0x5e7b,0x5e7c,0x5e7d,0x5e7e,0x5e7f,
+ 0x5e80,0x5e81,0x5e82,0x5e83,0x5e84,0x5e85,0x5e86,0x5e87,
+ 0x5e88,0x5e89,0x5e8a,0x5e8b,0x5e8c,0x5e8d,0x5e8e,0x5e8f,
+ 0x5e90,0x5e91,0x5e92,0x5e93,0x5e94,0x5e95,0x5e96,0x5e97,
+ 0x5e98,0x5e99,0x5e9a,0x5e9b,0x5e9c,0x5e9d,0x5e9e,0x5e9f,
+ 0x5ea0,0x5ea1,0x5ea2,0x5ea3,0x5ea4,0x5ea5,0x5ea6,0x5ea7,
+ 0x5ea8,0x5ea9,0x5eaa,0x5eab,0x5eac,0x5ead,0x5eae,0x5eaf,
+ 0x5eb0,0x5eb1,0x5eb2,0x5eb3,0x5eb4,0x5eb5,0x5eb6,0x5eb7,
+ 0x5eb8,0x5eb9,0x5eba,0x5ebb,0x5ebc,0x5ebd,0x5ebe,0x5ebf,
+ 0x5ec0,0x5ec1,0x5ec2,0x5ec3,0x5ec4,0x5ec5,0x5ec6,0x5ec7,
+ 0x5ec8,0x5ec9,0x5eca,0x5ecb,0x5ecc,0x5ecd,0x5ece,0x5ecf,
+ 0x5ed0,0x5ed1,0x5ed2,0x5ed3,0x5ed4,0x5ed5,0x5ed6,0x5ed7,
+ 0x5ed8,0x5ed9,0x5eda,0x5edb,0x5edc,0x5edd,0x5ede,0x5edf,
+ 0x5ee0,0x5ee1,0x5ee2,0x5ee3,0x5ee4,0x5ee5,0x5ee6,0x5ee7,
+ 0x5ee8,0x5ee9,0x5eea,0x5eeb,0x5eec,0x5eed,0x5eee,0x5eef,
+ 0x5ef0,0x5ef1,0x5ef2,0x5ef3,0x5ef4,0x5ef5,0x5ef6,0x5ef7,
+ 0x5ef8,0x5ef9,0x5efa,0x5efb,0x5efc,0x5efd,0x5efe,0x5eff,
+ 0x5f00,0x5f01,0x5f02,0x5f03,0x5f04,0x5f05,0x5f06,0x5f07,
+ 0x5f08,0x5f09,0x5f0a,0x5f0b,0x5f0c,0x5f0d,0x5f0e,0x5f0f,
+ 0x5f10,0x5f11,0x5f12,0x5f13,0x5f14,0x5f15,0x5f16,0x5f17,
+ 0x5f18,0x5f19,0x5f1a,0x5f1b,0x5f1c,0x5f1d,0x5f1e,0x5f1f,
+ 0x5f20,0x5f21,0x5f22,0x5f23,0x5f24,0x5f25,0x5f26,0x5f27,
+ 0x5f28,0x5f29,0x5f2a,0x5f2b,0x5f2c,0x5f2d,0x5f2e,0x5f2f,
+ 0x5f30,0x5f31,0x5f32,0x5f33,0x5f34,0x5f35,0x5f36,0x5f37,
+ 0x5f38,0x5f39,0x5f3a,0x5f3b,0x5f3c,0x5f3d,0x5f3e,0x5f3f,
+ 0x5f40,0x5f41,0x5f42,0x5f43,0x5f44,0x5f45,0x5f46,0x5f47,
+ 0x5f48,0x5f49,0x5f4a,0x5f4b,0x5f4c,0x5f4d,0x5f4e,0x5f4f,
+ 0x5f50,0x5f51,0x5f52,0x5f53,0x5f54,0x5f55,0x5f56,0x5f57,
+ 0x5f58,0x5f59,0x5f5a,0x5f5b,0x5f5c,0x5f5d,0x5f5e,0x5f5f,
+ 0x5f60,0x5f61,0x5f62,0x5f63,0x5f64,0x5f65,0x5f66,0x5f67,
+ 0x5f68,0x5f69,0x5f6a,0x5f6b,0x5f6c,0x5f6d,0x5f6e,0x5f6f,
+ 0x5f70,0x5f71,0x5f72,0x5f73,0x5f74,0x5f75,0x5f76,0x5f77,
+ 0x5f78,0x5f79,0x5f7a,0x5f7b,0x5f7c,0x5f7d,0x5f7e,0x5f7f,
+ 0x5f80,0x5f81,0x5f82,0x5f83,0x5f84,0x5f85,0x5f86,0x5f87,
+ 0x5f88,0x5f89,0x5f8a,0x5f8b,0x5f8c,0x5f8d,0x5f8e,0x5f8f,
+ 0x5f90,0x5f91,0x5f92,0x5f93,0x5f94,0x5f95,0x5f96,0x5f97,
+ 0x5f98,0x5f99,0x5f9a,0x5f9b,0x5f9c,0x5f9d,0x5f9e,0x5f9f,
+ 0x5fa0,0x5fa1,0x5fa2,0x5fa3,0x5fa4,0x5fa5,0x5fa6,0x5fa7,
+ 0x5fa8,0x5fa9,0x5faa,0x5fab,0x5fac,0x5fad,0x5fae,0x5faf,
+ 0x5fb0,0x5fb1,0x5fb2,0x5fb3,0x5fb4,0x5fb5,0x5fb6,0x5fb7,
+ 0x5fb8,0x5fb9,0x5fba,0x5fbb,0x5fbc,0x5fbd,0x5fbe,0x5fbf,
+ 0x5fc0,0x5fc1,0x5fc2,0x5fc3,0x5fc4,0x5fc5,0x5fc6,0x5fc7,
+ 0x5fc8,0x5fc9,0x5fca,0x5fcb,0x5fcc,0x5fcd,0x5fce,0x5fcf,
+ 0x5fd0,0x5fd1,0x5fd2,0x5fd3,0x5fd4,0x5fd5,0x5fd6,0x5fd7,
+ 0x5fd8,0x5fd9,0x5fda,0x5fdb,0x5fdc,0x5fdd,0x5fde,0x5fdf,
+ 0x5fe0,0x5fe1,0x5fe2,0x5fe3,0x5fe4,0x5fe5,0x5fe6,0x5fe7,
+ 0x5fe8,0x5fe9,0x5fea,0x5feb,0x5fec,0x5fed,0x5fee,0x5fef,
+ 0x5ff0,0x5ff1,0x5ff2,0x5ff3,0x5ff4,0x5ff5,0x5ff6,0x5ff7,
+ 0x5ff8,0x5ff9,0x5ffa,0x5ffb,0x5ffc,0x5ffd,0x5ffe,0x5fff,
+ 0x6000,0x6001,0x6002,0x6003,0x6004,0x6005,0x6006,0x6007,
+ 0x6008,0x6009,0x600a,0x600b,0x600c,0x600d,0x600e,0x600f,
+ 0x6010,0x6011,0x6012,0x6013,0x6014,0x6015,0x6016,0x6017,
+ 0x6018,0x6019,0x601a,0x601b,0x601c,0x601d,0x601e,0x601f,
+ 0x6020,0x6021,0x6022,0x6023,0x6024,0x6025,0x6026,0x6027,
+ 0x6028,0x6029,0x602a,0x602b,0x602c,0x602d,0x602e,0x602f,
+ 0x6030,0x6031,0x6032,0x6033,0x6034,0x6035,0x6036,0x6037,
+ 0x6038,0x6039,0x603a,0x603b,0x603c,0x603d,0x603e,0x603f,
+ 0x6040,0x6041,0x6042,0x6043,0x6044,0x6045,0x6046,0x6047,
+ 0x6048,0x6049,0x604a,0x604b,0x604c,0x604d,0x604e,0x604f,
+ 0x6050,0x6051,0x6052,0x6053,0x6054,0x6055,0x6056,0x6057,
+ 0x6058,0x6059,0x605a,0x605b,0x605c,0x605d,0x605e,0x605f,
+ 0x6060,0x6061,0x6062,0x6063,0x6064,0x6065,0x6066,0x6067,
+ 0x6068,0x6069,0x606a,0x606b,0x606c,0x606d,0x606e,0x606f,
+ 0x6070,0x6071,0x6072,0x6073,0x6074,0x6075,0x6076,0x6077,
+ 0x6078,0x6079,0x607a,0x607b,0x607c,0x607d,0x607e,0x607f,
+ 0x6080,0x6081,0x6082,0x6083,0x6084,0x6085,0x6086,0x6087,
+ 0x6088,0x6089,0x608a,0x608b,0x608c,0x608d,0x608e,0x608f,
+ 0x6090,0x6091,0x6092,0x6093,0x6094,0x6095,0x6096,0x6097,
+ 0x6098,0x6099,0x609a,0x609b,0x609c,0x609d,0x609e,0x609f,
+ 0x60a0,0x60a1,0x60a2,0x60a3,0x60a4,0x60a5,0x60a6,0x60a7,
+ 0x60a8,0x60a9,0x60aa,0x60ab,0x60ac,0x60ad,0x60ae,0x60af,
+ 0x60b0,0x60b1,0x60b2,0x60b3,0x60b4,0x60b5,0x60b6,0x60b7,
+ 0x60b8,0x60b9,0x60ba,0x60bb,0x60bc,0x60bd,0x60be,0x60bf,
+ 0x60c0,0x60c1,0x60c2,0x60c3,0x60c4,0x60c5,0x60c6,0x60c7,
+ 0x60c8,0x60c9,0x60ca,0x60cb,0x60cc,0x60cd,0x60ce,0x60cf,
+ 0x60d0,0x60d1,0x60d2,0x60d3,0x60d4,0x60d5,0x60d6,0x60d7,
+ 0x60d8,0x60d9,0x60da,0x60db,0x60dc,0x60dd,0x60de,0x60df,
+ 0x60e0,0x60e1,0x60e2,0x60e3,0x60e4,0x60e5,0x60e6,0x60e7,
+ 0x60e8,0x60e9,0x60ea,0x60eb,0x60ec,0x60ed,0x60ee,0x60ef,
+ 0x60f0,0x60f1,0x60f2,0x60f3,0x60f4,0x60f5,0x60f6,0x60f7,
+ 0x60f8,0x60f9,0x60fa,0x60fb,0x60fc,0x60fd,0x60fe,0x60ff,
+ 0x6100,0x6101,0x6102,0x6103,0x6104,0x6105,0x6106,0x6107,
+ 0x6108,0x6109,0x610a,0x610b,0x610c,0x610d,0x610e,0x610f,
+ 0x6110,0x6111,0x6112,0x6113,0x6114,0x6115,0x6116,0x6117,
+ 0x6118,0x6119,0x611a,0x611b,0x611c,0x611d,0x611e,0x611f,
+ 0x6120,0x6121,0x6122,0x6123,0x6124,0x6125,0x6126,0x6127,
+ 0x6128,0x6129,0x612a,0x612b,0x612c,0x612d,0x612e,0x612f,
+ 0x6130,0x6131,0x6132,0x6133,0x6134,0x6135,0x6136,0x6137,
+ 0x6138,0x6139,0x613a,0x613b,0x613c,0x613d,0x613e,0x613f,
+ 0x6140,0x6141,0x6142,0x6143,0x6144,0x6145,0x6146,0x6147,
+ 0x6148,0x6149,0x614a,0x614b,0x614c,0x614d,0x614e,0x614f,
+ 0x6150,0x6151,0x6152,0x6153,0x6154,0x6155,0x6156,0x6157,
+ 0x6158,0x6159,0x615a,0x615b,0x615c,0x615d,0x615e,0x615f,
+ 0x6160,0x6161,0x6162,0x6163,0x6164,0x6165,0x6166,0x6167,
+ 0x6168,0x6169,0x616a,0x616b,0x616c,0x616d,0x616e,0x616f,
+ 0x6170,0x6171,0x6172,0x6173,0x6174,0x6175,0x6176,0x6177,
+ 0x6178,0x6179,0x617a,0x617b,0x617c,0x617d,0x617e,0x617f,
+ 0x6180,0x6181,0x6182,0x6183,0x6184,0x6185,0x6186,0x6187,
+ 0x6188,0x6189,0x618a,0x618b,0x618c,0x618d,0x618e,0x618f,
+ 0x6190,0x6191,0x6192,0x6193,0x6194,0x6195,0x6196,0x6197,
+ 0x6198,0x6199,0x619a,0x619b,0x619c,0x619d,0x619e,0x619f,
+ 0x61a0,0x61a1,0x61a2,0x61a3,0x61a4,0x61a5,0x61a6,0x61a7,
+ 0x61a8,0x61a9,0x61aa,0x61ab,0x61ac,0x61ad,0x61ae,0x61af,
+ 0x61b0,0x61b1,0x61b2,0x61b3,0x61b4,0x61b5,0x61b6,0x61b7,
+ 0x61b8,0x61b9,0x61ba,0x61bb,0x61bc,0x61bd,0x61be,0x61bf,
+ 0x61c0,0x61c1,0x61c2,0x61c3,0x61c4,0x61c5,0x61c6,0x61c7,
+ 0x61c8,0x61c9,0x61ca,0x61cb,0x61cc,0x61cd,0x61ce,0x61cf,
+ 0x61d0,0x61d1,0x61d2,0x61d3,0x61d4,0x61d5,0x61d6,0x61d7,
+ 0x61d8,0x61d9,0x61da,0x61db,0x61dc,0x61dd,0x61de,0x61df,
+ 0x61e0,0x61e1,0x61e2,0x61e3,0x61e4,0x61e5,0x61e6,0x61e7,
+ 0x61e8,0x61e9,0x61ea,0x61eb,0x61ec,0x61ed,0x61ee,0x61ef,
+ 0x61f0,0x61f1,0x61f2,0x61f3,0x61f4,0x61f5,0x61f6,0x61f7,
+ 0x61f8,0x61f9,0x61fa,0x61fb,0x61fc,0x61fd,0x61fe,0x61ff,
+ 0x6200,0x6201,0x6202,0x6203,0x6204,0x6205,0x6206,0x6207,
+ 0x6208,0x6209,0x620a,0x620b,0x620c,0x620d,0x620e,0x620f,
+ 0x6210,0x6211,0x6212,0x6213,0x6214,0x6215,0x6216,0x6217,
+ 0x6218,0x6219,0x621a,0x621b,0x621c,0x621d,0x621e,0x621f,
+ 0x6220,0x6221,0x6222,0x6223,0x6224,0x6225,0x6226,0x6227,
+ 0x6228,0x6229,0x622a,0x622b,0x622c,0x622d,0x622e,0x622f,
+ 0x6230,0x6231,0x6232,0x6233,0x6234,0x6235,0x6236,0x6237,
+ 0x6238,0x6239,0x623a,0x623b,0x623c,0x623d,0x623e,0x623f,
+ 0x6240,0x6241,0x6242,0x6243,0x6244,0x6245,0x6246,0x6247,
+ 0x6248,0x6249,0x624a,0x624b,0x624c,0x624d,0x624e,0x624f,
+ 0x6250,0x6251,0x6252,0x6253,0x6254,0x6255,0x6256,0x6257,
+ 0x6258,0x6259,0x625a,0x625b,0x625c,0x625d,0x625e,0x625f,
+ 0x6260,0x6261,0x6262,0x6263,0x6264,0x6265,0x6266,0x6267,
+ 0x6268,0x6269,0x626a,0x626b,0x626c,0x626d,0x626e,0x626f,
+ 0x6270,0x6271,0x6272,0x6273,0x6274,0x6275,0x6276,0x6277,
+ 0x6278,0x6279,0x627a,0x627b,0x627c,0x627d,0x627e,0x627f,
+ 0x6280,0x6281,0x6282,0x6283,0x6284,0x6285,0x6286,0x6287,
+ 0x6288,0x6289,0x628a,0x628b,0x628c,0x628d,0x628e,0x628f,
+ 0x6290,0x6291,0x6292,0x6293,0x6294,0x6295,0x6296,0x6297,
+ 0x6298,0x6299,0x629a,0x629b,0x629c,0x629d,0x629e,0x629f,
+ 0x62a0,0x62a1,0x62a2,0x62a3,0x62a4,0x62a5,0x62a6,0x62a7,
+ 0x62a8,0x62a9,0x62aa,0x62ab,0x62ac,0x62ad,0x62ae,0x62af,
+ 0x62b0,0x62b1,0x62b2,0x62b3,0x62b4,0x62b5,0x62b6,0x62b7,
+ 0x62b8,0x62b9,0x62ba,0x62bb,0x62bc,0x62bd,0x62be,0x62bf,
+ 0x62c0,0x62c1,0x62c2,0x62c3,0x62c4,0x62c5,0x62c6,0x62c7,
+ 0x62c8,0x62c9,0x62ca,0x62cb,0x62cc,0x62cd,0x62ce,0x62cf,
+ 0x62d0,0x62d1,0x62d2,0x62d3,0x62d4,0x62d5,0x62d6,0x62d7,
+ 0x62d8,0x62d9,0x62da,0x62db,0x62dc,0x62dd,0x62de,0x62df,
+ 0x62e0,0x62e1,0x62e2,0x62e3,0x62e4,0x62e5,0x62e6,0x62e7,
+ 0x62e8,0x62e9,0x62ea,0x62eb,0x62ec,0x62ed,0x62ee,0x62ef,
+ 0x62f0,0x62f1,0x62f2,0x62f3,0x62f4,0x62f5,0x62f6,0x62f7,
+ 0x62f8,0x62f9,0x62fa,0x62fb,0x62fc,0x62fd,0x62fe,0x62ff,
+ 0x6300,0x6301,0x6302,0x6303,0x6304,0x6305,0x6306,0x6307,
+ 0x6308,0x6309,0x630a,0x630b,0x630c,0x630d,0x630e,0x630f,
+ 0x6310,0x6311,0x6312,0x6313,0x6314,0x6315,0x6316,0x6317,
+ 0x6318,0x6319,0x631a,0x631b,0x631c,0x631d,0x631e,0x631f,
+ 0x6320,0x6321,0x6322,0x6323,0x6324,0x6325,0x6326,0x6327,
+ 0x6328,0x6329,0x632a,0x632b,0x632c,0x632d,0x632e,0x632f,
+ 0x6330,0x6331,0x6332,0x6333,0x6334,0x6335,0x6336,0x6337,
+ 0x6338,0x6339,0x633a,0x633b,0x633c,0x633d,0x633e,0x633f,
+ 0x6340,0x6341,0x6342,0x6343,0x6344,0x6345,0x6346,0x6347,
+ 0x6348,0x6349,0x634a,0x634b,0x634c,0x634d,0x634e,0x634f,
+ 0x6350,0x6351,0x6352,0x6353,0x6354,0x6355,0x6356,0x6357,
+ 0x6358,0x6359,0x635a,0x635b,0x635c,0x635d,0x635e,0x635f,
+ 0x6360,0x6361,0x6362,0x6363,0x6364,0x6365,0x6366,0x6367,
+ 0x6368,0x6369,0x636a,0x636b,0x636c,0x636d,0x636e,0x636f,
+ 0x6370,0x6371,0x6372,0x6373,0x6374,0x6375,0x6376,0x6377,
+ 0x6378,0x6379,0x637a,0x637b,0x637c,0x637d,0x637e,0x637f,
+ 0x6380,0x6381,0x6382,0x6383,0x6384,0x6385,0x6386,0x6387,
+ 0x6388,0x6389,0x638a,0x638b,0x638c,0x638d,0x638e,0x638f,
+ 0x6390,0x6391,0x6392,0x6393,0x6394,0x6395,0x6396,0x6397,
+ 0x6398,0x6399,0x639a,0x639b,0x639c,0x639d,0x639e,0x639f,
+ 0x63a0,0x63a1,0x63a2,0x63a3,0x63a4,0x63a5,0x63a6,0x63a7,
+ 0x63a8,0x63a9,0x63aa,0x63ab,0x63ac,0x63ad,0x63ae,0x63af,
+ 0x63b0,0x63b1,0x63b2,0x63b3,0x63b4,0x63b5,0x63b6,0x63b7,
+ 0x63b8,0x63b9,0x63ba,0x63bb,0x63bc,0x63bd,0x63be,0x63bf,
+ 0x63c0,0x63c1,0x63c2,0x63c3,0x63c4,0x63c5,0x63c6,0x63c7,
+ 0x63c8,0x63c9,0x63ca,0x63cb,0x63cc,0x63cd,0x63ce,0x63cf,
+ 0x63d0,0x63d1,0x63d2,0x63d3,0x63d4,0x63d5,0x63d6,0x63d7,
+ 0x63d8,0x63d9,0x63da,0x63db,0x63dc,0x63dd,0x63de,0x63df,
+ 0x63e0,0x63e1,0x63e2,0x63e3,0x63e4,0x63e5,0x63e6,0x63e7,
+ 0x63e8,0x63e9,0x63ea,0x63eb,0x63ec,0x63ed,0x63ee,0x63ef,
+ 0x63f0,0x63f1,0x63f2,0x63f3,0x63f4,0x63f5,0x63f6,0x63f7,
+ 0x63f8,0x63f9,0x63fa,0x63fb,0x63fc,0x63fd,0x63fe,0x63ff,
+ 0x6400,0x6401,0x6402,0x6403,0x6404,0x6405,0x6406,0x6407,
+ 0x6408,0x6409,0x640a,0x640b,0x640c,0x640d,0x640e,0x640f,
+ 0x6410,0x6411,0x6412,0x6413,0x6414,0x6415,0x6416,0x6417,
+ 0x6418,0x6419,0x641a,0x641b,0x641c,0x641d,0x641e,0x641f,
+ 0x6420,0x6421,0x6422,0x6423,0x6424,0x6425,0x6426,0x6427,
+ 0x6428,0x6429,0x642a,0x642b,0x642c,0x642d,0x642e,0x642f,
+ 0x6430,0x6431,0x6432,0x6433,0x6434,0x6435,0x6436,0x6437,
+ 0x6438,0x6439,0x643a,0x643b,0x643c,0x643d,0x643e,0x643f,
+ 0x6440,0x6441,0x6442,0x6443,0x6444,0x6445,0x6446,0x6447,
+ 0x6448,0x6449,0x644a,0x644b,0x644c,0x644d,0x644e,0x644f,
+ 0x6450,0x6451,0x6452,0x6453,0x6454,0x6455,0x6456,0x6457,
+ 0x6458,0x6459,0x645a,0x645b,0x645c,0x645d,0x645e,0x645f,
+ 0x6460,0x6461,0x6462,0x6463,0x6464,0x6465,0x6466,0x6467,
+ 0x6468,0x6469,0x646a,0x646b,0x646c,0x646d,0x646e,0x646f,
+ 0x6470,0x6471,0x6472,0x6473,0x6474,0x6475,0x6476,0x6477,
+ 0x6478,0x6479,0x647a,0x647b,0x647c,0x647d,0x647e,0x647f,
+ 0x6480,0x6481,0x6482,0x6483,0x6484,0x6485,0x6486,0x6487,
+ 0x6488,0x6489,0x648a,0x648b,0x648c,0x648d,0x648e,0x648f,
+ 0x6490,0x6491,0x6492,0x6493,0x6494,0x6495,0x6496,0x6497,
+ 0x6498,0x6499,0x649a,0x649b,0x649c,0x649d,0x649e,0x649f,
+ 0x64a0,0x64a1,0x64a2,0x64a3,0x64a4,0x64a5,0x64a6,0x64a7,
+ 0x64a8,0x64a9,0x64aa,0x64ab,0x64ac,0x64ad,0x64ae,0x64af,
+ 0x64b0,0x64b1,0x64b2,0x64b3,0x64b4,0x64b5,0x64b6,0x64b7,
+ 0x64b8,0x64b9,0x64ba,0x64bb,0x64bc,0x64bd,0x64be,0x64bf,
+ 0x64c0,0x64c1,0x64c2,0x64c3,0x64c4,0x64c5,0x64c6,0x64c7,
+ 0x64c8,0x64c9,0x64ca,0x64cb,0x64cc,0x64cd,0x64ce,0x64cf,
+ 0x64d0,0x64d1,0x64d2,0x64d3,0x64d4,0x64d5,0x64d6,0x64d7,
+ 0x64d8,0x64d9,0x64da,0x64db,0x64dc,0x64dd,0x64de,0x64df,
+ 0x64e0,0x64e1,0x64e2,0x64e3,0x64e4,0x64e5,0x64e6,0x64e7,
+ 0x64e8,0x64e9,0x64ea,0x64eb,0x64ec,0x64ed,0x64ee,0x64ef,
+ 0x64f0,0x64f1,0x64f2,0x64f3,0x64f4,0x64f5,0x64f6,0x64f7,
+ 0x64f8,0x64f9,0x64fa,0x64fb,0x64fc,0x64fd,0x64fe,0x64ff,
+ 0x6500,0x6501,0x6502,0x6503,0x6504,0x6505,0x6506,0x6507,
+ 0x6508,0x6509,0x650a,0x650b,0x650c,0x650d,0x650e,0x650f,
+ 0x6510,0x6511,0x6512,0x6513,0x6514,0x6515,0x6516,0x6517,
+ 0x6518,0x6519,0x651a,0x651b,0x651c,0x651d,0x651e,0x651f,
+ 0x6520,0x6521,0x6522,0x6523,0x6524,0x6525,0x6526,0x6527,
+ 0x6528,0x6529,0x652a,0x652b,0x652c,0x652d,0x652e,0x652f,
+ 0x6530,0x6531,0x6532,0x6533,0x6534,0x6535,0x6536,0x6537,
+ 0x6538,0x6539,0x653a,0x653b,0x653c,0x653d,0x653e,0x653f,
+ 0x6540,0x6541,0x6542,0x6543,0x6544,0x6545,0x6546,0x6547,
+ 0x6548,0x6549,0x654a,0x654b,0x654c,0x654d,0x654e,0x654f,
+ 0x6550,0x6551,0x6552,0x6553,0x6554,0x6555,0x6556,0x6557,
+ 0x6558,0x6559,0x655a,0x655b,0x655c,0x655d,0x655e,0x655f,
+ 0x6560,0x6561,0x6562,0x6563,0x6564,0x6565,0x6566,0x6567,
+ 0x6568,0x6569,0x656a,0x656b,0x656c,0x656d,0x656e,0x656f,
+ 0x6570,0x6571,0x6572,0x6573,0x6574,0x6575,0x6576,0x6577,
+ 0x6578,0x6579,0x657a,0x657b,0x657c,0x657d,0x657e,0x657f,
+ 0x6580,0x6581,0x6582,0x6583,0x6584,0x6585,0x6586,0x6587,
+ 0x6588,0x6589,0x658a,0x658b,0x658c,0x658d,0x658e,0x658f,
+ 0x6590,0x6591,0x6592,0x6593,0x6594,0x6595,0x6596,0x6597,
+ 0x6598,0x6599,0x659a,0x659b,0x659c,0x659d,0x659e,0x659f,
+ 0x65a0,0x65a1,0x65a2,0x65a3,0x65a4,0x65a5,0x65a6,0x65a7,
+ 0x65a8,0x65a9,0x65aa,0x65ab,0x65ac,0x65ad,0x65ae,0x65af,
+ 0x65b0,0x65b1,0x65b2,0x65b3,0x65b4,0x65b5,0x65b6,0x65b7,
+ 0x65b8,0x65b9,0x65ba,0x65bb,0x65bc,0x65bd,0x65be,0x65bf,
+ 0x65c0,0x65c1,0x65c2,0x65c3,0x65c4,0x65c5,0x65c6,0x65c7,
+ 0x65c8,0x65c9,0x65ca,0x65cb,0x65cc,0x65cd,0x65ce,0x65cf,
+ 0x65d0,0x65d1,0x65d2,0x65d3,0x65d4,0x65d5,0x65d6,0x65d7,
+ 0x65d8,0x65d9,0x65da,0x65db,0x65dc,0x65dd,0x65de,0x65df,
+ 0x65e0,0x65e1,0x65e2,0x65e3,0x65e4,0x65e5,0x65e6,0x65e7,
+ 0x65e8,0x65e9,0x65ea,0x65eb,0x65ec,0x65ed,0x65ee,0x65ef,
+ 0x65f0,0x65f1,0x65f2,0x65f3,0x65f4,0x65f5,0x65f6,0x65f7,
+ 0x65f8,0x65f9,0x65fa,0x65fb,0x65fc,0x65fd,0x65fe,0x65ff,
+ 0x6600,0x6601,0x6602,0x6603,0x6604,0x6605,0x6606,0x6607,
+ 0x6608,0x6609,0x660a,0x660b,0x660c,0x660d,0x660e,0x660f,
+ 0x6610,0x6611,0x6612,0x6613,0x6614,0x6615,0x6616,0x6617,
+ 0x6618,0x6619,0x661a,0x661b,0x661c,0x661d,0x661e,0x661f,
+ 0x6620,0x6621,0x6622,0x6623,0x6624,0x6625,0x6626,0x6627,
+ 0x6628,0x6629,0x662a,0x662b,0x662c,0x662d,0x662e,0x662f,
+ 0x6630,0x6631,0x6632,0x6633,0x6634,0x6635,0x6636,0x6637,
+ 0x6638,0x6639,0x663a,0x663b,0x663c,0x663d,0x663e,0x663f,
+ 0x6640,0x6641,0x6642,0x6643,0x6644,0x6645,0x6646,0x6647,
+ 0x6648,0x6649,0x664a,0x664b,0x664c,0x664d,0x664e,0x664f,
+ 0x6650,0x6651,0x6652,0x6653,0x6654,0x6655,0x6656,0x6657,
+ 0x6658,0x6659,0x665a,0x665b,0x665c,0x665d,0x665e,0x665f,
+ 0x6660,0x6661,0x6662,0x6663,0x6664,0x6665,0x6666,0x6667,
+ 0x6668,0x6669,0x666a,0x666b,0x666c,0x666d,0x666e,0x666f,
+ 0x6670,0x6671,0x6672,0x6673,0x6674,0x6675,0x6676,0x6677,
+ 0x6678,0x6679,0x667a,0x667b,0x667c,0x667d,0x667e,0x667f,
+ 0x6680,0x6681,0x6682,0x6683,0x6684,0x6685,0x6686,0x6687,
+ 0x6688,0x6689,0x668a,0x668b,0x668c,0x668d,0x668e,0x668f,
+ 0x6690,0x6691,0x6692,0x6693,0x6694,0x6695,0x6696,0x6697,
+ 0x6698,0x6699,0x669a,0x669b,0x669c,0x669d,0x669e,0x669f,
+ 0x66a0,0x66a1,0x66a2,0x66a3,0x66a4,0x66a5,0x66a6,0x66a7,
+ 0x66a8,0x66a9,0x66aa,0x66ab,0x66ac,0x66ad,0x66ae,0x66af,
+ 0x66b0,0x66b1,0x66b2,0x66b3,0x66b4,0x66b5,0x66b6,0x66b7,
+ 0x66b8,0x66b9,0x66ba,0x66bb,0x66bc,0x66bd,0x66be,0x66bf,
+ 0x66c0,0x66c1,0x66c2,0x66c3,0x66c4,0x66c5,0x66c6,0x66c7,
+ 0x66c8,0x66c9,0x66ca,0x66cb,0x66cc,0x66cd,0x66ce,0x66cf,
+ 0x66d0,0x66d1,0x66d2,0x66d3,0x66d4,0x66d5,0x66d6,0x66d7,
+ 0x66d8,0x66d9,0x66da,0x66db,0x66dc,0x66dd,0x66de,0x66df,
+ 0x66e0,0x66e1,0x66e2,0x66e3,0x66e4,0x66e5,0x66e6,0x66e7,
+ 0x66e8,0x66e9,0x66ea,0x66eb,0x66ec,0x66ed,0x66ee,0x66ef,
+ 0x66f0,0x66f1,0x66f2,0x66f3,0x66f4,0x66f5,0x66f6,0x66f7,
+ 0x66f8,0x66f9,0x66fa,0x66fb,0x66fc,0x66fd,0x66fe,0x66ff,
+ 0x6700,0x6701,0x6702,0x6703,0x6704,0x6705,0x6706,0x6707,
+ 0x6708,0x6709,0x670a,0x670b,0x670c,0x670d,0x670e,0x670f,
+ 0x6710,0x6711,0x6712,0x6713,0x6714,0x6715,0x6716,0x6717,
+ 0x6718,0x6719,0x671a,0x671b,0x671c,0x671d,0x671e,0x671f,
+ 0x6720,0x6721,0x6722,0x6723,0x6724,0x6725,0x6726,0x6727,
+ 0x6728,0x6729,0x672a,0x672b,0x672c,0x672d,0x672e,0x672f,
+ 0x6730,0x6731,0x6732,0x6733,0x6734,0x6735,0x6736,0x6737,
+ 0x6738,0x6739,0x673a,0x673b,0x673c,0x673d,0x673e,0x673f,
+ 0x6740,0x6741,0x6742,0x6743,0x6744,0x6745,0x6746,0x6747,
+ 0x6748,0x6749,0x674a,0x674b,0x674c,0x674d,0x674e,0x674f,
+ 0x6750,0x6751,0x6752,0x6753,0x6754,0x6755,0x6756,0x6757,
+ 0x6758,0x6759,0x675a,0x675b,0x675c,0x675d,0x675e,0x675f,
+ 0x6760,0x6761,0x6762,0x6763,0x6764,0x6765,0x6766,0x6767,
+ 0x6768,0x6769,0x676a,0x676b,0x676c,0x676d,0x676e,0x676f,
+ 0x6770,0x6771,0x6772,0x6773,0x6774,0x6775,0x6776,0x6777,
+ 0x6778,0x6779,0x677a,0x677b,0x677c,0x677d,0x677e,0x677f,
+ 0x6780,0x6781,0x6782,0x6783,0x6784,0x6785,0x6786,0x6787,
+ 0x6788,0x6789,0x678a,0x678b,0x678c,0x678d,0x678e,0x678f,
+ 0x6790,0x6791,0x6792,0x6793,0x6794,0x6795,0x6796,0x6797,
+ 0x6798,0x6799,0x679a,0x679b,0x679c,0x679d,0x679e,0x679f,
+ 0x67a0,0x67a1,0x67a2,0x67a3,0x67a4,0x67a5,0x67a6,0x67a7,
+ 0x67a8,0x67a9,0x67aa,0x67ab,0x67ac,0x67ad,0x67ae,0x67af,
+ 0x67b0,0x67b1,0x67b2,0x67b3,0x67b4,0x67b5,0x67b6,0x67b7,
+ 0x67b8,0x67b9,0x67ba,0x67bb,0x67bc,0x67bd,0x67be,0x67bf,
+ 0x67c0,0x67c1,0x67c2,0x67c3,0x67c4,0x67c5,0x67c6,0x67c7,
+ 0x67c8,0x67c9,0x67ca,0x67cb,0x67cc,0x67cd,0x67ce,0x67cf,
+ 0x67d0,0x67d1,0x67d2,0x67d3,0x67d4,0x67d5,0x67d6,0x67d7,
+ 0x67d8,0x67d9,0x67da,0x67db,0x67dc,0x67dd,0x67de,0x67df,
+ 0x67e0,0x67e1,0x67e2,0x67e3,0x67e4,0x67e5,0x67e6,0x67e7,
+ 0x67e8,0x67e9,0x67ea,0x67eb,0x67ec,0x67ed,0x67ee,0x67ef,
+ 0x67f0,0x67f1,0x67f2,0x67f3,0x67f4,0x67f5,0x67f6,0x67f7,
+ 0x67f8,0x67f9,0x67fa,0x67fb,0x67fc,0x67fd,0x67fe,0x67ff,
+ 0x6800,0x6801,0x6802,0x6803,0x6804,0x6805,0x6806,0x6807,
+ 0x6808,0x6809,0x680a,0x680b,0x680c,0x680d,0x680e,0x680f,
+ 0x6810,0x6811,0x6812,0x6813,0x6814,0x6815,0x6816,0x6817,
+ 0x6818,0x6819,0x681a,0x681b,0x681c,0x681d,0x681e,0x681f,
+ 0x6820,0x6821,0x6822,0x6823,0x6824,0x6825,0x6826,0x6827,
+ 0x6828,0x6829,0x682a,0x682b,0x682c,0x682d,0x682e,0x682f,
+ 0x6830,0x6831,0x6832,0x6833,0x6834,0x6835,0x6836,0x6837,
+ 0x6838,0x6839,0x683a,0x683b,0x683c,0x683d,0x683e,0x683f,
+ 0x6840,0x6841,0x6842,0x6843,0x6844,0x6845,0x6846,0x6847,
+ 0x6848,0x6849,0x684a,0x684b,0x684c,0x684d,0x684e,0x684f,
+ 0x6850,0x6851,0x6852,0x6853,0x6854,0x6855,0x6856,0x6857,
+ 0x6858,0x6859,0x685a,0x685b,0x685c,0x685d,0x685e,0x685f,
+ 0x6860,0x6861,0x6862,0x6863,0x6864,0x6865,0x6866,0x6867,
+ 0x6868,0x6869,0x686a,0x686b,0x686c,0x686d,0x686e,0x686f,
+ 0x6870,0x6871,0x6872,0x6873,0x6874,0x6875,0x6876,0x6877,
+ 0x6878,0x6879,0x687a,0x687b,0x687c,0x687d,0x687e,0x687f,
+ 0x6880,0x6881,0x6882,0x6883,0x6884,0x6885,0x6886,0x6887,
+ 0x6888,0x6889,0x688a,0x688b,0x688c,0x688d,0x688e,0x688f,
+ 0x6890,0x6891,0x6892,0x6893,0x6894,0x6895,0x6896,0x6897,
+ 0x6898,0x6899,0x689a,0x689b,0x689c,0x689d,0x689e,0x689f,
+ 0x68a0,0x68a1,0x68a2,0x68a3,0x68a4,0x68a5,0x68a6,0x68a7,
+ 0x68a8,0x68a9,0x68aa,0x68ab,0x68ac,0x68ad,0x68ae,0x68af,
+ 0x68b0,0x68b1,0x68b2,0x68b3,0x68b4,0x68b5,0x68b6,0x68b7,
+ 0x68b8,0x68b9,0x68ba,0x68bb,0x68bc,0x68bd,0x68be,0x68bf,
+ 0x68c0,0x68c1,0x68c2,0x68c3,0x68c4,0x68c5,0x68c6,0x68c7,
+ 0x68c8,0x68c9,0x68ca,0x68cb,0x68cc,0x68cd,0x68ce,0x68cf,
+ 0x68d0,0x68d1,0x68d2,0x68d3,0x68d4,0x68d5,0x68d6,0x68d7,
+ 0x68d8,0x68d9,0x68da,0x68db,0x68dc,0x68dd,0x68de,0x68df,
+ 0x68e0,0x68e1,0x68e2,0x68e3,0x68e4,0x68e5,0x68e6,0x68e7,
+ 0x68e8,0x68e9,0x68ea,0x68eb,0x68ec,0x68ed,0x68ee,0x68ef,
+ 0x68f0,0x68f1,0x68f2,0x68f3,0x68f4,0x68f5,0x68f6,0x68f7,
+ 0x68f8,0x68f9,0x68fa,0x68fb,0x68fc,0x68fd,0x68fe,0x68ff,
+ 0x6900,0x6901,0x6902,0x6903,0x6904,0x6905,0x6906,0x6907,
+ 0x6908,0x6909,0x690a,0x690b,0x690c,0x690d,0x690e,0x690f,
+ 0x6910,0x6911,0x6912,0x6913,0x6914,0x6915,0x6916,0x6917,
+ 0x6918,0x6919,0x691a,0x691b,0x691c,0x691d,0x691e,0x691f,
+ 0x6920,0x6921,0x6922,0x6923,0x6924,0x6925,0x6926,0x6927,
+ 0x6928,0x6929,0x692a,0x692b,0x692c,0x692d,0x692e,0x692f,
+ 0x6930,0x6931,0x6932,0x6933,0x6934,0x6935,0x6936,0x6937,
+ 0x6938,0x6939,0x693a,0x693b,0x693c,0x693d,0x693e,0x693f,
+ 0x6940,0x6941,0x6942,0x6943,0x6944,0x6945,0x6946,0x6947,
+ 0x6948,0x6949,0x694a,0x694b,0x694c,0x694d,0x694e,0x694f,
+ 0x6950,0x6951,0x6952,0x6953,0x6954,0x6955,0x6956,0x6957,
+ 0x6958,0x6959,0x695a,0x695b,0x695c,0x695d,0x695e,0x695f,
+ 0x6960,0x6961,0x6962,0x6963,0x6964,0x6965,0x6966,0x6967,
+ 0x6968,0x6969,0x696a,0x696b,0x696c,0x696d,0x696e,0x696f,
+ 0x6970,0x6971,0x6972,0x6973,0x6974,0x6975,0x6976,0x6977,
+ 0x6978,0x6979,0x697a,0x697b,0x697c,0x697d,0x697e,0x697f,
+ 0x6980,0x6981,0x6982,0x6983,0x6984,0x6985,0x6986,0x6987,
+ 0x6988,0x6989,0x698a,0x698b,0x698c,0x698d,0x698e,0x698f,
+ 0x6990,0x6991,0x6992,0x6993,0x6994,0x6995,0x6996,0x6997,
+ 0x6998,0x6999,0x699a,0x699b,0x699c,0x699d,0x699e,0x699f,
+ 0x69a0,0x69a1,0x69a2,0x69a3,0x69a4,0x69a5,0x69a6,0x69a7,
+ 0x69a8,0x69a9,0x69aa,0x69ab,0x69ac,0x69ad,0x69ae,0x69af,
+ 0x69b0,0x69b1,0x69b2,0x69b3,0x69b4,0x69b5,0x69b6,0x69b7,
+ 0x69b8,0x69b9,0x69ba,0x69bb,0x69bc,0x69bd,0x69be,0x69bf,
+ 0x69c0,0x69c1,0x69c2,0x69c3,0x69c4,0x69c5,0x69c6,0x69c7,
+ 0x69c8,0x69c9,0x69ca,0x69cb,0x69cc,0x69cd,0x69ce,0x69cf,
+ 0x69d0,0x69d1,0x69d2,0x69d3,0x69d4,0x69d5,0x69d6,0x69d7,
+ 0x69d8,0x69d9,0x69da,0x69db,0x69dc,0x69dd,0x69de,0x69df,
+ 0x69e0,0x69e1,0x69e2,0x69e3,0x69e4,0x69e5,0x69e6,0x69e7,
+ 0x69e8,0x69e9,0x69ea,0x69eb,0x69ec,0x69ed,0x69ee,0x69ef,
+ 0x69f0,0x69f1,0x69f2,0x69f3,0x69f4,0x69f5,0x69f6,0x69f7,
+ 0x69f8,0x69f9,0x69fa,0x69fb,0x69fc,0x69fd,0x69fe,0x69ff,
+ 0x6a00,0x6a01,0x6a02,0x6a03,0x6a04,0x6a05,0x6a06,0x6a07,
+ 0x6a08,0x6a09,0x6a0a,0x6a0b,0x6a0c,0x6a0d,0x6a0e,0x6a0f,
+ 0x6a10,0x6a11,0x6a12,0x6a13,0x6a14,0x6a15,0x6a16,0x6a17,
+ 0x6a18,0x6a19,0x6a1a,0x6a1b,0x6a1c,0x6a1d,0x6a1e,0x6a1f,
+ 0x6a20,0x6a21,0x6a22,0x6a23,0x6a24,0x6a25,0x6a26,0x6a27,
+ 0x6a28,0x6a29,0x6a2a,0x6a2b,0x6a2c,0x6a2d,0x6a2e,0x6a2f,
+ 0x6a30,0x6a31,0x6a32,0x6a33,0x6a34,0x6a35,0x6a36,0x6a37,
+ 0x6a38,0x6a39,0x6a3a,0x6a3b,0x6a3c,0x6a3d,0x6a3e,0x6a3f,
+ 0x6a40,0x6a41,0x6a42,0x6a43,0x6a44,0x6a45,0x6a46,0x6a47,
+ 0x6a48,0x6a49,0x6a4a,0x6a4b,0x6a4c,0x6a4d,0x6a4e,0x6a4f,
+ 0x6a50,0x6a51,0x6a52,0x6a53,0x6a54,0x6a55,0x6a56,0x6a57,
+ 0x6a58,0x6a59,0x6a5a,0x6a5b,0x6a5c,0x6a5d,0x6a5e,0x6a5f,
+ 0x6a60,0x6a61,0x6a62,0x6a63,0x6a64,0x6a65,0x6a66,0x6a67,
+ 0x6a68,0x6a69,0x6a6a,0x6a6b,0x6a6c,0x6a6d,0x6a6e,0x6a6f,
+ 0x6a70,0x6a71,0x6a72,0x6a73,0x6a74,0x6a75,0x6a76,0x6a77,
+ 0x6a78,0x6a79,0x6a7a,0x6a7b,0x6a7c,0x6a7d,0x6a7e,0x6a7f,
+ 0x6a80,0x6a81,0x6a82,0x6a83,0x6a84,0x6a85,0x6a86,0x6a87,
+ 0x6a88,0x6a89,0x6a8a,0x6a8b,0x6a8c,0x6a8d,0x6a8e,0x6a8f,
+ 0x6a90,0x6a91,0x6a92,0x6a93,0x6a94,0x6a95,0x6a96,0x6a97,
+ 0x6a98,0x6a99,0x6a9a,0x6a9b,0x6a9c,0x6a9d,0x6a9e,0x6a9f,
+ 0x6aa0,0x6aa1,0x6aa2,0x6aa3,0x6aa4,0x6aa5,0x6aa6,0x6aa7,
+ 0x6aa8,0x6aa9,0x6aaa,0x6aab,0x6aac,0x6aad,0x6aae,0x6aaf,
+ 0x6ab0,0x6ab1,0x6ab2,0x6ab3,0x6ab4,0x6ab5,0x6ab6,0x6ab7,
+ 0x6ab8,0x6ab9,0x6aba,0x6abb,0x6abc,0x6abd,0x6abe,0x6abf,
+ 0x6ac0,0x6ac1,0x6ac2,0x6ac3,0x6ac4,0x6ac5,0x6ac6,0x6ac7,
+ 0x6ac8,0x6ac9,0x6aca,0x6acb,0x6acc,0x6acd,0x6ace,0x6acf,
+ 0x6ad0,0x6ad1,0x6ad2,0x6ad3,0x6ad4,0x6ad5,0x6ad6,0x6ad7,
+ 0x6ad8,0x6ad9,0x6ada,0x6adb,0x6adc,0x6add,0x6ade,0x6adf,
+ 0x6ae0,0x6ae1,0x6ae2,0x6ae3,0x6ae4,0x6ae5,0x6ae6,0x6ae7,
+ 0x6ae8,0x6ae9,0x6aea,0x6aeb,0x6aec,0x6aed,0x6aee,0x6aef,
+ 0x6af0,0x6af1,0x6af2,0x6af3,0x6af4,0x6af5,0x6af6,0x6af7,
+ 0x6af8,0x6af9,0x6afa,0x6afb,0x6afc,0x6afd,0x6afe,0x6aff,
+ 0x6b00,0x6b01,0x6b02,0x6b03,0x6b04,0x6b05,0x6b06,0x6b07,
+ 0x6b08,0x6b09,0x6b0a,0x6b0b,0x6b0c,0x6b0d,0x6b0e,0x6b0f,
+ 0x6b10,0x6b11,0x6b12,0x6b13,0x6b14,0x6b15,0x6b16,0x6b17,
+ 0x6b18,0x6b19,0x6b1a,0x6b1b,0x6b1c,0x6b1d,0x6b1e,0x6b1f,
+ 0x6b20,0x6b21,0x6b22,0x6b23,0x6b24,0x6b25,0x6b26,0x6b27,
+ 0x6b28,0x6b29,0x6b2a,0x6b2b,0x6b2c,0x6b2d,0x6b2e,0x6b2f,
+ 0x6b30,0x6b31,0x6b32,0x6b33,0x6b34,0x6b35,0x6b36,0x6b37,
+ 0x6b38,0x6b39,0x6b3a,0x6b3b,0x6b3c,0x6b3d,0x6b3e,0x6b3f,
+ 0x6b40,0x6b41,0x6b42,0x6b43,0x6b44,0x6b45,0x6b46,0x6b47,
+ 0x6b48,0x6b49,0x6b4a,0x6b4b,0x6b4c,0x6b4d,0x6b4e,0x6b4f,
+ 0x6b50,0x6b51,0x6b52,0x6b53,0x6b54,0x6b55,0x6b56,0x6b57,
+ 0x6b58,0x6b59,0x6b5a,0x6b5b,0x6b5c,0x6b5d,0x6b5e,0x6b5f,
+ 0x6b60,0x6b61,0x6b62,0x6b63,0x6b64,0x6b65,0x6b66,0x6b67,
+ 0x6b68,0x6b69,0x6b6a,0x6b6b,0x6b6c,0x6b6d,0x6b6e,0x6b6f,
+ 0x6b70,0x6b71,0x6b72,0x6b73,0x6b74,0x6b75,0x6b76,0x6b77,
+ 0x6b78,0x6b79,0x6b7a,0x6b7b,0x6b7c,0x6b7d,0x6b7e,0x6b7f,
+ 0x6b80,0x6b81,0x6b82,0x6b83,0x6b84,0x6b85,0x6b86,0x6b87,
+ 0x6b88,0x6b89,0x6b8a,0x6b8b,0x6b8c,0x6b8d,0x6b8e,0x6b8f,
+ 0x6b90,0x6b91,0x6b92,0x6b93,0x6b94,0x6b95,0x6b96,0x6b97,
+ 0x6b98,0x6b99,0x6b9a,0x6b9b,0x6b9c,0x6b9d,0x6b9e,0x6b9f,
+ 0x6ba0,0x6ba1,0x6ba2,0x6ba3,0x6ba4,0x6ba5,0x6ba6,0x6ba7,
+ 0x6ba8,0x6ba9,0x6baa,0x6bab,0x6bac,0x6bad,0x6bae,0x6baf,
+ 0x6bb0,0x6bb1,0x6bb2,0x6bb3,0x6bb4,0x6bb5,0x6bb6,0x6bb7,
+ 0x6bb8,0x6bb9,0x6bba,0x6bbb,0x6bbc,0x6bbd,0x6bbe,0x6bbf,
+ 0x6bc0,0x6bc1,0x6bc2,0x6bc3,0x6bc4,0x6bc5,0x6bc6,0x6bc7,
+ 0x6bc8,0x6bc9,0x6bca,0x6bcb,0x6bcc,0x6bcd,0x6bce,0x6bcf,
+ 0x6bd0,0x6bd1,0x6bd2,0x6bd3,0x6bd4,0x6bd5,0x6bd6,0x6bd7,
+ 0x6bd8,0x6bd9,0x6bda,0x6bdb,0x6bdc,0x6bdd,0x6bde,0x6bdf,
+ 0x6be0,0x6be1,0x6be2,0x6be3,0x6be4,0x6be5,0x6be6,0x6be7,
+ 0x6be8,0x6be9,0x6bea,0x6beb,0x6bec,0x6bed,0x6bee,0x6bef,
+ 0x6bf0,0x6bf1,0x6bf2,0x6bf3,0x6bf4,0x6bf5,0x6bf6,0x6bf7,
+ 0x6bf8,0x6bf9,0x6bfa,0x6bfb,0x6bfc,0x6bfd,0x6bfe,0x6bff,
+ 0x6c00,0x6c01,0x6c02,0x6c03,0x6c04,0x6c05,0x6c06,0x6c07,
+ 0x6c08,0x6c09,0x6c0a,0x6c0b,0x6c0c,0x6c0d,0x6c0e,0x6c0f,
+ 0x6c10,0x6c11,0x6c12,0x6c13,0x6c14,0x6c15,0x6c16,0x6c17,
+ 0x6c18,0x6c19,0x6c1a,0x6c1b,0x6c1c,0x6c1d,0x6c1e,0x6c1f,
+ 0x6c20,0x6c21,0x6c22,0x6c23,0x6c24,0x6c25,0x6c26,0x6c27,
+ 0x6c28,0x6c29,0x6c2a,0x6c2b,0x6c2c,0x6c2d,0x6c2e,0x6c2f,
+ 0x6c30,0x6c31,0x6c32,0x6c33,0x6c34,0x6c35,0x6c36,0x6c37,
+ 0x6c38,0x6c39,0x6c3a,0x6c3b,0x6c3c,0x6c3d,0x6c3e,0x6c3f,
+ 0x6c40,0x6c41,0x6c42,0x6c43,0x6c44,0x6c45,0x6c46,0x6c47,
+ 0x6c48,0x6c49,0x6c4a,0x6c4b,0x6c4c,0x6c4d,0x6c4e,0x6c4f,
+ 0x6c50,0x6c51,0x6c52,0x6c53,0x6c54,0x6c55,0x6c56,0x6c57,
+ 0x6c58,0x6c59,0x6c5a,0x6c5b,0x6c5c,0x6c5d,0x6c5e,0x6c5f,
+ 0x6c60,0x6c61,0x6c62,0x6c63,0x6c64,0x6c65,0x6c66,0x6c67,
+ 0x6c68,0x6c69,0x6c6a,0x6c6b,0x6c6c,0x6c6d,0x6c6e,0x6c6f,
+ 0x6c70,0x6c71,0x6c72,0x6c73,0x6c74,0x6c75,0x6c76,0x6c77,
+ 0x6c78,0x6c79,0x6c7a,0x6c7b,0x6c7c,0x6c7d,0x6c7e,0x6c7f,
+ 0x6c80,0x6c81,0x6c82,0x6c83,0x6c84,0x6c85,0x6c86,0x6c87,
+ 0x6c88,0x6c89,0x6c8a,0x6c8b,0x6c8c,0x6c8d,0x6c8e,0x6c8f,
+ 0x6c90,0x6c91,0x6c92,0x6c93,0x6c94,0x6c95,0x6c96,0x6c97,
+ 0x6c98,0x6c99,0x6c9a,0x6c9b,0x6c9c,0x6c9d,0x6c9e,0x6c9f,
+ 0x6ca0,0x6ca1,0x6ca2,0x6ca3,0x6ca4,0x6ca5,0x6ca6,0x6ca7,
+ 0x6ca8,0x6ca9,0x6caa,0x6cab,0x6cac,0x6cad,0x6cae,0x6caf,
+ 0x6cb0,0x6cb1,0x6cb2,0x6cb3,0x6cb4,0x6cb5,0x6cb6,0x6cb7,
+ 0x6cb8,0x6cb9,0x6cba,0x6cbb,0x6cbc,0x6cbd,0x6cbe,0x6cbf,
+ 0x6cc0,0x6cc1,0x6cc2,0x6cc3,0x6cc4,0x6cc5,0x6cc6,0x6cc7,
+ 0x6cc8,0x6cc9,0x6cca,0x6ccb,0x6ccc,0x6ccd,0x6cce,0x6ccf,
+ 0x6cd0,0x6cd1,0x6cd2,0x6cd3,0x6cd4,0x6cd5,0x6cd6,0x6cd7,
+ 0x6cd8,0x6cd9,0x6cda,0x6cdb,0x6cdc,0x6cdd,0x6cde,0x6cdf,
+ 0x6ce0,0x6ce1,0x6ce2,0x6ce3,0x6ce4,0x6ce5,0x6ce6,0x6ce7,
+ 0x6ce8,0x6ce9,0x6cea,0x6ceb,0x6cec,0x6ced,0x6cee,0x6cef,
+ 0x6cf0,0x6cf1,0x6cf2,0x6cf3,0x6cf4,0x6cf5,0x6cf6,0x6cf7,
+ 0x6cf8,0x6cf9,0x6cfa,0x6cfb,0x6cfc,0x6cfd,0x6cfe,0x6cff,
+ 0x6d00,0x6d01,0x6d02,0x6d03,0x6d04,0x6d05,0x6d06,0x6d07,
+ 0x6d08,0x6d09,0x6d0a,0x6d0b,0x6d0c,0x6d0d,0x6d0e,0x6d0f,
+ 0x6d10,0x6d11,0x6d12,0x6d13,0x6d14,0x6d15,0x6d16,0x6d17,
+ 0x6d18,0x6d19,0x6d1a,0x6d1b,0x6d1c,0x6d1d,0x6d1e,0x6d1f,
+ 0x6d20,0x6d21,0x6d22,0x6d23,0x6d24,0x6d25,0x6d26,0x6d27,
+ 0x6d28,0x6d29,0x6d2a,0x6d2b,0x6d2c,0x6d2d,0x6d2e,0x6d2f,
+ 0x6d30,0x6d31,0x6d32,0x6d33,0x6d34,0x6d35,0x6d36,0x6d37,
+ 0x6d38,0x6d39,0x6d3a,0x6d3b,0x6d3c,0x6d3d,0x6d3e,0x6d3f,
+ 0x6d40,0x6d41,0x6d42,0x6d43,0x6d44,0x6d45,0x6d46,0x6d47,
+ 0x6d48,0x6d49,0x6d4a,0x6d4b,0x6d4c,0x6d4d,0x6d4e,0x6d4f,
+ 0x6d50,0x6d51,0x6d52,0x6d53,0x6d54,0x6d55,0x6d56,0x6d57,
+ 0x6d58,0x6d59,0x6d5a,0x6d5b,0x6d5c,0x6d5d,0x6d5e,0x6d5f,
+ 0x6d60,0x6d61,0x6d62,0x6d63,0x6d64,0x6d65,0x6d66,0x6d67,
+ 0x6d68,0x6d69,0x6d6a,0x6d6b,0x6d6c,0x6d6d,0x6d6e,0x6d6f,
+ 0x6d70,0x6d71,0x6d72,0x6d73,0x6d74,0x6d75,0x6d76,0x6d77,
+ 0x6d78,0x6d79,0x6d7a,0x6d7b,0x6d7c,0x6d7d,0x6d7e,0x6d7f,
+ 0x6d80,0x6d81,0x6d82,0x6d83,0x6d84,0x6d85,0x6d86,0x6d87,
+ 0x6d88,0x6d89,0x6d8a,0x6d8b,0x6d8c,0x6d8d,0x6d8e,0x6d8f,
+ 0x6d90,0x6d91,0x6d92,0x6d93,0x6d94,0x6d95,0x6d96,0x6d97,
+ 0x6d98,0x6d99,0x6d9a,0x6d9b,0x6d9c,0x6d9d,0x6d9e,0x6d9f,
+ 0x6da0,0x6da1,0x6da2,0x6da3,0x6da4,0x6da5,0x6da6,0x6da7,
+ 0x6da8,0x6da9,0x6daa,0x6dab,0x6dac,0x6dad,0x6dae,0x6daf,
+ 0x6db0,0x6db1,0x6db2,0x6db3,0x6db4,0x6db5,0x6db6,0x6db7,
+ 0x6db8,0x6db9,0x6dba,0x6dbb,0x6dbc,0x6dbd,0x6dbe,0x6dbf,
+ 0x6dc0,0x6dc1,0x6dc2,0x6dc3,0x6dc4,0x6dc5,0x6dc6,0x6dc7,
+ 0x6dc8,0x6dc9,0x6dca,0x6dcb,0x6dcc,0x6dcd,0x6dce,0x6dcf,
+ 0x6dd0,0x6dd1,0x6dd2,0x6dd3,0x6dd4,0x6dd5,0x6dd6,0x6dd7,
+ 0x6dd8,0x6dd9,0x6dda,0x6ddb,0x6ddc,0x6ddd,0x6dde,0x6ddf,
+ 0x6de0,0x6de1,0x6de2,0x6de3,0x6de4,0x6de5,0x6de6,0x6de7,
+ 0x6de8,0x6de9,0x6dea,0x6deb,0x6dec,0x6ded,0x6dee,0x6def,
+ 0x6df0,0x6df1,0x6df2,0x6df3,0x6df4,0x6df5,0x6df6,0x6df7,
+ 0x6df8,0x6df9,0x6dfa,0x6dfb,0x6dfc,0x6dfd,0x6dfe,0x6dff,
+ 0x6e00,0x6e01,0x6e02,0x6e03,0x6e04,0x6e05,0x6e06,0x6e07,
+ 0x6e08,0x6e09,0x6e0a,0x6e0b,0x6e0c,0x6e0d,0x6e0e,0x6e0f,
+ 0x6e10,0x6e11,0x6e12,0x6e13,0x6e14,0x6e15,0x6e16,0x6e17,
+ 0x6e18,0x6e19,0x6e1a,0x6e1b,0x6e1c,0x6e1d,0x6e1e,0x6e1f,
+ 0x6e20,0x6e21,0x6e22,0x6e23,0x6e24,0x6e25,0x6e26,0x6e27,
+ 0x6e28,0x6e29,0x6e2a,0x6e2b,0x6e2c,0x6e2d,0x6e2e,0x6e2f,
+ 0x6e30,0x6e31,0x6e32,0x6e33,0x6e34,0x6e35,0x6e36,0x6e37,
+ 0x6e38,0x6e39,0x6e3a,0x6e3b,0x6e3c,0x6e3d,0x6e3e,0x6e3f,
+ 0x6e40,0x6e41,0x6e42,0x6e43,0x6e44,0x6e45,0x6e46,0x6e47,
+ 0x6e48,0x6e49,0x6e4a,0x6e4b,0x6e4c,0x6e4d,0x6e4e,0x6e4f,
+ 0x6e50,0x6e51,0x6e52,0x6e53,0x6e54,0x6e55,0x6e56,0x6e57,
+ 0x6e58,0x6e59,0x6e5a,0x6e5b,0x6e5c,0x6e5d,0x6e5e,0x6e5f,
+ 0x6e60,0x6e61,0x6e62,0x6e63,0x6e64,0x6e65,0x6e66,0x6e67,
+ 0x6e68,0x6e69,0x6e6a,0x6e6b,0x6e6c,0x6e6d,0x6e6e,0x6e6f,
+ 0x6e70,0x6e71,0x6e72,0x6e73,0x6e74,0x6e75,0x6e76,0x6e77,
+ 0x6e78,0x6e79,0x6e7a,0x6e7b,0x6e7c,0x6e7d,0x6e7e,0x6e7f,
+ 0x6e80,0x6e81,0x6e82,0x6e83,0x6e84,0x6e85,0x6e86,0x6e87,
+ 0x6e88,0x6e89,0x6e8a,0x6e8b,0x6e8c,0x6e8d,0x6e8e,0x6e8f,
+ 0x6e90,0x6e91,0x6e92,0x6e93,0x6e94,0x6e95,0x6e96,0x6e97,
+ 0x6e98,0x6e99,0x6e9a,0x6e9b,0x6e9c,0x6e9d,0x6e9e,0x6e9f,
+ 0x6ea0,0x6ea1,0x6ea2,0x6ea3,0x6ea4,0x6ea5,0x6ea6,0x6ea7,
+ 0x6ea8,0x6ea9,0x6eaa,0x6eab,0x6eac,0x6ead,0x6eae,0x6eaf,
+ 0x6eb0,0x6eb1,0x6eb2,0x6eb3,0x6eb4,0x6eb5,0x6eb6,0x6eb7,
+ 0x6eb8,0x6eb9,0x6eba,0x6ebb,0x6ebc,0x6ebd,0x6ebe,0x6ebf,
+ 0x6ec0,0x6ec1,0x6ec2,0x6ec3,0x6ec4,0x6ec5,0x6ec6,0x6ec7,
+ 0x6ec8,0x6ec9,0x6eca,0x6ecb,0x6ecc,0x6ecd,0x6ece,0x6ecf,
+ 0x6ed0,0x6ed1,0x6ed2,0x6ed3,0x6ed4,0x6ed5,0x6ed6,0x6ed7,
+ 0x6ed8,0x6ed9,0x6eda,0x6edb,0x6edc,0x6edd,0x6ede,0x6edf,
+ 0x6ee0,0x6ee1,0x6ee2,0x6ee3,0x6ee4,0x6ee5,0x6ee6,0x6ee7,
+ 0x6ee8,0x6ee9,0x6eea,0x6eeb,0x6eec,0x6eed,0x6eee,0x6eef,
+ 0x6ef0,0x6ef1,0x6ef2,0x6ef3,0x6ef4,0x6ef5,0x6ef6,0x6ef7,
+ 0x6ef8,0x6ef9,0x6efa,0x6efb,0x6efc,0x6efd,0x6efe,0x6eff,
+ 0x6f00,0x6f01,0x6f02,0x6f03,0x6f04,0x6f05,0x6f06,0x6f07,
+ 0x6f08,0x6f09,0x6f0a,0x6f0b,0x6f0c,0x6f0d,0x6f0e,0x6f0f,
+ 0x6f10,0x6f11,0x6f12,0x6f13,0x6f14,0x6f15,0x6f16,0x6f17,
+ 0x6f18,0x6f19,0x6f1a,0x6f1b,0x6f1c,0x6f1d,0x6f1e,0x6f1f,
+ 0x6f20,0x6f21,0x6f22,0x6f23,0x6f24,0x6f25,0x6f26,0x6f27,
+ 0x6f28,0x6f29,0x6f2a,0x6f2b,0x6f2c,0x6f2d,0x6f2e,0x6f2f,
+ 0x6f30,0x6f31,0x6f32,0x6f33,0x6f34,0x6f35,0x6f36,0x6f37,
+ 0x6f38,0x6f39,0x6f3a,0x6f3b,0x6f3c,0x6f3d,0x6f3e,0x6f3f,
+ 0x6f40,0x6f41,0x6f42,0x6f43,0x6f44,0x6f45,0x6f46,0x6f47,
+ 0x6f48,0x6f49,0x6f4a,0x6f4b,0x6f4c,0x6f4d,0x6f4e,0x6f4f,
+ 0x6f50,0x6f51,0x6f52,0x6f53,0x6f54,0x6f55,0x6f56,0x6f57,
+ 0x6f58,0x6f59,0x6f5a,0x6f5b,0x6f5c,0x6f5d,0x6f5e,0x6f5f,
+ 0x6f60,0x6f61,0x6f62,0x6f63,0x6f64,0x6f65,0x6f66,0x6f67,
+ 0x6f68,0x6f69,0x6f6a,0x6f6b,0x6f6c,0x6f6d,0x6f6e,0x6f6f,
+ 0x6f70,0x6f71,0x6f72,0x6f73,0x6f74,0x6f75,0x6f76,0x6f77,
+ 0x6f78,0x6f79,0x6f7a,0x6f7b,0x6f7c,0x6f7d,0x6f7e,0x6f7f,
+ 0x6f80,0x6f81,0x6f82,0x6f83,0x6f84,0x6f85,0x6f86,0x6f87,
+ 0x6f88,0x6f89,0x6f8a,0x6f8b,0x6f8c,0x6f8d,0x6f8e,0x6f8f,
+ 0x6f90,0x6f91,0x6f92,0x6f93,0x6f94,0x6f95,0x6f96,0x6f97,
+ 0x6f98,0x6f99,0x6f9a,0x6f9b,0x6f9c,0x6f9d,0x6f9e,0x6f9f,
+ 0x6fa0,0x6fa1,0x6fa2,0x6fa3,0x6fa4,0x6fa5,0x6fa6,0x6fa7,
+ 0x6fa8,0x6fa9,0x6faa,0x6fab,0x6fac,0x6fad,0x6fae,0x6faf,
+ 0x6fb0,0x6fb1,0x6fb2,0x6fb3,0x6fb4,0x6fb5,0x6fb6,0x6fb7,
+ 0x6fb8,0x6fb9,0x6fba,0x6fbb,0x6fbc,0x6fbd,0x6fbe,0x6fbf,
+ 0x6fc0,0x6fc1,0x6fc2,0x6fc3,0x6fc4,0x6fc5,0x6fc6,0x6fc7,
+ 0x6fc8,0x6fc9,0x6fca,0x6fcb,0x6fcc,0x6fcd,0x6fce,0x6fcf,
+ 0x6fd0,0x6fd1,0x6fd2,0x6fd3,0x6fd4,0x6fd5,0x6fd6,0x6fd7,
+ 0x6fd8,0x6fd9,0x6fda,0x6fdb,0x6fdc,0x6fdd,0x6fde,0x6fdf,
+ 0x6fe0,0x6fe1,0x6fe2,0x6fe3,0x6fe4,0x6fe5,0x6fe6,0x6fe7,
+ 0x6fe8,0x6fe9,0x6fea,0x6feb,0x6fec,0x6fed,0x6fee,0x6fef,
+ 0x6ff0,0x6ff1,0x6ff2,0x6ff3,0x6ff4,0x6ff5,0x6ff6,0x6ff7,
+ 0x6ff8,0x6ff9,0x6ffa,0x6ffb,0x6ffc,0x6ffd,0x6ffe,0x6fff,
+ 0x7000,0x7001,0x7002,0x7003,0x7004,0x7005,0x7006,0x7007,
+ 0x7008,0x7009,0x700a,0x700b,0x700c,0x700d,0x700e,0x700f,
+ 0x7010,0x7011,0x7012,0x7013,0x7014,0x7015,0x7016,0x7017,
+ 0x7018,0x7019,0x701a,0x701b,0x701c,0x701d,0x701e,0x701f,
+ 0x7020,0x7021,0x7022,0x7023,0x7024,0x7025,0x7026,0x7027,
+ 0x7028,0x7029,0x702a,0x702b,0x702c,0x702d,0x702e,0x702f,
+ 0x7030,0x7031,0x7032,0x7033,0x7034,0x7035,0x7036,0x7037,
+ 0x7038,0x7039,0x703a,0x703b,0x703c,0x703d,0x703e,0x703f,
+ 0x7040,0x7041,0x7042,0x7043,0x7044,0x7045,0x7046,0x7047,
+ 0x7048,0x7049,0x704a,0x704b,0x704c,0x704d,0x704e,0x704f,
+ 0x7050,0x7051,0x7052,0x7053,0x7054,0x7055,0x7056,0x7057,
+ 0x7058,0x7059,0x705a,0x705b,0x705c,0x705d,0x705e,0x705f,
+ 0x7060,0x7061,0x7062,0x7063,0x7064,0x7065,0x7066,0x7067,
+ 0x7068,0x7069,0x706a,0x706b,0x706c,0x706d,0x706e,0x706f,
+ 0x7070,0x7071,0x7072,0x7073,0x7074,0x7075,0x7076,0x7077,
+ 0x7078,0x7079,0x707a,0x707b,0x707c,0x707d,0x707e,0x707f,
+ 0x7080,0x7081,0x7082,0x7083,0x7084,0x7085,0x7086,0x7087,
+ 0x7088,0x7089,0x708a,0x708b,0x708c,0x708d,0x708e,0x708f,
+ 0x7090,0x7091,0x7092,0x7093,0x7094,0x7095,0x7096,0x7097,
+ 0x7098,0x7099,0x709a,0x709b,0x709c,0x709d,0x709e,0x709f,
+ 0x70a0,0x70a1,0x70a2,0x70a3,0x70a4,0x70a5,0x70a6,0x70a7,
+ 0x70a8,0x70a9,0x70aa,0x70ab,0x70ac,0x70ad,0x70ae,0x70af,
+ 0x70b0,0x70b1,0x70b2,0x70b3,0x70b4,0x70b5,0x70b6,0x70b7,
+ 0x70b8,0x70b9,0x70ba,0x70bb,0x70bc,0x70bd,0x70be,0x70bf,
+ 0x70c0,0x70c1,0x70c2,0x70c3,0x70c4,0x70c5,0x70c6,0x70c7,
+ 0x70c8,0x70c9,0x70ca,0x70cb,0x70cc,0x70cd,0x70ce,0x70cf,
+ 0x70d0,0x70d1,0x70d2,0x70d3,0x70d4,0x70d5,0x70d6,0x70d7,
+ 0x70d8,0x70d9,0x70da,0x70db,0x70dc,0x70dd,0x70de,0x70df,
+ 0x70e0,0x70e1,0x70e2,0x70e3,0x70e4,0x70e5,0x70e6,0x70e7,
+ 0x70e8,0x70e9,0x70ea,0x70eb,0x70ec,0x70ed,0x70ee,0x70ef,
+ 0x70f0,0x70f1,0x70f2,0x70f3,0x70f4,0x70f5,0x70f6,0x70f7,
+ 0x70f8,0x70f9,0x70fa,0x70fb,0x70fc,0x70fd,0x70fe,0x70ff,
+ 0x7100,0x7101,0x7102,0x7103,0x7104,0x7105,0x7106,0x7107,
+ 0x7108,0x7109,0x710a,0x710b,0x710c,0x710d,0x710e,0x710f,
+ 0x7110,0x7111,0x7112,0x7113,0x7114,0x7115,0x7116,0x7117,
+ 0x7118,0x7119,0x711a,0x711b,0x711c,0x711d,0x711e,0x711f,
+ 0x7120,0x7121,0x7122,0x7123,0x7124,0x7125,0x7126,0x7127,
+ 0x7128,0x7129,0x712a,0x712b,0x712c,0x712d,0x712e,0x712f,
+ 0x7130,0x7131,0x7132,0x7133,0x7134,0x7135,0x7136,0x7137,
+ 0x7138,0x7139,0x713a,0x713b,0x713c,0x713d,0x713e,0x713f,
+ 0x7140,0x7141,0x7142,0x7143,0x7144,0x7145,0x7146,0x7147,
+ 0x7148,0x7149,0x714a,0x714b,0x714c,0x714d,0x714e,0x714f,
+ 0x7150,0x7151,0x7152,0x7153,0x7154,0x7155,0x7156,0x7157,
+ 0x7158,0x7159,0x715a,0x715b,0x715c,0x715d,0x715e,0x715f,
+ 0x7160,0x7161,0x7162,0x7163,0x7164,0x7165,0x7166,0x7167,
+ 0x7168,0x7169,0x716a,0x716b,0x716c,0x716d,0x716e,0x716f,
+ 0x7170,0x7171,0x7172,0x7173,0x7174,0x7175,0x7176,0x7177,
+ 0x7178,0x7179,0x717a,0x717b,0x717c,0x717d,0x717e,0x717f,
+ 0x7180,0x7181,0x7182,0x7183,0x7184,0x7185,0x7186,0x7187,
+ 0x7188,0x7189,0x718a,0x718b,0x718c,0x718d,0x718e,0x718f,
+ 0x7190,0x7191,0x7192,0x7193,0x7194,0x7195,0x7196,0x7197,
+ 0x7198,0x7199,0x719a,0x719b,0x719c,0x719d,0x719e,0x719f,
+ 0x71a0,0x71a1,0x71a2,0x71a3,0x71a4,0x71a5,0x71a6,0x71a7,
+ 0x71a8,0x71a9,0x71aa,0x71ab,0x71ac,0x71ad,0x71ae,0x71af,
+ 0x71b0,0x71b1,0x71b2,0x71b3,0x71b4,0x71b5,0x71b6,0x71b7,
+ 0x71b8,0x71b9,0x71ba,0x71bb,0x71bc,0x71bd,0x71be,0x71bf,
+ 0x71c0,0x71c1,0x71c2,0x71c3,0x71c4,0x71c5,0x71c6,0x71c7,
+ 0x71c8,0x71c9,0x71ca,0x71cb,0x71cc,0x71cd,0x71ce,0x71cf,
+ 0x71d0,0x71d1,0x71d2,0x71d3,0x71d4,0x71d5,0x71d6,0x71d7,
+ 0x71d8,0x71d9,0x71da,0x71db,0x71dc,0x71dd,0x71de,0x71df,
+ 0x71e0,0x71e1,0x71e2,0x71e3,0x71e4,0x71e5,0x71e6,0x71e7,
+ 0x71e8,0x71e9,0x71ea,0x71eb,0x71ec,0x71ed,0x71ee,0x71ef,
+ 0x71f0,0x71f1,0x71f2,0x71f3,0x71f4,0x71f5,0x71f6,0x71f7,
+ 0x71f8,0x71f9,0x71fa,0x71fb,0x71fc,0x71fd,0x71fe,0x71ff,
+ 0x7200,0x7201,0x7202,0x7203,0x7204,0x7205,0x7206,0x7207,
+ 0x7208,0x7209,0x720a,0x720b,0x720c,0x720d,0x720e,0x720f,
+ 0x7210,0x7211,0x7212,0x7213,0x7214,0x7215,0x7216,0x7217,
+ 0x7218,0x7219,0x721a,0x721b,0x721c,0x721d,0x721e,0x721f,
+ 0x7220,0x7221,0x7222,0x7223,0x7224,0x7225,0x7226,0x7227,
+ 0x7228,0x7229,0x722a,0x722b,0x722c,0x722d,0x722e,0x722f,
+ 0x7230,0x7231,0x7232,0x7233,0x7234,0x7235,0x7236,0x7237,
+ 0x7238,0x7239,0x723a,0x723b,0x723c,0x723d,0x723e,0x723f,
+ 0x7240,0x7241,0x7242,0x7243,0x7244,0x7245,0x7246,0x7247,
+ 0x7248,0x7249,0x724a,0x724b,0x724c,0x724d,0x724e,0x724f,
+ 0x7250,0x7251,0x7252,0x7253,0x7254,0x7255,0x7256,0x7257,
+ 0x7258,0x7259,0x725a,0x725b,0x725c,0x725d,0x725e,0x725f,
+ 0x7260,0x7261,0x7262,0x7263,0x7264,0x7265,0x7266,0x7267,
+ 0x7268,0x7269,0x726a,0x726b,0x726c,0x726d,0x726e,0x726f,
+ 0x7270,0x7271,0x7272,0x7273,0x7274,0x7275,0x7276,0x7277,
+ 0x7278,0x7279,0x727a,0x727b,0x727c,0x727d,0x727e,0x727f,
+ 0x7280,0x7281,0x7282,0x7283,0x7284,0x7285,0x7286,0x7287,
+ 0x7288,0x7289,0x728a,0x728b,0x728c,0x728d,0x728e,0x728f,
+ 0x7290,0x7291,0x7292,0x7293,0x7294,0x7295,0x7296,0x7297,
+ 0x7298,0x7299,0x729a,0x729b,0x729c,0x729d,0x729e,0x729f,
+ 0x72a0,0x72a1,0x72a2,0x72a3,0x72a4,0x72a5,0x72a6,0x72a7,
+ 0x72a8,0x72a9,0x72aa,0x72ab,0x72ac,0x72ad,0x72ae,0x72af,
+ 0x72b0,0x72b1,0x72b2,0x72b3,0x72b4,0x72b5,0x72b6,0x72b7,
+ 0x72b8,0x72b9,0x72ba,0x72bb,0x72bc,0x72bd,0x72be,0x72bf,
+ 0x72c0,0x72c1,0x72c2,0x72c3,0x72c4,0x72c5,0x72c6,0x72c7,
+ 0x72c8,0x72c9,0x72ca,0x72cb,0x72cc,0x72cd,0x72ce,0x72cf,
+ 0x72d0,0x72d1,0x72d2,0x72d3,0x72d4,0x72d5,0x72d6,0x72d7,
+ 0x72d8,0x72d9,0x72da,0x72db,0x72dc,0x72dd,0x72de,0x72df,
+ 0x72e0,0x72e1,0x72e2,0x72e3,0x72e4,0x72e5,0x72e6,0x72e7,
+ 0x72e8,0x72e9,0x72ea,0x72eb,0x72ec,0x72ed,0x72ee,0x72ef,
+ 0x72f0,0x72f1,0x72f2,0x72f3,0x72f4,0x72f5,0x72f6,0x72f7,
+ 0x72f8,0x72f9,0x72fa,0x72fb,0x72fc,0x72fd,0x72fe,0x72ff,
+ 0x7300,0x7301,0x7302,0x7303,0x7304,0x7305,0x7306,0x7307,
+ 0x7308,0x7309,0x730a,0x730b,0x730c,0x730d,0x730e,0x730f,
+ 0x7310,0x7311,0x7312,0x7313,0x7314,0x7315,0x7316,0x7317,
+ 0x7318,0x7319,0x731a,0x731b,0x731c,0x731d,0x731e,0x731f,
+ 0x7320,0x7321,0x7322,0x7323,0x7324,0x7325,0x7326,0x7327,
+ 0x7328,0x7329,0x732a,0x732b,0x732c,0x732d,0x732e,0x732f,
+ 0x7330,0x7331,0x7332,0x7333,0x7334,0x7335,0x7336,0x7337,
+ 0x7338,0x7339,0x733a,0x733b,0x733c,0x733d,0x733e,0x733f,
+ 0x7340,0x7341,0x7342,0x7343,0x7344,0x7345,0x7346,0x7347,
+ 0x7348,0x7349,0x734a,0x734b,0x734c,0x734d,0x734e,0x734f,
+ 0x7350,0x7351,0x7352,0x7353,0x7354,0x7355,0x7356,0x7357,
+ 0x7358,0x7359,0x735a,0x735b,0x735c,0x735d,0x735e,0x735f,
+ 0x7360,0x7361,0x7362,0x7363,0x7364,0x7365,0x7366,0x7367,
+ 0x7368,0x7369,0x736a,0x736b,0x736c,0x736d,0x736e,0x736f,
+ 0x7370,0x7371,0x7372,0x7373,0x7374,0x7375,0x7376,0x7377,
+ 0x7378,0x7379,0x737a,0x737b,0x737c,0x737d,0x737e,0x737f,
+ 0x7380,0x7381,0x7382,0x7383,0x7384,0x7385,0x7386,0x7387,
+ 0x7388,0x7389,0x738a,0x738b,0x738c,0x738d,0x738e,0x738f,
+ 0x7390,0x7391,0x7392,0x7393,0x7394,0x7395,0x7396,0x7397,
+ 0x7398,0x7399,0x739a,0x739b,0x739c,0x739d,0x739e,0x739f,
+ 0x73a0,0x73a1,0x73a2,0x73a3,0x73a4,0x73a5,0x73a6,0x73a7,
+ 0x73a8,0x73a9,0x73aa,0x73ab,0x73ac,0x73ad,0x73ae,0x73af,
+ 0x73b0,0x73b1,0x73b2,0x73b3,0x73b4,0x73b5,0x73b6,0x73b7,
+ 0x73b8,0x73b9,0x73ba,0x73bb,0x73bc,0x73bd,0x73be,0x73bf,
+ 0x73c0,0x73c1,0x73c2,0x73c3,0x73c4,0x73c5,0x73c6,0x73c7,
+ 0x73c8,0x73c9,0x73ca,0x73cb,0x73cc,0x73cd,0x73ce,0x73cf,
+ 0x73d0,0x73d1,0x73d2,0x73d3,0x73d4,0x73d5,0x73d6,0x73d7,
+ 0x73d8,0x73d9,0x73da,0x73db,0x73dc,0x73dd,0x73de,0x73df,
+ 0x73e0,0x73e1,0x73e2,0x73e3,0x73e4,0x73e5,0x73e6,0x73e7,
+ 0x73e8,0x73e9,0x73ea,0x73eb,0x73ec,0x73ed,0x73ee,0x73ef,
+ 0x73f0,0x73f1,0x73f2,0x73f3,0x73f4,0x73f5,0x73f6,0x73f7,
+ 0x73f8,0x73f9,0x73fa,0x73fb,0x73fc,0x73fd,0x73fe,0x73ff,
+ 0x7400,0x7401,0x7402,0x7403,0x7404,0x7405,0x7406,0x7407,
+ 0x7408,0x7409,0x740a,0x740b,0x740c,0x740d,0x740e,0x740f,
+ 0x7410,0x7411,0x7412,0x7413,0x7414,0x7415,0x7416,0x7417,
+ 0x7418,0x7419,0x741a,0x741b,0x741c,0x741d,0x741e,0x741f,
+ 0x7420,0x7421,0x7422,0x7423,0x7424,0x7425,0x7426,0x7427,
+ 0x7428,0x7429,0x742a,0x742b,0x742c,0x742d,0x742e,0x742f,
+ 0x7430,0x7431,0x7432,0x7433,0x7434,0x7435,0x7436,0x7437,
+ 0x7438,0x7439,0x743a,0x743b,0x743c,0x743d,0x743e,0x743f,
+ 0x7440,0x7441,0x7442,0x7443,0x7444,0x7445,0x7446,0x7447,
+ 0x7448,0x7449,0x744a,0x744b,0x744c,0x744d,0x744e,0x744f,
+ 0x7450,0x7451,0x7452,0x7453,0x7454,0x7455,0x7456,0x7457,
+ 0x7458,0x7459,0x745a,0x745b,0x745c,0x745d,0x745e,0x745f,
+ 0x7460,0x7461,0x7462,0x7463,0x7464,0x7465,0x7466,0x7467,
+ 0x7468,0x7469,0x746a,0x746b,0x746c,0x746d,0x746e,0x746f,
+ 0x7470,0x7471,0x7472,0x7473,0x7474,0x7475,0x7476,0x7477,
+ 0x7478,0x7479,0x747a,0x747b,0x747c,0x747d,0x747e,0x747f,
+ 0x7480,0x7481,0x7482,0x7483,0x7484,0x7485,0x7486,0x7487,
+ 0x7488,0x7489,0x748a,0x748b,0x748c,0x748d,0x748e,0x748f,
+ 0x7490,0x7491,0x7492,0x7493,0x7494,0x7495,0x7496,0x7497,
+ 0x7498,0x7499,0x749a,0x749b,0x749c,0x749d,0x749e,0x749f,
+ 0x74a0,0x74a1,0x74a2,0x74a3,0x74a4,0x74a5,0x74a6,0x74a7,
+ 0x74a8,0x74a9,0x74aa,0x74ab,0x74ac,0x74ad,0x74ae,0x74af,
+ 0x74b0,0x74b1,0x74b2,0x74b3,0x74b4,0x74b5,0x74b6,0x74b7,
+ 0x74b8,0x74b9,0x74ba,0x74bb,0x74bc,0x74bd,0x74be,0x74bf,
+ 0x74c0,0x74c1,0x74c2,0x74c3,0x74c4,0x74c5,0x74c6,0x74c7,
+ 0x74c8,0x74c9,0x74ca,0x74cb,0x74cc,0x74cd,0x74ce,0x74cf,
+ 0x74d0,0x74d1,0x74d2,0x74d3,0x74d4,0x74d5,0x74d6,0x74d7,
+ 0x74d8,0x74d9,0x74da,0x74db,0x74dc,0x74dd,0x74de,0x74df,
+ 0x74e0,0x74e1,0x74e2,0x74e3,0x74e4,0x74e5,0x74e6,0x74e7,
+ 0x74e8,0x74e9,0x74ea,0x74eb,0x74ec,0x74ed,0x74ee,0x74ef,
+ 0x74f0,0x74f1,0x74f2,0x74f3,0x74f4,0x74f5,0x74f6,0x74f7,
+ 0x74f8,0x74f9,0x74fa,0x74fb,0x74fc,0x74fd,0x74fe,0x74ff,
+ 0x7500,0x7501,0x7502,0x7503,0x7504,0x7505,0x7506,0x7507,
+ 0x7508,0x7509,0x750a,0x750b,0x750c,0x750d,0x750e,0x750f,
+ 0x7510,0x7511,0x7512,0x7513,0x7514,0x7515,0x7516,0x7517,
+ 0x7518,0x7519,0x751a,0x751b,0x751c,0x751d,0x751e,0x751f,
+ 0x7520,0x7521,0x7522,0x7523,0x7524,0x7525,0x7526,0x7527,
+ 0x7528,0x7529,0x752a,0x752b,0x752c,0x752d,0x752e,0x752f,
+ 0x7530,0x7531,0x7532,0x7533,0x7534,0x7535,0x7536,0x7537,
+ 0x7538,0x7539,0x753a,0x753b,0x753c,0x753d,0x753e,0x753f,
+ 0x7540,0x7541,0x7542,0x7543,0x7544,0x7545,0x7546,0x7547,
+ 0x7548,0x7549,0x754a,0x754b,0x754c,0x754d,0x754e,0x754f,
+ 0x7550,0x7551,0x7552,0x7553,0x7554,0x7555,0x7556,0x7557,
+ 0x7558,0x7559,0x755a,0x755b,0x755c,0x755d,0x755e,0x755f,
+ 0x7560,0x7561,0x7562,0x7563,0x7564,0x7565,0x7566,0x7567,
+ 0x7568,0x7569,0x756a,0x756b,0x756c,0x756d,0x756e,0x756f,
+ 0x7570,0x7571,0x7572,0x7573,0x7574,0x7575,0x7576,0x7577,
+ 0x7578,0x7579,0x757a,0x757b,0x757c,0x757d,0x757e,0x757f,
+ 0x7580,0x7581,0x7582,0x7583,0x7584,0x7585,0x7586,0x7587,
+ 0x7588,0x7589,0x758a,0x758b,0x758c,0x758d,0x758e,0x758f,
+ 0x7590,0x7591,0x7592,0x7593,0x7594,0x7595,0x7596,0x7597,
+ 0x7598,0x7599,0x759a,0x759b,0x759c,0x759d,0x759e,0x759f,
+ 0x75a0,0x75a1,0x75a2,0x75a3,0x75a4,0x75a5,0x75a6,0x75a7,
+ 0x75a8,0x75a9,0x75aa,0x75ab,0x75ac,0x75ad,0x75ae,0x75af,
+ 0x75b0,0x75b1,0x75b2,0x75b3,0x75b4,0x75b5,0x75b6,0x75b7,
+ 0x75b8,0x75b9,0x75ba,0x75bb,0x75bc,0x75bd,0x75be,0x75bf,
+ 0x75c0,0x75c1,0x75c2,0x75c3,0x75c4,0x75c5,0x75c6,0x75c7,
+ 0x75c8,0x75c9,0x75ca,0x75cb,0x75cc,0x75cd,0x75ce,0x75cf,
+ 0x75d0,0x75d1,0x75d2,0x75d3,0x75d4,0x75d5,0x75d6,0x75d7,
+ 0x75d8,0x75d9,0x75da,0x75db,0x75dc,0x75dd,0x75de,0x75df,
+ 0x75e0,0x75e1,0x75e2,0x75e3,0x75e4,0x75e5,0x75e6,0x75e7,
+ 0x75e8,0x75e9,0x75ea,0x75eb,0x75ec,0x75ed,0x75ee,0x75ef,
+ 0x75f0,0x75f1,0x75f2,0x75f3,0x75f4,0x75f5,0x75f6,0x75f7,
+ 0x75f8,0x75f9,0x75fa,0x75fb,0x75fc,0x75fd,0x75fe,0x75ff,
+ 0x7600,0x7601,0x7602,0x7603,0x7604,0x7605,0x7606,0x7607,
+ 0x7608,0x7609,0x760a,0x760b,0x760c,0x760d,0x760e,0x760f,
+ 0x7610,0x7611,0x7612,0x7613,0x7614,0x7615,0x7616,0x7617,
+ 0x7618,0x7619,0x761a,0x761b,0x761c,0x761d,0x761e,0x761f,
+ 0x7620,0x7621,0x7622,0x7623,0x7624,0x7625,0x7626,0x7627,
+ 0x7628,0x7629,0x762a,0x762b,0x762c,0x762d,0x762e,0x762f,
+ 0x7630,0x7631,0x7632,0x7633,0x7634,0x7635,0x7636,0x7637,
+ 0x7638,0x7639,0x763a,0x763b,0x763c,0x763d,0x763e,0x763f,
+ 0x7640,0x7641,0x7642,0x7643,0x7644,0x7645,0x7646,0x7647,
+ 0x7648,0x7649,0x764a,0x764b,0x764c,0x764d,0x764e,0x764f,
+ 0x7650,0x7651,0x7652,0x7653,0x7654,0x7655,0x7656,0x7657,
+ 0x7658,0x7659,0x765a,0x765b,0x765c,0x765d,0x765e,0x765f,
+ 0x7660,0x7661,0x7662,0x7663,0x7664,0x7665,0x7666,0x7667,
+ 0x7668,0x7669,0x766a,0x766b,0x766c,0x766d,0x766e,0x766f,
+ 0x7670,0x7671,0x7672,0x7673,0x7674,0x7675,0x7676,0x7677,
+ 0x7678,0x7679,0x767a,0x767b,0x767c,0x767d,0x767e,0x767f,
+ 0x7680,0x7681,0x7682,0x7683,0x7684,0x7685,0x7686,0x7687,
+ 0x7688,0x7689,0x768a,0x768b,0x768c,0x768d,0x768e,0x768f,
+ 0x7690,0x7691,0x7692,0x7693,0x7694,0x7695,0x7696,0x7697,
+ 0x7698,0x7699,0x769a,0x769b,0x769c,0x769d,0x769e,0x769f,
+ 0x76a0,0x76a1,0x76a2,0x76a3,0x76a4,0x76a5,0x76a6,0x76a7,
+ 0x76a8,0x76a9,0x76aa,0x76ab,0x76ac,0x76ad,0x76ae,0x76af,
+ 0x76b0,0x76b1,0x76b2,0x76b3,0x76b4,0x76b5,0x76b6,0x76b7,
+ 0x76b8,0x76b9,0x76ba,0x76bb,0x76bc,0x76bd,0x76be,0x76bf,
+ 0x76c0,0x76c1,0x76c2,0x76c3,0x76c4,0x76c5,0x76c6,0x76c7,
+ 0x76c8,0x76c9,0x76ca,0x76cb,0x76cc,0x76cd,0x76ce,0x76cf,
+ 0x76d0,0x76d1,0x76d2,0x76d3,0x76d4,0x76d5,0x76d6,0x76d7,
+ 0x76d8,0x76d9,0x76da,0x76db,0x76dc,0x76dd,0x76de,0x76df,
+ 0x76e0,0x76e1,0x76e2,0x76e3,0x76e4,0x76e5,0x76e6,0x76e7,
+ 0x76e8,0x76e9,0x76ea,0x76eb,0x76ec,0x76ed,0x76ee,0x76ef,
+ 0x76f0,0x76f1,0x76f2,0x76f3,0x76f4,0x76f5,0x76f6,0x76f7,
+ 0x76f8,0x76f9,0x76fa,0x76fb,0x76fc,0x76fd,0x76fe,0x76ff,
+ 0x7700,0x7701,0x7702,0x7703,0x7704,0x7705,0x7706,0x7707,
+ 0x7708,0x7709,0x770a,0x770b,0x770c,0x770d,0x770e,0x770f,
+ 0x7710,0x7711,0x7712,0x7713,0x7714,0x7715,0x7716,0x7717,
+ 0x7718,0x7719,0x771a,0x771b,0x771c,0x771d,0x771e,0x771f,
+ 0x7720,0x7721,0x7722,0x7723,0x7724,0x7725,0x7726,0x7727,
+ 0x7728,0x7729,0x772a,0x772b,0x772c,0x772d,0x772e,0x772f,
+ 0x7730,0x7731,0x7732,0x7733,0x7734,0x7735,0x7736,0x7737,
+ 0x7738,0x7739,0x773a,0x773b,0x773c,0x773d,0x773e,0x773f,
+ 0x7740,0x7741,0x7742,0x7743,0x7744,0x7745,0x7746,0x7747,
+ 0x7748,0x7749,0x774a,0x774b,0x774c,0x774d,0x774e,0x774f,
+ 0x7750,0x7751,0x7752,0x7753,0x7754,0x7755,0x7756,0x7757,
+ 0x7758,0x7759,0x775a,0x775b,0x775c,0x775d,0x775e,0x775f,
+ 0x7760,0x7761,0x7762,0x7763,0x7764,0x7765,0x7766,0x7767,
+ 0x7768,0x7769,0x776a,0x776b,0x776c,0x776d,0x776e,0x776f,
+ 0x7770,0x7771,0x7772,0x7773,0x7774,0x7775,0x7776,0x7777,
+ 0x7778,0x7779,0x777a,0x777b,0x777c,0x777d,0x777e,0x777f,
+ 0x7780,0x7781,0x7782,0x7783,0x7784,0x7785,0x7786,0x7787,
+ 0x7788,0x7789,0x778a,0x778b,0x778c,0x778d,0x778e,0x778f,
+ 0x7790,0x7791,0x7792,0x7793,0x7794,0x7795,0x7796,0x7797,
+ 0x7798,0x7799,0x779a,0x779b,0x779c,0x779d,0x779e,0x779f,
+ 0x77a0,0x77a1,0x77a2,0x77a3,0x77a4,0x77a5,0x77a6,0x77a7,
+ 0x77a8,0x77a9,0x77aa,0x77ab,0x77ac,0x77ad,0x77ae,0x77af,
+ 0x77b0,0x77b1,0x77b2,0x77b3,0x77b4,0x77b5,0x77b6,0x77b7,
+ 0x77b8,0x77b9,0x77ba,0x77bb,0x77bc,0x77bd,0x77be,0x77bf,
+ 0x77c0,0x77c1,0x77c2,0x77c3,0x77c4,0x77c5,0x77c6,0x77c7,
+ 0x77c8,0x77c9,0x77ca,0x77cb,0x77cc,0x77cd,0x77ce,0x77cf,
+ 0x77d0,0x77d1,0x77d2,0x77d3,0x77d4,0x77d5,0x77d6,0x77d7,
+ 0x77d8,0x77d9,0x77da,0x77db,0x77dc,0x77dd,0x77de,0x77df,
+ 0x77e0,0x77e1,0x77e2,0x77e3,0x77e4,0x77e5,0x77e6,0x77e7,
+ 0x77e8,0x77e9,0x77ea,0x77eb,0x77ec,0x77ed,0x77ee,0x77ef,
+ 0x77f0,0x77f1,0x77f2,0x77f3,0x77f4,0x77f5,0x77f6,0x77f7,
+ 0x77f8,0x77f9,0x77fa,0x77fb,0x77fc,0x77fd,0x77fe,0x77ff,
+ 0x7800,0x7801,0x7802,0x7803,0x7804,0x7805,0x7806,0x7807,
+ 0x7808,0x7809,0x780a,0x780b,0x780c,0x780d,0x780e,0x780f,
+ 0x7810,0x7811,0x7812,0x7813,0x7814,0x7815,0x7816,0x7817,
+ 0x7818,0x7819,0x781a,0x781b,0x781c,0x781d,0x781e,0x781f,
+ 0x7820,0x7821,0x7822,0x7823,0x7824,0x7825,0x7826,0x7827,
+ 0x7828,0x7829,0x782a,0x782b,0x782c,0x782d,0x782e,0x782f,
+ 0x7830,0x7831,0x7832,0x7833,0x7834,0x7835,0x7836,0x7837,
+ 0x7838,0x7839,0x783a,0x783b,0x783c,0x783d,0x783e,0x783f,
+ 0x7840,0x7841,0x7842,0x7843,0x7844,0x7845,0x7846,0x7847,
+ 0x7848,0x7849,0x784a,0x784b,0x784c,0x784d,0x784e,0x784f,
+ 0x7850,0x7851,0x7852,0x7853,0x7854,0x7855,0x7856,0x7857,
+ 0x7858,0x7859,0x785a,0x785b,0x785c,0x785d,0x785e,0x785f,
+ 0x7860,0x7861,0x7862,0x7863,0x7864,0x7865,0x7866,0x7867,
+ 0x7868,0x7869,0x786a,0x786b,0x786c,0x786d,0x786e,0x786f,
+ 0x7870,0x7871,0x7872,0x7873,0x7874,0x7875,0x7876,0x7877,
+ 0x7878,0x7879,0x787a,0x787b,0x787c,0x787d,0x787e,0x787f,
+ 0x7880,0x7881,0x7882,0x7883,0x7884,0x7885,0x7886,0x7887,
+ 0x7888,0x7889,0x788a,0x788b,0x788c,0x788d,0x788e,0x788f,
+ 0x7890,0x7891,0x7892,0x7893,0x7894,0x7895,0x7896,0x7897,
+ 0x7898,0x7899,0x789a,0x789b,0x789c,0x789d,0x789e,0x789f,
+ 0x78a0,0x78a1,0x78a2,0x78a3,0x78a4,0x78a5,0x78a6,0x78a7,
+ 0x78a8,0x78a9,0x78aa,0x78ab,0x78ac,0x78ad,0x78ae,0x78af,
+ 0x78b0,0x78b1,0x78b2,0x78b3,0x78b4,0x78b5,0x78b6,0x78b7,
+ 0x78b8,0x78b9,0x78ba,0x78bb,0x78bc,0x78bd,0x78be,0x78bf,
+ 0x78c0,0x78c1,0x78c2,0x78c3,0x78c4,0x78c5,0x78c6,0x78c7,
+ 0x78c8,0x78c9,0x78ca,0x78cb,0x78cc,0x78cd,0x78ce,0x78cf,
+ 0x78d0,0x78d1,0x78d2,0x78d3,0x78d4,0x78d5,0x78d6,0x78d7,
+ 0x78d8,0x78d9,0x78da,0x78db,0x78dc,0x78dd,0x78de,0x78df,
+ 0x78e0,0x78e1,0x78e2,0x78e3,0x78e4,0x78e5,0x78e6,0x78e7,
+ 0x78e8,0x78e9,0x78ea,0x78eb,0x78ec,0x78ed,0x78ee,0x78ef,
+ 0x78f0,0x78f1,0x78f2,0x78f3,0x78f4,0x78f5,0x78f6,0x78f7,
+ 0x78f8,0x78f9,0x78fa,0x78fb,0x78fc,0x78fd,0x78fe,0x78ff,
+ 0x7900,0x7901,0x7902,0x7903,0x7904,0x7905,0x7906,0x7907,
+ 0x7908,0x7909,0x790a,0x790b,0x790c,0x790d,0x790e,0x790f,
+ 0x7910,0x7911,0x7912,0x7913,0x7914,0x7915,0x7916,0x7917,
+ 0x7918,0x7919,0x791a,0x791b,0x791c,0x791d,0x791e,0x791f,
+ 0x7920,0x7921,0x7922,0x7923,0x7924,0x7925,0x7926,0x7927,
+ 0x7928,0x7929,0x792a,0x792b,0x792c,0x792d,0x792e,0x792f,
+ 0x7930,0x7931,0x7932,0x7933,0x7934,0x7935,0x7936,0x7937,
+ 0x7938,0x7939,0x793a,0x793b,0x793c,0x793d,0x793e,0x793f,
+ 0x7940,0x7941,0x7942,0x7943,0x7944,0x7945,0x7946,0x7947,
+ 0x7948,0x7949,0x794a,0x794b,0x794c,0x794d,0x794e,0x794f,
+ 0x7950,0x7951,0x7952,0x7953,0x7954,0x7955,0x7956,0x7957,
+ 0x7958,0x7959,0x795a,0x795b,0x795c,0x795d,0x795e,0x795f,
+ 0x7960,0x7961,0x7962,0x7963,0x7964,0x7965,0x7966,0x7967,
+ 0x7968,0x7969,0x796a,0x796b,0x796c,0x796d,0x796e,0x796f,
+ 0x7970,0x7971,0x7972,0x7973,0x7974,0x7975,0x7976,0x7977,
+ 0x7978,0x7979,0x797a,0x797b,0x797c,0x797d,0x797e,0x797f,
+ 0x7980,0x7981,0x7982,0x7983,0x7984,0x7985,0x7986,0x7987,
+ 0x7988,0x7989,0x798a,0x798b,0x798c,0x798d,0x798e,0x798f,
+ 0x7990,0x7991,0x7992,0x7993,0x7994,0x7995,0x7996,0x7997,
+ 0x7998,0x7999,0x799a,0x799b,0x799c,0x799d,0x799e,0x799f,
+ 0x79a0,0x79a1,0x79a2,0x79a3,0x79a4,0x79a5,0x79a6,0x79a7,
+ 0x79a8,0x79a9,0x79aa,0x79ab,0x79ac,0x79ad,0x79ae,0x79af,
+ 0x79b0,0x79b1,0x79b2,0x79b3,0x79b4,0x79b5,0x79b6,0x79b7,
+ 0x79b8,0x79b9,0x79ba,0x79bb,0x79bc,0x79bd,0x79be,0x79bf,
+ 0x79c0,0x79c1,0x79c2,0x79c3,0x79c4,0x79c5,0x79c6,0x79c7,
+ 0x79c8,0x79c9,0x79ca,0x79cb,0x79cc,0x79cd,0x79ce,0x79cf,
+ 0x79d0,0x79d1,0x79d2,0x79d3,0x79d4,0x79d5,0x79d6,0x79d7,
+ 0x79d8,0x79d9,0x79da,0x79db,0x79dc,0x79dd,0x79de,0x79df,
+ 0x79e0,0x79e1,0x79e2,0x79e3,0x79e4,0x79e5,0x79e6,0x79e7,
+ 0x79e8,0x79e9,0x79ea,0x79eb,0x79ec,0x79ed,0x79ee,0x79ef,
+ 0x79f0,0x79f1,0x79f2,0x79f3,0x79f4,0x79f5,0x79f6,0x79f7,
+ 0x79f8,0x79f9,0x79fa,0x79fb,0x79fc,0x79fd,0x79fe,0x79ff,
+ 0x7a00,0x7a01,0x7a02,0x7a03,0x7a04,0x7a05,0x7a06,0x7a07,
+ 0x7a08,0x7a09,0x7a0a,0x7a0b,0x7a0c,0x7a0d,0x7a0e,0x7a0f,
+ 0x7a10,0x7a11,0x7a12,0x7a13,0x7a14,0x7a15,0x7a16,0x7a17,
+ 0x7a18,0x7a19,0x7a1a,0x7a1b,0x7a1c,0x7a1d,0x7a1e,0x7a1f,
+ 0x7a20,0x7a21,0x7a22,0x7a23,0x7a24,0x7a25,0x7a26,0x7a27,
+ 0x7a28,0x7a29,0x7a2a,0x7a2b,0x7a2c,0x7a2d,0x7a2e,0x7a2f,
+ 0x7a30,0x7a31,0x7a32,0x7a33,0x7a34,0x7a35,0x7a36,0x7a37,
+ 0x7a38,0x7a39,0x7a3a,0x7a3b,0x7a3c,0x7a3d,0x7a3e,0x7a3f,
+ 0x7a40,0x7a41,0x7a42,0x7a43,0x7a44,0x7a45,0x7a46,0x7a47,
+ 0x7a48,0x7a49,0x7a4a,0x7a4b,0x7a4c,0x7a4d,0x7a4e,0x7a4f,
+ 0x7a50,0x7a51,0x7a52,0x7a53,0x7a54,0x7a55,0x7a56,0x7a57,
+ 0x7a58,0x7a59,0x7a5a,0x7a5b,0x7a5c,0x7a5d,0x7a5e,0x7a5f,
+ 0x7a60,0x7a61,0x7a62,0x7a63,0x7a64,0x7a65,0x7a66,0x7a67,
+ 0x7a68,0x7a69,0x7a6a,0x7a6b,0x7a6c,0x7a6d,0x7a6e,0x7a6f,
+ 0x7a70,0x7a71,0x7a72,0x7a73,0x7a74,0x7a75,0x7a76,0x7a77,
+ 0x7a78,0x7a79,0x7a7a,0x7a7b,0x7a7c,0x7a7d,0x7a7e,0x7a7f,
+ 0x7a80,0x7a81,0x7a82,0x7a83,0x7a84,0x7a85,0x7a86,0x7a87,
+ 0x7a88,0x7a89,0x7a8a,0x7a8b,0x7a8c,0x7a8d,0x7a8e,0x7a8f,
+ 0x7a90,0x7a91,0x7a92,0x7a93,0x7a94,0x7a95,0x7a96,0x7a97,
+ 0x7a98,0x7a99,0x7a9a,0x7a9b,0x7a9c,0x7a9d,0x7a9e,0x7a9f,
+ 0x7aa0,0x7aa1,0x7aa2,0x7aa3,0x7aa4,0x7aa5,0x7aa6,0x7aa7,
+ 0x7aa8,0x7aa9,0x7aaa,0x7aab,0x7aac,0x7aad,0x7aae,0x7aaf,
+ 0x7ab0,0x7ab1,0x7ab2,0x7ab3,0x7ab4,0x7ab5,0x7ab6,0x7ab7,
+ 0x7ab8,0x7ab9,0x7aba,0x7abb,0x7abc,0x7abd,0x7abe,0x7abf,
+ 0x7ac0,0x7ac1,0x7ac2,0x7ac3,0x7ac4,0x7ac5,0x7ac6,0x7ac7,
+ 0x7ac8,0x7ac9,0x7aca,0x7acb,0x7acc,0x7acd,0x7ace,0x7acf,
+ 0x7ad0,0x7ad1,0x7ad2,0x7ad3,0x7ad4,0x7ad5,0x7ad6,0x7ad7,
+ 0x7ad8,0x7ad9,0x7ada,0x7adb,0x7adc,0x7add,0x7ade,0x7adf,
+ 0x7ae0,0x7ae1,0x7ae2,0x7ae3,0x7ae4,0x7ae5,0x7ae6,0x7ae7,
+ 0x7ae8,0x7ae9,0x7aea,0x7aeb,0x7aec,0x7aed,0x7aee,0x7aef,
+ 0x7af0,0x7af1,0x7af2,0x7af3,0x7af4,0x7af5,0x7af6,0x7af7,
+ 0x7af8,0x7af9,0x7afa,0x7afb,0x7afc,0x7afd,0x7afe,0x7aff,
+ 0x7b00,0x7b01,0x7b02,0x7b03,0x7b04,0x7b05,0x7b06,0x7b07,
+ 0x7b08,0x7b09,0x7b0a,0x7b0b,0x7b0c,0x7b0d,0x7b0e,0x7b0f,
+ 0x7b10,0x7b11,0x7b12,0x7b13,0x7b14,0x7b15,0x7b16,0x7b17,
+ 0x7b18,0x7b19,0x7b1a,0x7b1b,0x7b1c,0x7b1d,0x7b1e,0x7b1f,
+ 0x7b20,0x7b21,0x7b22,0x7b23,0x7b24,0x7b25,0x7b26,0x7b27,
+ 0x7b28,0x7b29,0x7b2a,0x7b2b,0x7b2c,0x7b2d,0x7b2e,0x7b2f,
+ 0x7b30,0x7b31,0x7b32,0x7b33,0x7b34,0x7b35,0x7b36,0x7b37,
+ 0x7b38,0x7b39,0x7b3a,0x7b3b,0x7b3c,0x7b3d,0x7b3e,0x7b3f,
+ 0x7b40,0x7b41,0x7b42,0x7b43,0x7b44,0x7b45,0x7b46,0x7b47,
+ 0x7b48,0x7b49,0x7b4a,0x7b4b,0x7b4c,0x7b4d,0x7b4e,0x7b4f,
+ 0x7b50,0x7b51,0x7b52,0x7b53,0x7b54,0x7b55,0x7b56,0x7b57,
+ 0x7b58,0x7b59,0x7b5a,0x7b5b,0x7b5c,0x7b5d,0x7b5e,0x7b5f,
+ 0x7b60,0x7b61,0x7b62,0x7b63,0x7b64,0x7b65,0x7b66,0x7b67,
+ 0x7b68,0x7b69,0x7b6a,0x7b6b,0x7b6c,0x7b6d,0x7b6e,0x7b6f,
+ 0x7b70,0x7b71,0x7b72,0x7b73,0x7b74,0x7b75,0x7b76,0x7b77,
+ 0x7b78,0x7b79,0x7b7a,0x7b7b,0x7b7c,0x7b7d,0x7b7e,0x7b7f,
+ 0x7b80,0x7b81,0x7b82,0x7b83,0x7b84,0x7b85,0x7b86,0x7b87,
+ 0x7b88,0x7b89,0x7b8a,0x7b8b,0x7b8c,0x7b8d,0x7b8e,0x7b8f,
+ 0x7b90,0x7b91,0x7b92,0x7b93,0x7b94,0x7b95,0x7b96,0x7b97,
+ 0x7b98,0x7b99,0x7b9a,0x7b9b,0x7b9c,0x7b9d,0x7b9e,0x7b9f,
+ 0x7ba0,0x7ba1,0x7ba2,0x7ba3,0x7ba4,0x7ba5,0x7ba6,0x7ba7,
+ 0x7ba8,0x7ba9,0x7baa,0x7bab,0x7bac,0x7bad,0x7bae,0x7baf,
+ 0x7bb0,0x7bb1,0x7bb2,0x7bb3,0x7bb4,0x7bb5,0x7bb6,0x7bb7,
+ 0x7bb8,0x7bb9,0x7bba,0x7bbb,0x7bbc,0x7bbd,0x7bbe,0x7bbf,
+ 0x7bc0,0x7bc1,0x7bc2,0x7bc3,0x7bc4,0x7bc5,0x7bc6,0x7bc7,
+ 0x7bc8,0x7bc9,0x7bca,0x7bcb,0x7bcc,0x7bcd,0x7bce,0x7bcf,
+ 0x7bd0,0x7bd1,0x7bd2,0x7bd3,0x7bd4,0x7bd5,0x7bd6,0x7bd7,
+ 0x7bd8,0x7bd9,0x7bda,0x7bdb,0x7bdc,0x7bdd,0x7bde,0x7bdf,
+ 0x7be0,0x7be1,0x7be2,0x7be3,0x7be4,0x7be5,0x7be6,0x7be7,
+ 0x7be8,0x7be9,0x7bea,0x7beb,0x7bec,0x7bed,0x7bee,0x7bef,
+ 0x7bf0,0x7bf1,0x7bf2,0x7bf3,0x7bf4,0x7bf5,0x7bf6,0x7bf7,
+ 0x7bf8,0x7bf9,0x7bfa,0x7bfb,0x7bfc,0x7bfd,0x7bfe,0x7bff,
+ 0x7c00,0x7c01,0x7c02,0x7c03,0x7c04,0x7c05,0x7c06,0x7c07,
+ 0x7c08,0x7c09,0x7c0a,0x7c0b,0x7c0c,0x7c0d,0x7c0e,0x7c0f,
+ 0x7c10,0x7c11,0x7c12,0x7c13,0x7c14,0x7c15,0x7c16,0x7c17,
+ 0x7c18,0x7c19,0x7c1a,0x7c1b,0x7c1c,0x7c1d,0x7c1e,0x7c1f,
+ 0x7c20,0x7c21,0x7c22,0x7c23,0x7c24,0x7c25,0x7c26,0x7c27,
+ 0x7c28,0x7c29,0x7c2a,0x7c2b,0x7c2c,0x7c2d,0x7c2e,0x7c2f,
+ 0x7c30,0x7c31,0x7c32,0x7c33,0x7c34,0x7c35,0x7c36,0x7c37,
+ 0x7c38,0x7c39,0x7c3a,0x7c3b,0x7c3c,0x7c3d,0x7c3e,0x7c3f,
+ 0x7c40,0x7c41,0x7c42,0x7c43,0x7c44,0x7c45,0x7c46,0x7c47,
+ 0x7c48,0x7c49,0x7c4a,0x7c4b,0x7c4c,0x7c4d,0x7c4e,0x7c4f,
+ 0x7c50,0x7c51,0x7c52,0x7c53,0x7c54,0x7c55,0x7c56,0x7c57,
+ 0x7c58,0x7c59,0x7c5a,0x7c5b,0x7c5c,0x7c5d,0x7c5e,0x7c5f,
+ 0x7c60,0x7c61,0x7c62,0x7c63,0x7c64,0x7c65,0x7c66,0x7c67,
+ 0x7c68,0x7c69,0x7c6a,0x7c6b,0x7c6c,0x7c6d,0x7c6e,0x7c6f,
+ 0x7c70,0x7c71,0x7c72,0x7c73,0x7c74,0x7c75,0x7c76,0x7c77,
+ 0x7c78,0x7c79,0x7c7a,0x7c7b,0x7c7c,0x7c7d,0x7c7e,0x7c7f,
+ 0x7c80,0x7c81,0x7c82,0x7c83,0x7c84,0x7c85,0x7c86,0x7c87,
+ 0x7c88,0x7c89,0x7c8a,0x7c8b,0x7c8c,0x7c8d,0x7c8e,0x7c8f,
+ 0x7c90,0x7c91,0x7c92,0x7c93,0x7c94,0x7c95,0x7c96,0x7c97,
+ 0x7c98,0x7c99,0x7c9a,0x7c9b,0x7c9c,0x7c9d,0x7c9e,0x7c9f,
+ 0x7ca0,0x7ca1,0x7ca2,0x7ca3,0x7ca4,0x7ca5,0x7ca6,0x7ca7,
+ 0x7ca8,0x7ca9,0x7caa,0x7cab,0x7cac,0x7cad,0x7cae,0x7caf,
+ 0x7cb0,0x7cb1,0x7cb2,0x7cb3,0x7cb4,0x7cb5,0x7cb6,0x7cb7,
+ 0x7cb8,0x7cb9,0x7cba,0x7cbb,0x7cbc,0x7cbd,0x7cbe,0x7cbf,
+ 0x7cc0,0x7cc1,0x7cc2,0x7cc3,0x7cc4,0x7cc5,0x7cc6,0x7cc7,
+ 0x7cc8,0x7cc9,0x7cca,0x7ccb,0x7ccc,0x7ccd,0x7cce,0x7ccf,
+ 0x7cd0,0x7cd1,0x7cd2,0x7cd3,0x7cd4,0x7cd5,0x7cd6,0x7cd7,
+ 0x7cd8,0x7cd9,0x7cda,0x7cdb,0x7cdc,0x7cdd,0x7cde,0x7cdf,
+ 0x7ce0,0x7ce1,0x7ce2,0x7ce3,0x7ce4,0x7ce5,0x7ce6,0x7ce7,
+ 0x7ce8,0x7ce9,0x7cea,0x7ceb,0x7cec,0x7ced,0x7cee,0x7cef,
+ 0x7cf0,0x7cf1,0x7cf2,0x7cf3,0x7cf4,0x7cf5,0x7cf6,0x7cf7,
+ 0x7cf8,0x7cf9,0x7cfa,0x7cfb,0x7cfc,0x7cfd,0x7cfe,0x7cff,
+ 0x7d00,0x7d01,0x7d02,0x7d03,0x7d04,0x7d05,0x7d06,0x7d07,
+ 0x7d08,0x7d09,0x7d0a,0x7d0b,0x7d0c,0x7d0d,0x7d0e,0x7d0f,
+ 0x7d10,0x7d11,0x7d12,0x7d13,0x7d14,0x7d15,0x7d16,0x7d17,
+ 0x7d18,0x7d19,0x7d1a,0x7d1b,0x7d1c,0x7d1d,0x7d1e,0x7d1f,
+ 0x7d20,0x7d21,0x7d22,0x7d23,0x7d24,0x7d25,0x7d26,0x7d27,
+ 0x7d28,0x7d29,0x7d2a,0x7d2b,0x7d2c,0x7d2d,0x7d2e,0x7d2f,
+ 0x7d30,0x7d31,0x7d32,0x7d33,0x7d34,0x7d35,0x7d36,0x7d37,
+ 0x7d38,0x7d39,0x7d3a,0x7d3b,0x7d3c,0x7d3d,0x7d3e,0x7d3f,
+ 0x7d40,0x7d41,0x7d42,0x7d43,0x7d44,0x7d45,0x7d46,0x7d47,
+ 0x7d48,0x7d49,0x7d4a,0x7d4b,0x7d4c,0x7d4d,0x7d4e,0x7d4f,
+ 0x7d50,0x7d51,0x7d52,0x7d53,0x7d54,0x7d55,0x7d56,0x7d57,
+ 0x7d58,0x7d59,0x7d5a,0x7d5b,0x7d5c,0x7d5d,0x7d5e,0x7d5f,
+ 0x7d60,0x7d61,0x7d62,0x7d63,0x7d64,0x7d65,0x7d66,0x7d67,
+ 0x7d68,0x7d69,0x7d6a,0x7d6b,0x7d6c,0x7d6d,0x7d6e,0x7d6f,
+ 0x7d70,0x7d71,0x7d72,0x7d73,0x7d74,0x7d75,0x7d76,0x7d77,
+ 0x7d78,0x7d79,0x7d7a,0x7d7b,0x7d7c,0x7d7d,0x7d7e,0x7d7f,
+ 0x7d80,0x7d81,0x7d82,0x7d83,0x7d84,0x7d85,0x7d86,0x7d87,
+ 0x7d88,0x7d89,0x7d8a,0x7d8b,0x7d8c,0x7d8d,0x7d8e,0x7d8f,
+ 0x7d90,0x7d91,0x7d92,0x7d93,0x7d94,0x7d95,0x7d96,0x7d97,
+ 0x7d98,0x7d99,0x7d9a,0x7d9b,0x7d9c,0x7d9d,0x7d9e,0x7d9f,
+ 0x7da0,0x7da1,0x7da2,0x7da3,0x7da4,0x7da5,0x7da6,0x7da7,
+ 0x7da8,0x7da9,0x7daa,0x7dab,0x7dac,0x7dad,0x7dae,0x7daf,
+ 0x7db0,0x7db1,0x7db2,0x7db3,0x7db4,0x7db5,0x7db6,0x7db7,
+ 0x7db8,0x7db9,0x7dba,0x7dbb,0x7dbc,0x7dbd,0x7dbe,0x7dbf,
+ 0x7dc0,0x7dc1,0x7dc2,0x7dc3,0x7dc4,0x7dc5,0x7dc6,0x7dc7,
+ 0x7dc8,0x7dc9,0x7dca,0x7dcb,0x7dcc,0x7dcd,0x7dce,0x7dcf,
+ 0x7dd0,0x7dd1,0x7dd2,0x7dd3,0x7dd4,0x7dd5,0x7dd6,0x7dd7,
+ 0x7dd8,0x7dd9,0x7dda,0x7ddb,0x7ddc,0x7ddd,0x7dde,0x7ddf,
+ 0x7de0,0x7de1,0x7de2,0x7de3,0x7de4,0x7de5,0x7de6,0x7de7,
+ 0x7de8,0x7de9,0x7dea,0x7deb,0x7dec,0x7ded,0x7dee,0x7def,
+ 0x7df0,0x7df1,0x7df2,0x7df3,0x7df4,0x7df5,0x7df6,0x7df7,
+ 0x7df8,0x7df9,0x7dfa,0x7dfb,0x7dfc,0x7dfd,0x7dfe,0x7dff,
+ 0x7e00,0x7e01,0x7e02,0x7e03,0x7e04,0x7e05,0x7e06,0x7e07,
+ 0x7e08,0x7e09,0x7e0a,0x7e0b,0x7e0c,0x7e0d,0x7e0e,0x7e0f,
+ 0x7e10,0x7e11,0x7e12,0x7e13,0x7e14,0x7e15,0x7e16,0x7e17,
+ 0x7e18,0x7e19,0x7e1a,0x7e1b,0x7e1c,0x7e1d,0x7e1e,0x7e1f,
+ 0x7e20,0x7e21,0x7e22,0x7e23,0x7e24,0x7e25,0x7e26,0x7e27,
+ 0x7e28,0x7e29,0x7e2a,0x7e2b,0x7e2c,0x7e2d,0x7e2e,0x7e2f,
+ 0x7e30,0x7e31,0x7e32,0x7e33,0x7e34,0x7e35,0x7e36,0x7e37,
+ 0x7e38,0x7e39,0x7e3a,0x7e3b,0x7e3c,0x7e3d,0x7e3e,0x7e3f,
+ 0x7e40,0x7e41,0x7e42,0x7e43,0x7e44,0x7e45,0x7e46,0x7e47,
+ 0x7e48,0x7e49,0x7e4a,0x7e4b,0x7e4c,0x7e4d,0x7e4e,0x7e4f,
+ 0x7e50,0x7e51,0x7e52,0x7e53,0x7e54,0x7e55,0x7e56,0x7e57,
+ 0x7e58,0x7e59,0x7e5a,0x7e5b,0x7e5c,0x7e5d,0x7e5e,0x7e5f,
+ 0x7e60,0x7e61,0x7e62,0x7e63,0x7e64,0x7e65,0x7e66,0x7e67,
+ 0x7e68,0x7e69,0x7e6a,0x7e6b,0x7e6c,0x7e6d,0x7e6e,0x7e6f,
+ 0x7e70,0x7e71,0x7e72,0x7e73,0x7e74,0x7e75,0x7e76,0x7e77,
+ 0x7e78,0x7e79,0x7e7a,0x7e7b,0x7e7c,0x7e7d,0x7e7e,0x7e7f,
+ 0x7e80,0x7e81,0x7e82,0x7e83,0x7e84,0x7e85,0x7e86,0x7e87,
+ 0x7e88,0x7e89,0x7e8a,0x7e8b,0x7e8c,0x7e8d,0x7e8e,0x7e8f,
+ 0x7e90,0x7e91,0x7e92,0x7e93,0x7e94,0x7e95,0x7e96,0x7e97,
+ 0x7e98,0x7e99,0x7e9a,0x7e9b,0x7e9c,0x7e9d,0x7e9e,0x7e9f,
+ 0x7ea0,0x7ea1,0x7ea2,0x7ea3,0x7ea4,0x7ea5,0x7ea6,0x7ea7,
+ 0x7ea8,0x7ea9,0x7eaa,0x7eab,0x7eac,0x7ead,0x7eae,0x7eaf,
+ 0x7eb0,0x7eb1,0x7eb2,0x7eb3,0x7eb4,0x7eb5,0x7eb6,0x7eb7,
+ 0x7eb8,0x7eb9,0x7eba,0x7ebb,0x7ebc,0x7ebd,0x7ebe,0x7ebf,
+ 0x7ec0,0x7ec1,0x7ec2,0x7ec3,0x7ec4,0x7ec5,0x7ec6,0x7ec7,
+ 0x7ec8,0x7ec9,0x7eca,0x7ecb,0x7ecc,0x7ecd,0x7ece,0x7ecf,
+ 0x7ed0,0x7ed1,0x7ed2,0x7ed3,0x7ed4,0x7ed5,0x7ed6,0x7ed7,
+ 0x7ed8,0x7ed9,0x7eda,0x7edb,0x7edc,0x7edd,0x7ede,0x7edf,
+ 0x7ee0,0x7ee1,0x7ee2,0x7ee3,0x7ee4,0x7ee5,0x7ee6,0x7ee7,
+ 0x7ee8,0x7ee9,0x7eea,0x7eeb,0x7eec,0x7eed,0x7eee,0x7eef,
+ 0x7ef0,0x7ef1,0x7ef2,0x7ef3,0x7ef4,0x7ef5,0x7ef6,0x7ef7,
+ 0x7ef8,0x7ef9,0x7efa,0x7efb,0x7efc,0x7efd,0x7efe,0x7eff,
+ 0x7f00,0x7f01,0x7f02,0x7f03,0x7f04,0x7f05,0x7f06,0x7f07,
+ 0x7f08,0x7f09,0x7f0a,0x7f0b,0x7f0c,0x7f0d,0x7f0e,0x7f0f,
+ 0x7f10,0x7f11,0x7f12,0x7f13,0x7f14,0x7f15,0x7f16,0x7f17,
+ 0x7f18,0x7f19,0x7f1a,0x7f1b,0x7f1c,0x7f1d,0x7f1e,0x7f1f,
+ 0x7f20,0x7f21,0x7f22,0x7f23,0x7f24,0x7f25,0x7f26,0x7f27,
+ 0x7f28,0x7f29,0x7f2a,0x7f2b,0x7f2c,0x7f2d,0x7f2e,0x7f2f,
+ 0x7f30,0x7f31,0x7f32,0x7f33,0x7f34,0x7f35,0x7f36,0x7f37,
+ 0x7f38,0x7f39,0x7f3a,0x7f3b,0x7f3c,0x7f3d,0x7f3e,0x7f3f,
+ 0x7f40,0x7f41,0x7f42,0x7f43,0x7f44,0x7f45,0x7f46,0x7f47,
+ 0x7f48,0x7f49,0x7f4a,0x7f4b,0x7f4c,0x7f4d,0x7f4e,0x7f4f,
+ 0x7f50,0x7f51,0x7f52,0x7f53,0x7f54,0x7f55,0x7f56,0x7f57,
+ 0x7f58,0x7f59,0x7f5a,0x7f5b,0x7f5c,0x7f5d,0x7f5e,0x7f5f,
+ 0x7f60,0x7f61,0x7f62,0x7f63,0x7f64,0x7f65,0x7f66,0x7f67,
+ 0x7f68,0x7f69,0x7f6a,0x7f6b,0x7f6c,0x7f6d,0x7f6e,0x7f6f,
+ 0x7f70,0x7f71,0x7f72,0x7f73,0x7f74,0x7f75,0x7f76,0x7f77,
+ 0x7f78,0x7f79,0x7f7a,0x7f7b,0x7f7c,0x7f7d,0x7f7e,0x7f7f,
+ 0x7f80,0x7f81,0x7f82,0x7f83,0x7f84,0x7f85,0x7f86,0x7f87,
+ 0x7f88,0x7f89,0x7f8a,0x7f8b,0x7f8c,0x7f8d,0x7f8e,0x7f8f,
+ 0x7f90,0x7f91,0x7f92,0x7f93,0x7f94,0x7f95,0x7f96,0x7f97,
+ 0x7f98,0x7f99,0x7f9a,0x7f9b,0x7f9c,0x7f9d,0x7f9e,0x7f9f,
+ 0x7fa0,0x7fa1,0x7fa2,0x7fa3,0x7fa4,0x7fa5,0x7fa6,0x7fa7,
+ 0x7fa8,0x7fa9,0x7faa,0x7fab,0x7fac,0x7fad,0x7fae,0x7faf,
+ 0x7fb0,0x7fb1,0x7fb2,0x7fb3,0x7fb4,0x7fb5,0x7fb6,0x7fb7,
+ 0x7fb8,0x7fb9,0x7fba,0x7fbb,0x7fbc,0x7fbd,0x7fbe,0x7fbf,
+ 0x7fc0,0x7fc1,0x7fc2,0x7fc3,0x7fc4,0x7fc5,0x7fc6,0x7fc7,
+ 0x7fc8,0x7fc9,0x7fca,0x7fcb,0x7fcc,0x7fcd,0x7fce,0x7fcf,
+ 0x7fd0,0x7fd1,0x7fd2,0x7fd3,0x7fd4,0x7fd5,0x7fd6,0x7fd7,
+ 0x7fd8,0x7fd9,0x7fda,0x7fdb,0x7fdc,0x7fdd,0x7fde,0x7fdf,
+ 0x7fe0,0x7fe1,0x7fe2,0x7fe3,0x7fe4,0x7fe5,0x7fe6,0x7fe7,
+ 0x7fe8,0x7fe9,0x7fea,0x7feb,0x7fec,0x7fed,0x7fee,0x7fef,
+ 0x7ff0,0x7ff1,0x7ff2,0x7ff3,0x7ff4,0x7ff5,0x7ff6,0x7ff7,
+ 0x7ff8,0x7ff9,0x7ffa,0x7ffb,0x7ffc,0x7ffd,0x7ffe,0x7fff,
+ 0x8000,0x8001,0x8002,0x8003,0x8004,0x8005,0x8006,0x8007,
+ 0x8008,0x8009,0x800a,0x800b,0x800c,0x800d,0x800e,0x800f,
+ 0x8010,0x8011,0x8012,0x8013,0x8014,0x8015,0x8016,0x8017,
+ 0x8018,0x8019,0x801a,0x801b,0x801c,0x801d,0x801e,0x801f,
+ 0x8020,0x8021,0x8022,0x8023,0x8024,0x8025,0x8026,0x8027,
+ 0x8028,0x8029,0x802a,0x802b,0x802c,0x802d,0x802e,0x802f,
+ 0x8030,0x8031,0x8032,0x8033,0x8034,0x8035,0x8036,0x8037,
+ 0x8038,0x8039,0x803a,0x803b,0x803c,0x803d,0x803e,0x803f,
+ 0x8040,0x8041,0x8042,0x8043,0x8044,0x8045,0x8046,0x8047,
+ 0x8048,0x8049,0x804a,0x804b,0x804c,0x804d,0x804e,0x804f,
+ 0x8050,0x8051,0x8052,0x8053,0x8054,0x8055,0x8056,0x8057,
+ 0x8058,0x8059,0x805a,0x805b,0x805c,0x805d,0x805e,0x805f,
+ 0x8060,0x8061,0x8062,0x8063,0x8064,0x8065,0x8066,0x8067,
+ 0x8068,0x8069,0x806a,0x806b,0x806c,0x806d,0x806e,0x806f,
+ 0x8070,0x8071,0x8072,0x8073,0x8074,0x8075,0x8076,0x8077,
+ 0x8078,0x8079,0x807a,0x807b,0x807c,0x807d,0x807e,0x807f,
+ 0x8080,0x8081,0x8082,0x8083,0x8084,0x8085,0x8086,0x8087,
+ 0x8088,0x8089,0x808a,0x808b,0x808c,0x808d,0x808e,0x808f,
+ 0x8090,0x8091,0x8092,0x8093,0x8094,0x8095,0x8096,0x8097,
+ 0x8098,0x8099,0x809a,0x809b,0x809c,0x809d,0x809e,0x809f,
+ 0x80a0,0x80a1,0x80a2,0x80a3,0x80a4,0x80a5,0x80a6,0x80a7,
+ 0x80a8,0x80a9,0x80aa,0x80ab,0x80ac,0x80ad,0x80ae,0x80af,
+ 0x80b0,0x80b1,0x80b2,0x80b3,0x80b4,0x80b5,0x80b6,0x80b7,
+ 0x80b8,0x80b9,0x80ba,0x80bb,0x80bc,0x80bd,0x80be,0x80bf,
+ 0x80c0,0x80c1,0x80c2,0x80c3,0x80c4,0x80c5,0x80c6,0x80c7,
+ 0x80c8,0x80c9,0x80ca,0x80cb,0x80cc,0x80cd,0x80ce,0x80cf,
+ 0x80d0,0x80d1,0x80d2,0x80d3,0x80d4,0x80d5,0x80d6,0x80d7,
+ 0x80d8,0x80d9,0x80da,0x80db,0x80dc,0x80dd,0x80de,0x80df,
+ 0x80e0,0x80e1,0x80e2,0x80e3,0x80e4,0x80e5,0x80e6,0x80e7,
+ 0x80e8,0x80e9,0x80ea,0x80eb,0x80ec,0x80ed,0x80ee,0x80ef,
+ 0x80f0,0x80f1,0x80f2,0x80f3,0x80f4,0x80f5,0x80f6,0x80f7,
+ 0x80f8,0x80f9,0x80fa,0x80fb,0x80fc,0x80fd,0x80fe,0x80ff,
+ 0x8100,0x8101,0x8102,0x8103,0x8104,0x8105,0x8106,0x8107,
+ 0x8108,0x8109,0x810a,0x810b,0x810c,0x810d,0x810e,0x810f,
+ 0x8110,0x8111,0x8112,0x8113,0x8114,0x8115,0x8116,0x8117,
+ 0x8118,0x8119,0x811a,0x811b,0x811c,0x811d,0x811e,0x811f,
+ 0x8120,0x8121,0x8122,0x8123,0x8124,0x8125,0x8126,0x8127,
+ 0x8128,0x8129,0x812a,0x812b,0x812c,0x812d,0x812e,0x812f,
+ 0x8130,0x8131,0x8132,0x8133,0x8134,0x8135,0x8136,0x8137,
+ 0x8138,0x8139,0x813a,0x813b,0x813c,0x813d,0x813e,0x813f,
+ 0x8140,0x8141,0x8142,0x8143,0x8144,0x8145,0x8146,0x8147,
+ 0x8148,0x8149,0x814a,0x814b,0x814c,0x814d,0x814e,0x814f,
+ 0x8150,0x8151,0x8152,0x8153,0x8154,0x8155,0x8156,0x8157,
+ 0x8158,0x8159,0x815a,0x815b,0x815c,0x815d,0x815e,0x815f,
+ 0x8160,0x8161,0x8162,0x8163,0x8164,0x8165,0x8166,0x8167,
+ 0x8168,0x8169,0x816a,0x816b,0x816c,0x816d,0x816e,0x816f,
+ 0x8170,0x8171,0x8172,0x8173,0x8174,0x8175,0x8176,0x8177,
+ 0x8178,0x8179,0x817a,0x817b,0x817c,0x817d,0x817e,0x817f,
+ 0x8180,0x8181,0x8182,0x8183,0x8184,0x8185,0x8186,0x8187,
+ 0x8188,0x8189,0x818a,0x818b,0x818c,0x818d,0x818e,0x818f,
+ 0x8190,0x8191,0x8192,0x8193,0x8194,0x8195,0x8196,0x8197,
+ 0x8198,0x8199,0x819a,0x819b,0x819c,0x819d,0x819e,0x819f,
+ 0x81a0,0x81a1,0x81a2,0x81a3,0x81a4,0x81a5,0x81a6,0x81a7,
+ 0x81a8,0x81a9,0x81aa,0x81ab,0x81ac,0x81ad,0x81ae,0x81af,
+ 0x81b0,0x81b1,0x81b2,0x81b3,0x81b4,0x81b5,0x81b6,0x81b7,
+ 0x81b8,0x81b9,0x81ba,0x81bb,0x81bc,0x81bd,0x81be,0x81bf,
+ 0x81c0,0x81c1,0x81c2,0x81c3,0x81c4,0x81c5,0x81c6,0x81c7,
+ 0x81c8,0x81c9,0x81ca,0x81cb,0x81cc,0x81cd,0x81ce,0x81cf,
+ 0x81d0,0x81d1,0x81d2,0x81d3,0x81d4,0x81d5,0x81d6,0x81d7,
+ 0x81d8,0x81d9,0x81da,0x81db,0x81dc,0x81dd,0x81de,0x81df,
+ 0x81e0,0x81e1,0x81e2,0x81e3,0x81e4,0x81e5,0x81e6,0x81e7,
+ 0x81e8,0x81e9,0x81ea,0x81eb,0x81ec,0x81ed,0x81ee,0x81ef,
+ 0x81f0,0x81f1,0x81f2,0x81f3,0x81f4,0x81f5,0x81f6,0x81f7,
+ 0x81f8,0x81f9,0x81fa,0x81fb,0x81fc,0x81fd,0x81fe,0x81ff,
+ 0x8200,0x8201,0x8202,0x8203,0x8204,0x8205,0x8206,0x8207,
+ 0x8208,0x8209,0x820a,0x820b,0x820c,0x820d,0x820e,0x820f,
+ 0x8210,0x8211,0x8212,0x8213,0x8214,0x8215,0x8216,0x8217,
+ 0x8218,0x8219,0x821a,0x821b,0x821c,0x821d,0x821e,0x821f,
+ 0x8220,0x8221,0x8222,0x8223,0x8224,0x8225,0x8226,0x8227,
+ 0x8228,0x8229,0x822a,0x822b,0x822c,0x822d,0x822e,0x822f,
+ 0x8230,0x8231,0x8232,0x8233,0x8234,0x8235,0x8236,0x8237,
+ 0x8238,0x8239,0x823a,0x823b,0x823c,0x823d,0x823e,0x823f,
+ 0x8240,0x8241,0x8242,0x8243,0x8244,0x8245,0x8246,0x8247,
+ 0x8248,0x8249,0x824a,0x824b,0x824c,0x824d,0x824e,0x824f,
+ 0x8250,0x8251,0x8252,0x8253,0x8254,0x8255,0x8256,0x8257,
+ 0x8258,0x8259,0x825a,0x825b,0x825c,0x825d,0x825e,0x825f,
+ 0x8260,0x8261,0x8262,0x8263,0x8264,0x8265,0x8266,0x8267,
+ 0x8268,0x8269,0x826a,0x826b,0x826c,0x826d,0x826e,0x826f,
+ 0x8270,0x8271,0x8272,0x8273,0x8274,0x8275,0x8276,0x8277,
+ 0x8278,0x8279,0x827a,0x827b,0x827c,0x827d,0x827e,0x827f,
+ 0x8280,0x8281,0x8282,0x8283,0x8284,0x8285,0x8286,0x8287,
+ 0x8288,0x8289,0x828a,0x828b,0x828c,0x828d,0x828e,0x828f,
+ 0x8290,0x8291,0x8292,0x8293,0x8294,0x8295,0x8296,0x8297,
+ 0x8298,0x8299,0x829a,0x829b,0x829c,0x829d,0x829e,0x829f,
+ 0x82a0,0x82a1,0x82a2,0x82a3,0x82a4,0x82a5,0x82a6,0x82a7,
+ 0x82a8,0x82a9,0x82aa,0x82ab,0x82ac,0x82ad,0x82ae,0x82af,
+ 0x82b0,0x82b1,0x82b2,0x82b3,0x82b4,0x82b5,0x82b6,0x82b7,
+ 0x82b8,0x82b9,0x82ba,0x82bb,0x82bc,0x82bd,0x82be,0x82bf,
+ 0x82c0,0x82c1,0x82c2,0x82c3,0x82c4,0x82c5,0x82c6,0x82c7,
+ 0x82c8,0x82c9,0x82ca,0x82cb,0x82cc,0x82cd,0x82ce,0x82cf,
+ 0x82d0,0x82d1,0x82d2,0x82d3,0x82d4,0x82d5,0x82d6,0x82d7,
+ 0x82d8,0x82d9,0x82da,0x82db,0x82dc,0x82dd,0x82de,0x82df,
+ 0x82e0,0x82e1,0x82e2,0x82e3,0x82e4,0x82e5,0x82e6,0x82e7,
+ 0x82e8,0x82e9,0x82ea,0x82eb,0x82ec,0x82ed,0x82ee,0x82ef,
+ 0x82f0,0x82f1,0x82f2,0x82f3,0x82f4,0x82f5,0x82f6,0x82f7,
+ 0x82f8,0x82f9,0x82fa,0x82fb,0x82fc,0x82fd,0x82fe,0x82ff,
+ 0x8300,0x8301,0x8302,0x8303,0x8304,0x8305,0x8306,0x8307,
+ 0x8308,0x8309,0x830a,0x830b,0x830c,0x830d,0x830e,0x830f,
+ 0x8310,0x8311,0x8312,0x8313,0x8314,0x8315,0x8316,0x8317,
+ 0x8318,0x8319,0x831a,0x831b,0x831c,0x831d,0x831e,0x831f,
+ 0x8320,0x8321,0x8322,0x8323,0x8324,0x8325,0x8326,0x8327,
+ 0x8328,0x8329,0x832a,0x832b,0x832c,0x832d,0x832e,0x832f,
+ 0x8330,0x8331,0x8332,0x8333,0x8334,0x8335,0x8336,0x8337,
+ 0x8338,0x8339,0x833a,0x833b,0x833c,0x833d,0x833e,0x833f,
+ 0x8340,0x8341,0x8342,0x8343,0x8344,0x8345,0x8346,0x8347,
+ 0x8348,0x8349,0x834a,0x834b,0x834c,0x834d,0x834e,0x834f,
+ 0x8350,0x8351,0x8352,0x8353,0x8354,0x8355,0x8356,0x8357,
+ 0x8358,0x8359,0x835a,0x835b,0x835c,0x835d,0x835e,0x835f,
+ 0x8360,0x8361,0x8362,0x8363,0x8364,0x8365,0x8366,0x8367,
+ 0x8368,0x8369,0x836a,0x836b,0x836c,0x836d,0x836e,0x836f,
+ 0x8370,0x8371,0x8372,0x8373,0x8374,0x8375,0x8376,0x8377,
+ 0x8378,0x8379,0x837a,0x837b,0x837c,0x837d,0x837e,0x837f,
+ 0x8380,0x8381,0x8382,0x8383,0x8384,0x8385,0x8386,0x8387,
+ 0x8388,0x8389,0x838a,0x838b,0x838c,0x838d,0x838e,0x838f,
+ 0x8390,0x8391,0x8392,0x8393,0x8394,0x8395,0x8396,0x8397,
+ 0x8398,0x8399,0x839a,0x839b,0x839c,0x839d,0x839e,0x839f,
+ 0x83a0,0x83a1,0x83a2,0x83a3,0x83a4,0x83a5,0x83a6,0x83a7,
+ 0x83a8,0x83a9,0x83aa,0x83ab,0x83ac,0x83ad,0x83ae,0x83af,
+ 0x83b0,0x83b1,0x83b2,0x83b3,0x83b4,0x83b5,0x83b6,0x83b7,
+ 0x83b8,0x83b9,0x83ba,0x83bb,0x83bc,0x83bd,0x83be,0x83bf,
+ 0x83c0,0x83c1,0x83c2,0x83c3,0x83c4,0x83c5,0x83c6,0x83c7,
+ 0x83c8,0x83c9,0x83ca,0x83cb,0x83cc,0x83cd,0x83ce,0x83cf,
+ 0x83d0,0x83d1,0x83d2,0x83d3,0x83d4,0x83d5,0x83d6,0x83d7,
+ 0x83d8,0x83d9,0x83da,0x83db,0x83dc,0x83dd,0x83de,0x83df,
+ 0x83e0,0x83e1,0x83e2,0x83e3,0x83e4,0x83e5,0x83e6,0x83e7,
+ 0x83e8,0x83e9,0x83ea,0x83eb,0x83ec,0x83ed,0x83ee,0x83ef,
+ 0x83f0,0x83f1,0x83f2,0x83f3,0x83f4,0x83f5,0x83f6,0x83f7,
+ 0x83f8,0x83f9,0x83fa,0x83fb,0x83fc,0x83fd,0x83fe,0x83ff,
+ 0x8400,0x8401,0x8402,0x8403,0x8404,0x8405,0x8406,0x8407,
+ 0x8408,0x8409,0x840a,0x840b,0x840c,0x840d,0x840e,0x840f,
+ 0x8410,0x8411,0x8412,0x8413,0x8414,0x8415,0x8416,0x8417,
+ 0x8418,0x8419,0x841a,0x841b,0x841c,0x841d,0x841e,0x841f,
+ 0x8420,0x8421,0x8422,0x8423,0x8424,0x8425,0x8426,0x8427,
+ 0x8428,0x8429,0x842a,0x842b,0x842c,0x842d,0x842e,0x842f,
+ 0x8430,0x8431,0x8432,0x8433,0x8434,0x8435,0x8436,0x8437,
+ 0x8438,0x8439,0x843a,0x843b,0x843c,0x843d,0x843e,0x843f,
+ 0x8440,0x8441,0x8442,0x8443,0x8444,0x8445,0x8446,0x8447,
+ 0x8448,0x8449,0x844a,0x844b,0x844c,0x844d,0x844e,0x844f,
+ 0x8450,0x8451,0x8452,0x8453,0x8454,0x8455,0x8456,0x8457,
+ 0x8458,0x8459,0x845a,0x845b,0x845c,0x845d,0x845e,0x845f,
+ 0x8460,0x8461,0x8462,0x8463,0x8464,0x8465,0x8466,0x8467,
+ 0x8468,0x8469,0x846a,0x846b,0x846c,0x846d,0x846e,0x846f,
+ 0x8470,0x8471,0x8472,0x8473,0x8474,0x8475,0x8476,0x8477,
+ 0x8478,0x8479,0x847a,0x847b,0x847c,0x847d,0x847e,0x847f,
+ 0x8480,0x8481,0x8482,0x8483,0x8484,0x8485,0x8486,0x8487,
+ 0x8488,0x8489,0x848a,0x848b,0x848c,0x848d,0x848e,0x848f,
+ 0x8490,0x8491,0x8492,0x8493,0x8494,0x8495,0x8496,0x8497,
+ 0x8498,0x8499,0x849a,0x849b,0x849c,0x849d,0x849e,0x849f,
+ 0x84a0,0x84a1,0x84a2,0x84a3,0x84a4,0x84a5,0x84a6,0x84a7,
+ 0x84a8,0x84a9,0x84aa,0x84ab,0x84ac,0x84ad,0x84ae,0x84af,
+ 0x84b0,0x84b1,0x84b2,0x84b3,0x84b4,0x84b5,0x84b6,0x84b7,
+ 0x84b8,0x84b9,0x84ba,0x84bb,0x84bc,0x84bd,0x84be,0x84bf,
+ 0x84c0,0x84c1,0x84c2,0x84c3,0x84c4,0x84c5,0x84c6,0x84c7,
+ 0x84c8,0x84c9,0x84ca,0x84cb,0x84cc,0x84cd,0x84ce,0x84cf,
+ 0x84d0,0x84d1,0x84d2,0x84d3,0x84d4,0x84d5,0x84d6,0x84d7,
+ 0x84d8,0x84d9,0x84da,0x84db,0x84dc,0x84dd,0x84de,0x84df,
+ 0x84e0,0x84e1,0x84e2,0x84e3,0x84e4,0x84e5,0x84e6,0x84e7,
+ 0x84e8,0x84e9,0x84ea,0x84eb,0x84ec,0x84ed,0x84ee,0x84ef,
+ 0x84f0,0x84f1,0x84f2,0x84f3,0x84f4,0x84f5,0x84f6,0x84f7,
+ 0x84f8,0x84f9,0x84fa,0x84fb,0x84fc,0x84fd,0x84fe,0x84ff,
+ 0x8500,0x8501,0x8502,0x8503,0x8504,0x8505,0x8506,0x8507,
+ 0x8508,0x8509,0x850a,0x850b,0x850c,0x850d,0x850e,0x850f,
+ 0x8510,0x8511,0x8512,0x8513,0x8514,0x8515,0x8516,0x8517,
+ 0x8518,0x8519,0x851a,0x851b,0x851c,0x851d,0x851e,0x851f,
+ 0x8520,0x8521,0x8522,0x8523,0x8524,0x8525,0x8526,0x8527,
+ 0x8528,0x8529,0x852a,0x852b,0x852c,0x852d,0x852e,0x852f,
+ 0x8530,0x8531,0x8532,0x8533,0x8534,0x8535,0x8536,0x8537,
+ 0x8538,0x8539,0x853a,0x853b,0x853c,0x853d,0x853e,0x853f,
+ 0x8540,0x8541,0x8542,0x8543,0x8544,0x8545,0x8546,0x8547,
+ 0x8548,0x8549,0x854a,0x854b,0x854c,0x854d,0x854e,0x854f,
+ 0x8550,0x8551,0x8552,0x8553,0x8554,0x8555,0x8556,0x8557,
+ 0x8558,0x8559,0x855a,0x855b,0x855c,0x855d,0x855e,0x855f,
+ 0x8560,0x8561,0x8562,0x8563,0x8564,0x8565,0x8566,0x8567,
+ 0x8568,0x8569,0x856a,0x856b,0x856c,0x856d,0x856e,0x856f,
+ 0x8570,0x8571,0x8572,0x8573,0x8574,0x8575,0x8576,0x8577,
+ 0x8578,0x8579,0x857a,0x857b,0x857c,0x857d,0x857e,0x857f,
+ 0x8580,0x8581,0x8582,0x8583,0x8584,0x8585,0x8586,0x8587,
+ 0x8588,0x8589,0x858a,0x858b,0x858c,0x858d,0x858e,0x858f,
+ 0x8590,0x8591,0x8592,0x8593,0x8594,0x8595,0x8596,0x8597,
+ 0x8598,0x8599,0x859a,0x859b,0x859c,0x859d,0x859e,0x859f,
+ 0x85a0,0x85a1,0x85a2,0x85a3,0x85a4,0x85a5,0x85a6,0x85a7,
+ 0x85a8,0x85a9,0x85aa,0x85ab,0x85ac,0x85ad,0x85ae,0x85af,
+ 0x85b0,0x85b1,0x85b2,0x85b3,0x85b4,0x85b5,0x85b6,0x85b7,
+ 0x85b8,0x85b9,0x85ba,0x85bb,0x85bc,0x85bd,0x85be,0x85bf,
+ 0x85c0,0x85c1,0x85c2,0x85c3,0x85c4,0x85c5,0x85c6,0x85c7,
+ 0x85c8,0x85c9,0x85ca,0x85cb,0x85cc,0x85cd,0x85ce,0x85cf,
+ 0x85d0,0x85d1,0x85d2,0x85d3,0x85d4,0x85d5,0x85d6,0x85d7,
+ 0x85d8,0x85d9,0x85da,0x85db,0x85dc,0x85dd,0x85de,0x85df,
+ 0x85e0,0x85e1,0x85e2,0x85e3,0x85e4,0x85e5,0x85e6,0x85e7,
+ 0x85e8,0x85e9,0x85ea,0x85eb,0x85ec,0x85ed,0x85ee,0x85ef,
+ 0x85f0,0x85f1,0x85f2,0x85f3,0x85f4,0x85f5,0x85f6,0x85f7,
+ 0x85f8,0x85f9,0x85fa,0x85fb,0x85fc,0x85fd,0x85fe,0x85ff,
+ 0x8600,0x8601,0x8602,0x8603,0x8604,0x8605,0x8606,0x8607,
+ 0x8608,0x8609,0x860a,0x860b,0x860c,0x860d,0x860e,0x860f,
+ 0x8610,0x8611,0x8612,0x8613,0x8614,0x8615,0x8616,0x8617,
+ 0x8618,0x8619,0x861a,0x861b,0x861c,0x861d,0x861e,0x861f,
+ 0x8620,0x8621,0x8622,0x8623,0x8624,0x8625,0x8626,0x8627,
+ 0x8628,0x8629,0x862a,0x862b,0x862c,0x862d,0x862e,0x862f,
+ 0x8630,0x8631,0x8632,0x8633,0x8634,0x8635,0x8636,0x8637,
+ 0x8638,0x8639,0x863a,0x863b,0x863c,0x863d,0x863e,0x863f,
+ 0x8640,0x8641,0x8642,0x8643,0x8644,0x8645,0x8646,0x8647,
+ 0x8648,0x8649,0x864a,0x864b,0x864c,0x864d,0x864e,0x864f,
+ 0x8650,0x8651,0x8652,0x8653,0x8654,0x8655,0x8656,0x8657,
+ 0x8658,0x8659,0x865a,0x865b,0x865c,0x865d,0x865e,0x865f,
+ 0x8660,0x8661,0x8662,0x8663,0x8664,0x8665,0x8666,0x8667,
+ 0x8668,0x8669,0x866a,0x866b,0x866c,0x866d,0x866e,0x866f,
+ 0x8670,0x8671,0x8672,0x8673,0x8674,0x8675,0x8676,0x8677,
+ 0x8678,0x8679,0x867a,0x867b,0x867c,0x867d,0x867e,0x867f,
+ 0x8680,0x8681,0x8682,0x8683,0x8684,0x8685,0x8686,0x8687,
+ 0x8688,0x8689,0x868a,0x868b,0x868c,0x868d,0x868e,0x868f,
+ 0x8690,0x8691,0x8692,0x8693,0x8694,0x8695,0x8696,0x8697,
+ 0x8698,0x8699,0x869a,0x869b,0x869c,0x869d,0x869e,0x869f,
+ 0x86a0,0x86a1,0x86a2,0x86a3,0x86a4,0x86a5,0x86a6,0x86a7,
+ 0x86a8,0x86a9,0x86aa,0x86ab,0x86ac,0x86ad,0x86ae,0x86af,
+ 0x86b0,0x86b1,0x86b2,0x86b3,0x86b4,0x86b5,0x86b6,0x86b7,
+ 0x86b8,0x86b9,0x86ba,0x86bb,0x86bc,0x86bd,0x86be,0x86bf,
+ 0x86c0,0x86c1,0x86c2,0x86c3,0x86c4,0x86c5,0x86c6,0x86c7,
+ 0x86c8,0x86c9,0x86ca,0x86cb,0x86cc,0x86cd,0x86ce,0x86cf,
+ 0x86d0,0x86d1,0x86d2,0x86d3,0x86d4,0x86d5,0x86d6,0x86d7,
+ 0x86d8,0x86d9,0x86da,0x86db,0x86dc,0x86dd,0x86de,0x86df,
+ 0x86e0,0x86e1,0x86e2,0x86e3,0x86e4,0x86e5,0x86e6,0x86e7,
+ 0x86e8,0x86e9,0x86ea,0x86eb,0x86ec,0x86ed,0x86ee,0x86ef,
+ 0x86f0,0x86f1,0x86f2,0x86f3,0x86f4,0x86f5,0x86f6,0x86f7,
+ 0x86f8,0x86f9,0x86fa,0x86fb,0x86fc,0x86fd,0x86fe,0x86ff,
+ 0x8700,0x8701,0x8702,0x8703,0x8704,0x8705,0x8706,0x8707,
+ 0x8708,0x8709,0x870a,0x870b,0x870c,0x870d,0x870e,0x870f,
+ 0x8710,0x8711,0x8712,0x8713,0x8714,0x8715,0x8716,0x8717,
+ 0x8718,0x8719,0x871a,0x871b,0x871c,0x871d,0x871e,0x871f,
+ 0x8720,0x8721,0x8722,0x8723,0x8724,0x8725,0x8726,0x8727,
+ 0x8728,0x8729,0x872a,0x872b,0x872c,0x872d,0x872e,0x872f,
+ 0x8730,0x8731,0x8732,0x8733,0x8734,0x8735,0x8736,0x8737,
+ 0x8738,0x8739,0x873a,0x873b,0x873c,0x873d,0x873e,0x873f,
+ 0x8740,0x8741,0x8742,0x8743,0x8744,0x8745,0x8746,0x8747,
+ 0x8748,0x8749,0x874a,0x874b,0x874c,0x874d,0x874e,0x874f,
+ 0x8750,0x8751,0x8752,0x8753,0x8754,0x8755,0x8756,0x8757,
+ 0x8758,0x8759,0x875a,0x875b,0x875c,0x875d,0x875e,0x875f,
+ 0x8760,0x8761,0x8762,0x8763,0x8764,0x8765,0x8766,0x8767,
+ 0x8768,0x8769,0x876a,0x876b,0x876c,0x876d,0x876e,0x876f,
+ 0x8770,0x8771,0x8772,0x8773,0x8774,0x8775,0x8776,0x8777,
+ 0x8778,0x8779,0x877a,0x877b,0x877c,0x877d,0x877e,0x877f,
+ 0x8780,0x8781,0x8782,0x8783,0x8784,0x8785,0x8786,0x8787,
+ 0x8788,0x8789,0x878a,0x878b,0x878c,0x878d,0x878e,0x878f,
+ 0x8790,0x8791,0x8792,0x8793,0x8794,0x8795,0x8796,0x8797,
+ 0x8798,0x8799,0x879a,0x879b,0x879c,0x879d,0x879e,0x879f,
+ 0x87a0,0x87a1,0x87a2,0x87a3,0x87a4,0x87a5,0x87a6,0x87a7,
+ 0x87a8,0x87a9,0x87aa,0x87ab,0x87ac,0x87ad,0x87ae,0x87af,
+ 0x87b0,0x87b1,0x87b2,0x87b3,0x87b4,0x87b5,0x87b6,0x87b7,
+ 0x87b8,0x87b9,0x87ba,0x87bb,0x87bc,0x87bd,0x87be,0x87bf,
+ 0x87c0,0x87c1,0x87c2,0x87c3,0x87c4,0x87c5,0x87c6,0x87c7,
+ 0x87c8,0x87c9,0x87ca,0x87cb,0x87cc,0x87cd,0x87ce,0x87cf,
+ 0x87d0,0x87d1,0x87d2,0x87d3,0x87d4,0x87d5,0x87d6,0x87d7,
+ 0x87d8,0x87d9,0x87da,0x87db,0x87dc,0x87dd,0x87de,0x87df,
+ 0x87e0,0x87e1,0x87e2,0x87e3,0x87e4,0x87e5,0x87e6,0x87e7,
+ 0x87e8,0x87e9,0x87ea,0x87eb,0x87ec,0x87ed,0x87ee,0x87ef,
+ 0x87f0,0x87f1,0x87f2,0x87f3,0x87f4,0x87f5,0x87f6,0x87f7,
+ 0x87f8,0x87f9,0x87fa,0x87fb,0x87fc,0x87fd,0x87fe,0x87ff,
+ 0x8800,0x8801,0x8802,0x8803,0x8804,0x8805,0x8806,0x8807,
+ 0x8808,0x8809,0x880a,0x880b,0x880c,0x880d,0x880e,0x880f,
+ 0x8810,0x8811,0x8812,0x8813,0x8814,0x8815,0x8816,0x8817,
+ 0x8818,0x8819,0x881a,0x881b,0x881c,0x881d,0x881e,0x881f,
+ 0x8820,0x8821,0x8822,0x8823,0x8824,0x8825,0x8826,0x8827,
+ 0x8828,0x8829,0x882a,0x882b,0x882c,0x882d,0x882e,0x882f,
+ 0x8830,0x8831,0x8832,0x8833,0x8834,0x8835,0x8836,0x8837,
+ 0x8838,0x8839,0x883a,0x883b,0x883c,0x883d,0x883e,0x883f,
+ 0x8840,0x8841,0x8842,0x8843,0x8844,0x8845,0x8846,0x8847,
+ 0x8848,0x8849,0x884a,0x884b,0x884c,0x884d,0x884e,0x884f,
+ 0x8850,0x8851,0x8852,0x8853,0x8854,0x8855,0x8856,0x8857,
+ 0x8858,0x8859,0x885a,0x885b,0x885c,0x885d,0x885e,0x885f,
+ 0x8860,0x8861,0x8862,0x8863,0x8864,0x8865,0x8866,0x8867,
+ 0x8868,0x8869,0x886a,0x886b,0x886c,0x886d,0x886e,0x886f,
+ 0x8870,0x8871,0x8872,0x8873,0x8874,0x8875,0x8876,0x8877,
+ 0x8878,0x8879,0x887a,0x887b,0x887c,0x887d,0x887e,0x887f,
+ 0x8880,0x8881,0x8882,0x8883,0x8884,0x8885,0x8886,0x8887,
+ 0x8888,0x8889,0x888a,0x888b,0x888c,0x888d,0x888e,0x888f,
+ 0x8890,0x8891,0x8892,0x8893,0x8894,0x8895,0x8896,0x8897,
+ 0x8898,0x8899,0x889a,0x889b,0x889c,0x889d,0x889e,0x889f,
+ 0x88a0,0x88a1,0x88a2,0x88a3,0x88a4,0x88a5,0x88a6,0x88a7,
+ 0x88a8,0x88a9,0x88aa,0x88ab,0x88ac,0x88ad,0x88ae,0x88af,
+ 0x88b0,0x88b1,0x88b2,0x88b3,0x88b4,0x88b5,0x88b6,0x88b7,
+ 0x88b8,0x88b9,0x88ba,0x88bb,0x88bc,0x88bd,0x88be,0x88bf,
+ 0x88c0,0x88c1,0x88c2,0x88c3,0x88c4,0x88c5,0x88c6,0x88c7,
+ 0x88c8,0x88c9,0x88ca,0x88cb,0x88cc,0x88cd,0x88ce,0x88cf,
+ 0x88d0,0x88d1,0x88d2,0x88d3,0x88d4,0x88d5,0x88d6,0x88d7,
+ 0x88d8,0x88d9,0x88da,0x88db,0x88dc,0x88dd,0x88de,0x88df,
+ 0x88e0,0x88e1,0x88e2,0x88e3,0x88e4,0x88e5,0x88e6,0x88e7,
+ 0x88e8,0x88e9,0x88ea,0x88eb,0x88ec,0x88ed,0x88ee,0x88ef,
+ 0x88f0,0x88f1,0x88f2,0x88f3,0x88f4,0x88f5,0x88f6,0x88f7,
+ 0x88f8,0x88f9,0x88fa,0x88fb,0x88fc,0x88fd,0x88fe,0x88ff,
+ 0x8900,0x8901,0x8902,0x8903,0x8904,0x8905,0x8906,0x8907,
+ 0x8908,0x8909,0x890a,0x890b,0x890c,0x890d,0x890e,0x890f,
+ 0x8910,0x8911,0x8912,0x8913,0x8914,0x8915,0x8916,0x8917,
+ 0x8918,0x8919,0x891a,0x891b,0x891c,0x891d,0x891e,0x891f,
+ 0x8920,0x8921,0x8922,0x8923,0x8924,0x8925,0x8926,0x8927,
+ 0x8928,0x8929,0x892a,0x892b,0x892c,0x892d,0x892e,0x892f,
+ 0x8930,0x8931,0x8932,0x8933,0x8934,0x8935,0x8936,0x8937,
+ 0x8938,0x8939,0x893a,0x893b,0x893c,0x893d,0x893e,0x893f,
+ 0x8940,0x8941,0x8942,0x8943,0x8944,0x8945,0x8946,0x8947,
+ 0x8948,0x8949,0x894a,0x894b,0x894c,0x894d,0x894e,0x894f,
+ 0x8950,0x8951,0x8952,0x8953,0x8954,0x8955,0x8956,0x8957,
+ 0x8958,0x8959,0x895a,0x895b,0x895c,0x895d,0x895e,0x895f,
+ 0x8960,0x8961,0x8962,0x8963,0x8964,0x8965,0x8966,0x8967,
+ 0x8968,0x8969,0x896a,0x896b,0x896c,0x896d,0x896e,0x896f,
+ 0x8970,0x8971,0x8972,0x8973,0x8974,0x8975,0x8976,0x8977,
+ 0x8978,0x8979,0x897a,0x897b,0x897c,0x897d,0x897e,0x897f,
+ 0x8980,0x8981,0x8982,0x8983,0x8984,0x8985,0x8986,0x8987,
+ 0x8988,0x8989,0x898a,0x898b,0x898c,0x898d,0x898e,0x898f,
+ 0x8990,0x8991,0x8992,0x8993,0x8994,0x8995,0x8996,0x8997,
+ 0x8998,0x8999,0x899a,0x899b,0x899c,0x899d,0x899e,0x899f,
+ 0x89a0,0x89a1,0x89a2,0x89a3,0x89a4,0x89a5,0x89a6,0x89a7,
+ 0x89a8,0x89a9,0x89aa,0x89ab,0x89ac,0x89ad,0x89ae,0x89af,
+ 0x89b0,0x89b1,0x89b2,0x89b3,0x89b4,0x89b5,0x89b6,0x89b7,
+ 0x89b8,0x89b9,0x89ba,0x89bb,0x89bc,0x89bd,0x89be,0x89bf,
+ 0x89c0,0x89c1,0x89c2,0x89c3,0x89c4,0x89c5,0x89c6,0x89c7,
+ 0x89c8,0x89c9,0x89ca,0x89cb,0x89cc,0x89cd,0x89ce,0x89cf,
+ 0x89d0,0x89d1,0x89d2,0x89d3,0x89d4,0x89d5,0x89d6,0x89d7,
+ 0x89d8,0x89d9,0x89da,0x89db,0x89dc,0x89dd,0x89de,0x89df,
+ 0x89e0,0x89e1,0x89e2,0x89e3,0x89e4,0x89e5,0x89e6,0x89e7,
+ 0x89e8,0x89e9,0x89ea,0x89eb,0x89ec,0x89ed,0x89ee,0x89ef,
+ 0x89f0,0x89f1,0x89f2,0x89f3,0x89f4,0x89f5,0x89f6,0x89f7,
+ 0x89f8,0x89f9,0x89fa,0x89fb,0x89fc,0x89fd,0x89fe,0x89ff,
+ 0x8a00,0x8a01,0x8a02,0x8a03,0x8a04,0x8a05,0x8a06,0x8a07,
+ 0x8a08,0x8a09,0x8a0a,0x8a0b,0x8a0c,0x8a0d,0x8a0e,0x8a0f,
+ 0x8a10,0x8a11,0x8a12,0x8a13,0x8a14,0x8a15,0x8a16,0x8a17,
+ 0x8a18,0x8a19,0x8a1a,0x8a1b,0x8a1c,0x8a1d,0x8a1e,0x8a1f,
+ 0x8a20,0x8a21,0x8a22,0x8a23,0x8a24,0x8a25,0x8a26,0x8a27,
+ 0x8a28,0x8a29,0x8a2a,0x8a2b,0x8a2c,0x8a2d,0x8a2e,0x8a2f,
+ 0x8a30,0x8a31,0x8a32,0x8a33,0x8a34,0x8a35,0x8a36,0x8a37,
+ 0x8a38,0x8a39,0x8a3a,0x8a3b,0x8a3c,0x8a3d,0x8a3e,0x8a3f,
+ 0x8a40,0x8a41,0x8a42,0x8a43,0x8a44,0x8a45,0x8a46,0x8a47,
+ 0x8a48,0x8a49,0x8a4a,0x8a4b,0x8a4c,0x8a4d,0x8a4e,0x8a4f,
+ 0x8a50,0x8a51,0x8a52,0x8a53,0x8a54,0x8a55,0x8a56,0x8a57,
+ 0x8a58,0x8a59,0x8a5a,0x8a5b,0x8a5c,0x8a5d,0x8a5e,0x8a5f,
+ 0x8a60,0x8a61,0x8a62,0x8a63,0x8a64,0x8a65,0x8a66,0x8a67,
+ 0x8a68,0x8a69,0x8a6a,0x8a6b,0x8a6c,0x8a6d,0x8a6e,0x8a6f,
+ 0x8a70,0x8a71,0x8a72,0x8a73,0x8a74,0x8a75,0x8a76,0x8a77,
+ 0x8a78,0x8a79,0x8a7a,0x8a7b,0x8a7c,0x8a7d,0x8a7e,0x8a7f,
+ 0x8a80,0x8a81,0x8a82,0x8a83,0x8a84,0x8a85,0x8a86,0x8a87,
+ 0x8a88,0x8a89,0x8a8a,0x8a8b,0x8a8c,0x8a8d,0x8a8e,0x8a8f,
+ 0x8a90,0x8a91,0x8a92,0x8a93,0x8a94,0x8a95,0x8a96,0x8a97,
+ 0x8a98,0x8a99,0x8a9a,0x8a9b,0x8a9c,0x8a9d,0x8a9e,0x8a9f,
+ 0x8aa0,0x8aa1,0x8aa2,0x8aa3,0x8aa4,0x8aa5,0x8aa6,0x8aa7,
+ 0x8aa8,0x8aa9,0x8aaa,0x8aab,0x8aac,0x8aad,0x8aae,0x8aaf,
+ 0x8ab0,0x8ab1,0x8ab2,0x8ab3,0x8ab4,0x8ab5,0x8ab6,0x8ab7,
+ 0x8ab8,0x8ab9,0x8aba,0x8abb,0x8abc,0x8abd,0x8abe,0x8abf,
+ 0x8ac0,0x8ac1,0x8ac2,0x8ac3,0x8ac4,0x8ac5,0x8ac6,0x8ac7,
+ 0x8ac8,0x8ac9,0x8aca,0x8acb,0x8acc,0x8acd,0x8ace,0x8acf,
+ 0x8ad0,0x8ad1,0x8ad2,0x8ad3,0x8ad4,0x8ad5,0x8ad6,0x8ad7,
+ 0x8ad8,0x8ad9,0x8ada,0x8adb,0x8adc,0x8add,0x8ade,0x8adf,
+ 0x8ae0,0x8ae1,0x8ae2,0x8ae3,0x8ae4,0x8ae5,0x8ae6,0x8ae7,
+ 0x8ae8,0x8ae9,0x8aea,0x8aeb,0x8aec,0x8aed,0x8aee,0x8aef,
+ 0x8af0,0x8af1,0x8af2,0x8af3,0x8af4,0x8af5,0x8af6,0x8af7,
+ 0x8af8,0x8af9,0x8afa,0x8afb,0x8afc,0x8afd,0x8afe,0x8aff,
+ 0x8b00,0x8b01,0x8b02,0x8b03,0x8b04,0x8b05,0x8b06,0x8b07,
+ 0x8b08,0x8b09,0x8b0a,0x8b0b,0x8b0c,0x8b0d,0x8b0e,0x8b0f,
+ 0x8b10,0x8b11,0x8b12,0x8b13,0x8b14,0x8b15,0x8b16,0x8b17,
+ 0x8b18,0x8b19,0x8b1a,0x8b1b,0x8b1c,0x8b1d,0x8b1e,0x8b1f,
+ 0x8b20,0x8b21,0x8b22,0x8b23,0x8b24,0x8b25,0x8b26,0x8b27,
+ 0x8b28,0x8b29,0x8b2a,0x8b2b,0x8b2c,0x8b2d,0x8b2e,0x8b2f,
+ 0x8b30,0x8b31,0x8b32,0x8b33,0x8b34,0x8b35,0x8b36,0x8b37,
+ 0x8b38,0x8b39,0x8b3a,0x8b3b,0x8b3c,0x8b3d,0x8b3e,0x8b3f,
+ 0x8b40,0x8b41,0x8b42,0x8b43,0x8b44,0x8b45,0x8b46,0x8b47,
+ 0x8b48,0x8b49,0x8b4a,0x8b4b,0x8b4c,0x8b4d,0x8b4e,0x8b4f,
+ 0x8b50,0x8b51,0x8b52,0x8b53,0x8b54,0x8b55,0x8b56,0x8b57,
+ 0x8b58,0x8b59,0x8b5a,0x8b5b,0x8b5c,0x8b5d,0x8b5e,0x8b5f,
+ 0x8b60,0x8b61,0x8b62,0x8b63,0x8b64,0x8b65,0x8b66,0x8b67,
+ 0x8b68,0x8b69,0x8b6a,0x8b6b,0x8b6c,0x8b6d,0x8b6e,0x8b6f,
+ 0x8b70,0x8b71,0x8b72,0x8b73,0x8b74,0x8b75,0x8b76,0x8b77,
+ 0x8b78,0x8b79,0x8b7a,0x8b7b,0x8b7c,0x8b7d,0x8b7e,0x8b7f,
+ 0x8b80,0x8b81,0x8b82,0x8b83,0x8b84,0x8b85,0x8b86,0x8b87,
+ 0x8b88,0x8b89,0x8b8a,0x8b8b,0x8b8c,0x8b8d,0x8b8e,0x8b8f,
+ 0x8b90,0x8b91,0x8b92,0x8b93,0x8b94,0x8b95,0x8b96,0x8b97,
+ 0x8b98,0x8b99,0x8b9a,0x8b9b,0x8b9c,0x8b9d,0x8b9e,0x8b9f,
+ 0x8ba0,0x8ba1,0x8ba2,0x8ba3,0x8ba4,0x8ba5,0x8ba6,0x8ba7,
+ 0x8ba8,0x8ba9,0x8baa,0x8bab,0x8bac,0x8bad,0x8bae,0x8baf,
+ 0x8bb0,0x8bb1,0x8bb2,0x8bb3,0x8bb4,0x8bb5,0x8bb6,0x8bb7,
+ 0x8bb8,0x8bb9,0x8bba,0x8bbb,0x8bbc,0x8bbd,0x8bbe,0x8bbf,
+ 0x8bc0,0x8bc1,0x8bc2,0x8bc3,0x8bc4,0x8bc5,0x8bc6,0x8bc7,
+ 0x8bc8,0x8bc9,0x8bca,0x8bcb,0x8bcc,0x8bcd,0x8bce,0x8bcf,
+ 0x8bd0,0x8bd1,0x8bd2,0x8bd3,0x8bd4,0x8bd5,0x8bd6,0x8bd7,
+ 0x8bd8,0x8bd9,0x8bda,0x8bdb,0x8bdc,0x8bdd,0x8bde,0x8bdf,
+ 0x8be0,0x8be1,0x8be2,0x8be3,0x8be4,0x8be5,0x8be6,0x8be7,
+ 0x8be8,0x8be9,0x8bea,0x8beb,0x8bec,0x8bed,0x8bee,0x8bef,
+ 0x8bf0,0x8bf1,0x8bf2,0x8bf3,0x8bf4,0x8bf5,0x8bf6,0x8bf7,
+ 0x8bf8,0x8bf9,0x8bfa,0x8bfb,0x8bfc,0x8bfd,0x8bfe,0x8bff,
+ 0x8c00,0x8c01,0x8c02,0x8c03,0x8c04,0x8c05,0x8c06,0x8c07,
+ 0x8c08,0x8c09,0x8c0a,0x8c0b,0x8c0c,0x8c0d,0x8c0e,0x8c0f,
+ 0x8c10,0x8c11,0x8c12,0x8c13,0x8c14,0x8c15,0x8c16,0x8c17,
+ 0x8c18,0x8c19,0x8c1a,0x8c1b,0x8c1c,0x8c1d,0x8c1e,0x8c1f,
+ 0x8c20,0x8c21,0x8c22,0x8c23,0x8c24,0x8c25,0x8c26,0x8c27,
+ 0x8c28,0x8c29,0x8c2a,0x8c2b,0x8c2c,0x8c2d,0x8c2e,0x8c2f,
+ 0x8c30,0x8c31,0x8c32,0x8c33,0x8c34,0x8c35,0x8c36,0x8c37,
+ 0x8c38,0x8c39,0x8c3a,0x8c3b,0x8c3c,0x8c3d,0x8c3e,0x8c3f,
+ 0x8c40,0x8c41,0x8c42,0x8c43,0x8c44,0x8c45,0x8c46,0x8c47,
+ 0x8c48,0x8c49,0x8c4a,0x8c4b,0x8c4c,0x8c4d,0x8c4e,0x8c4f,
+ 0x8c50,0x8c51,0x8c52,0x8c53,0x8c54,0x8c55,0x8c56,0x8c57,
+ 0x8c58,0x8c59,0x8c5a,0x8c5b,0x8c5c,0x8c5d,0x8c5e,0x8c5f,
+ 0x8c60,0x8c61,0x8c62,0x8c63,0x8c64,0x8c65,0x8c66,0x8c67,
+ 0x8c68,0x8c69,0x8c6a,0x8c6b,0x8c6c,0x8c6d,0x8c6e,0x8c6f,
+ 0x8c70,0x8c71,0x8c72,0x8c73,0x8c74,0x8c75,0x8c76,0x8c77,
+ 0x8c78,0x8c79,0x8c7a,0x8c7b,0x8c7c,0x8c7d,0x8c7e,0x8c7f,
+ 0x8c80,0x8c81,0x8c82,0x8c83,0x8c84,0x8c85,0x8c86,0x8c87,
+ 0x8c88,0x8c89,0x8c8a,0x8c8b,0x8c8c,0x8c8d,0x8c8e,0x8c8f,
+ 0x8c90,0x8c91,0x8c92,0x8c93,0x8c94,0x8c95,0x8c96,0x8c97,
+ 0x8c98,0x8c99,0x8c9a,0x8c9b,0x8c9c,0x8c9d,0x8c9e,0x8c9f,
+ 0x8ca0,0x8ca1,0x8ca2,0x8ca3,0x8ca4,0x8ca5,0x8ca6,0x8ca7,
+ 0x8ca8,0x8ca9,0x8caa,0x8cab,0x8cac,0x8cad,0x8cae,0x8caf,
+ 0x8cb0,0x8cb1,0x8cb2,0x8cb3,0x8cb4,0x8cb5,0x8cb6,0x8cb7,
+ 0x8cb8,0x8cb9,0x8cba,0x8cbb,0x8cbc,0x8cbd,0x8cbe,0x8cbf,
+ 0x8cc0,0x8cc1,0x8cc2,0x8cc3,0x8cc4,0x8cc5,0x8cc6,0x8cc7,
+ 0x8cc8,0x8cc9,0x8cca,0x8ccb,0x8ccc,0x8ccd,0x8cce,0x8ccf,
+ 0x8cd0,0x8cd1,0x8cd2,0x8cd3,0x8cd4,0x8cd5,0x8cd6,0x8cd7,
+ 0x8cd8,0x8cd9,0x8cda,0x8cdb,0x8cdc,0x8cdd,0x8cde,0x8cdf,
+ 0x8ce0,0x8ce1,0x8ce2,0x8ce3,0x8ce4,0x8ce5,0x8ce6,0x8ce7,
+ 0x8ce8,0x8ce9,0x8cea,0x8ceb,0x8cec,0x8ced,0x8cee,0x8cef,
+ 0x8cf0,0x8cf1,0x8cf2,0x8cf3,0x8cf4,0x8cf5,0x8cf6,0x8cf7,
+ 0x8cf8,0x8cf9,0x8cfa,0x8cfb,0x8cfc,0x8cfd,0x8cfe,0x8cff,
+ 0x8d00,0x8d01,0x8d02,0x8d03,0x8d04,0x8d05,0x8d06,0x8d07,
+ 0x8d08,0x8d09,0x8d0a,0x8d0b,0x8d0c,0x8d0d,0x8d0e,0x8d0f,
+ 0x8d10,0x8d11,0x8d12,0x8d13,0x8d14,0x8d15,0x8d16,0x8d17,
+ 0x8d18,0x8d19,0x8d1a,0x8d1b,0x8d1c,0x8d1d,0x8d1e,0x8d1f,
+ 0x8d20,0x8d21,0x8d22,0x8d23,0x8d24,0x8d25,0x8d26,0x8d27,
+ 0x8d28,0x8d29,0x8d2a,0x8d2b,0x8d2c,0x8d2d,0x8d2e,0x8d2f,
+ 0x8d30,0x8d31,0x8d32,0x8d33,0x8d34,0x8d35,0x8d36,0x8d37,
+ 0x8d38,0x8d39,0x8d3a,0x8d3b,0x8d3c,0x8d3d,0x8d3e,0x8d3f,
+ 0x8d40,0x8d41,0x8d42,0x8d43,0x8d44,0x8d45,0x8d46,0x8d47,
+ 0x8d48,0x8d49,0x8d4a,0x8d4b,0x8d4c,0x8d4d,0x8d4e,0x8d4f,
+ 0x8d50,0x8d51,0x8d52,0x8d53,0x8d54,0x8d55,0x8d56,0x8d57,
+ 0x8d58,0x8d59,0x8d5a,0x8d5b,0x8d5c,0x8d5d,0x8d5e,0x8d5f,
+ 0x8d60,0x8d61,0x8d62,0x8d63,0x8d64,0x8d65,0x8d66,0x8d67,
+ 0x8d68,0x8d69,0x8d6a,0x8d6b,0x8d6c,0x8d6d,0x8d6e,0x8d6f,
+ 0x8d70,0x8d71,0x8d72,0x8d73,0x8d74,0x8d75,0x8d76,0x8d77,
+ 0x8d78,0x8d79,0x8d7a,0x8d7b,0x8d7c,0x8d7d,0x8d7e,0x8d7f,
+ 0x8d80,0x8d81,0x8d82,0x8d83,0x8d84,0x8d85,0x8d86,0x8d87,
+ 0x8d88,0x8d89,0x8d8a,0x8d8b,0x8d8c,0x8d8d,0x8d8e,0x8d8f,
+ 0x8d90,0x8d91,0x8d92,0x8d93,0x8d94,0x8d95,0x8d96,0x8d97,
+ 0x8d98,0x8d99,0x8d9a,0x8d9b,0x8d9c,0x8d9d,0x8d9e,0x8d9f,
+ 0x8da0,0x8da1,0x8da2,0x8da3,0x8da4,0x8da5,0x8da6,0x8da7,
+ 0x8da8,0x8da9,0x8daa,0x8dab,0x8dac,0x8dad,0x8dae,0x8daf,
+ 0x8db0,0x8db1,0x8db2,0x8db3,0x8db4,0x8db5,0x8db6,0x8db7,
+ 0x8db8,0x8db9,0x8dba,0x8dbb,0x8dbc,0x8dbd,0x8dbe,0x8dbf,
+ 0x8dc0,0x8dc1,0x8dc2,0x8dc3,0x8dc4,0x8dc5,0x8dc6,0x8dc7,
+ 0x8dc8,0x8dc9,0x8dca,0x8dcb,0x8dcc,0x8dcd,0x8dce,0x8dcf,
+ 0x8dd0,0x8dd1,0x8dd2,0x8dd3,0x8dd4,0x8dd5,0x8dd6,0x8dd7,
+ 0x8dd8,0x8dd9,0x8dda,0x8ddb,0x8ddc,0x8ddd,0x8dde,0x8ddf,
+ 0x8de0,0x8de1,0x8de2,0x8de3,0x8de4,0x8de5,0x8de6,0x8de7,
+ 0x8de8,0x8de9,0x8dea,0x8deb,0x8dec,0x8ded,0x8dee,0x8def,
+ 0x8df0,0x8df1,0x8df2,0x8df3,0x8df4,0x8df5,0x8df6,0x8df7,
+ 0x8df8,0x8df9,0x8dfa,0x8dfb,0x8dfc,0x8dfd,0x8dfe,0x8dff,
+ 0x8e00,0x8e01,0x8e02,0x8e03,0x8e04,0x8e05,0x8e06,0x8e07,
+ 0x8e08,0x8e09,0x8e0a,0x8e0b,0x8e0c,0x8e0d,0x8e0e,0x8e0f,
+ 0x8e10,0x8e11,0x8e12,0x8e13,0x8e14,0x8e15,0x8e16,0x8e17,
+ 0x8e18,0x8e19,0x8e1a,0x8e1b,0x8e1c,0x8e1d,0x8e1e,0x8e1f,
+ 0x8e20,0x8e21,0x8e22,0x8e23,0x8e24,0x8e25,0x8e26,0x8e27,
+ 0x8e28,0x8e29,0x8e2a,0x8e2b,0x8e2c,0x8e2d,0x8e2e,0x8e2f,
+ 0x8e30,0x8e31,0x8e32,0x8e33,0x8e34,0x8e35,0x8e36,0x8e37,
+ 0x8e38,0x8e39,0x8e3a,0x8e3b,0x8e3c,0x8e3d,0x8e3e,0x8e3f,
+ 0x8e40,0x8e41,0x8e42,0x8e43,0x8e44,0x8e45,0x8e46,0x8e47,
+ 0x8e48,0x8e49,0x8e4a,0x8e4b,0x8e4c,0x8e4d,0x8e4e,0x8e4f,
+ 0x8e50,0x8e51,0x8e52,0x8e53,0x8e54,0x8e55,0x8e56,0x8e57,
+ 0x8e58,0x8e59,0x8e5a,0x8e5b,0x8e5c,0x8e5d,0x8e5e,0x8e5f,
+ 0x8e60,0x8e61,0x8e62,0x8e63,0x8e64,0x8e65,0x8e66,0x8e67,
+ 0x8e68,0x8e69,0x8e6a,0x8e6b,0x8e6c,0x8e6d,0x8e6e,0x8e6f,
+ 0x8e70,0x8e71,0x8e72,0x8e73,0x8e74,0x8e75,0x8e76,0x8e77,
+ 0x8e78,0x8e79,0x8e7a,0x8e7b,0x8e7c,0x8e7d,0x8e7e,0x8e7f,
+ 0x8e80,0x8e81,0x8e82,0x8e83,0x8e84,0x8e85,0x8e86,0x8e87,
+ 0x8e88,0x8e89,0x8e8a,0x8e8b,0x8e8c,0x8e8d,0x8e8e,0x8e8f,
+ 0x8e90,0x8e91,0x8e92,0x8e93,0x8e94,0x8e95,0x8e96,0x8e97,
+ 0x8e98,0x8e99,0x8e9a,0x8e9b,0x8e9c,0x8e9d,0x8e9e,0x8e9f,
+ 0x8ea0,0x8ea1,0x8ea2,0x8ea3,0x8ea4,0x8ea5,0x8ea6,0x8ea7,
+ 0x8ea8,0x8ea9,0x8eaa,0x8eab,0x8eac,0x8ead,0x8eae,0x8eaf,
+ 0x8eb0,0x8eb1,0x8eb2,0x8eb3,0x8eb4,0x8eb5,0x8eb6,0x8eb7,
+ 0x8eb8,0x8eb9,0x8eba,0x8ebb,0x8ebc,0x8ebd,0x8ebe,0x8ebf,
+ 0x8ec0,0x8ec1,0x8ec2,0x8ec3,0x8ec4,0x8ec5,0x8ec6,0x8ec7,
+ 0x8ec8,0x8ec9,0x8eca,0x8ecb,0x8ecc,0x8ecd,0x8ece,0x8ecf,
+ 0x8ed0,0x8ed1,0x8ed2,0x8ed3,0x8ed4,0x8ed5,0x8ed6,0x8ed7,
+ 0x8ed8,0x8ed9,0x8eda,0x8edb,0x8edc,0x8edd,0x8ede,0x8edf,
+ 0x8ee0,0x8ee1,0x8ee2,0x8ee3,0x8ee4,0x8ee5,0x8ee6,0x8ee7,
+ 0x8ee8,0x8ee9,0x8eea,0x8eeb,0x8eec,0x8eed,0x8eee,0x8eef,
+ 0x8ef0,0x8ef1,0x8ef2,0x8ef3,0x8ef4,0x8ef5,0x8ef6,0x8ef7,
+ 0x8ef8,0x8ef9,0x8efa,0x8efb,0x8efc,0x8efd,0x8efe,0x8eff,
+ 0x8f00,0x8f01,0x8f02,0x8f03,0x8f04,0x8f05,0x8f06,0x8f07,
+ 0x8f08,0x8f09,0x8f0a,0x8f0b,0x8f0c,0x8f0d,0x8f0e,0x8f0f,
+ 0x8f10,0x8f11,0x8f12,0x8f13,0x8f14,0x8f15,0x8f16,0x8f17,
+ 0x8f18,0x8f19,0x8f1a,0x8f1b,0x8f1c,0x8f1d,0x8f1e,0x8f1f,
+ 0x8f20,0x8f21,0x8f22,0x8f23,0x8f24,0x8f25,0x8f26,0x8f27,
+ 0x8f28,0x8f29,0x8f2a,0x8f2b,0x8f2c,0x8f2d,0x8f2e,0x8f2f,
+ 0x8f30,0x8f31,0x8f32,0x8f33,0x8f34,0x8f35,0x8f36,0x8f37,
+ 0x8f38,0x8f39,0x8f3a,0x8f3b,0x8f3c,0x8f3d,0x8f3e,0x8f3f,
+ 0x8f40,0x8f41,0x8f42,0x8f43,0x8f44,0x8f45,0x8f46,0x8f47,
+ 0x8f48,0x8f49,0x8f4a,0x8f4b,0x8f4c,0x8f4d,0x8f4e,0x8f4f,
+ 0x8f50,0x8f51,0x8f52,0x8f53,0x8f54,0x8f55,0x8f56,0x8f57,
+ 0x8f58,0x8f59,0x8f5a,0x8f5b,0x8f5c,0x8f5d,0x8f5e,0x8f5f,
+ 0x8f60,0x8f61,0x8f62,0x8f63,0x8f64,0x8f65,0x8f66,0x8f67,
+ 0x8f68,0x8f69,0x8f6a,0x8f6b,0x8f6c,0x8f6d,0x8f6e,0x8f6f,
+ 0x8f70,0x8f71,0x8f72,0x8f73,0x8f74,0x8f75,0x8f76,0x8f77,
+ 0x8f78,0x8f79,0x8f7a,0x8f7b,0x8f7c,0x8f7d,0x8f7e,0x8f7f,
+ 0x8f80,0x8f81,0x8f82,0x8f83,0x8f84,0x8f85,0x8f86,0x8f87,
+ 0x8f88,0x8f89,0x8f8a,0x8f8b,0x8f8c,0x8f8d,0x8f8e,0x8f8f,
+ 0x8f90,0x8f91,0x8f92,0x8f93,0x8f94,0x8f95,0x8f96,0x8f97,
+ 0x8f98,0x8f99,0x8f9a,0x8f9b,0x8f9c,0x8f9d,0x8f9e,0x8f9f,
+ 0x8fa0,0x8fa1,0x8fa2,0x8fa3,0x8fa4,0x8fa5,0x8fa6,0x8fa7,
+ 0x8fa8,0x8fa9,0x8faa,0x8fab,0x8fac,0x8fad,0x8fae,0x8faf,
+ 0x8fb0,0x8fb1,0x8fb2,0x8fb3,0x8fb4,0x8fb5,0x8fb6,0x8fb7,
+ 0x8fb8,0x8fb9,0x8fba,0x8fbb,0x8fbc,0x8fbd,0x8fbe,0x8fbf,
+ 0x8fc0,0x8fc1,0x8fc2,0x8fc3,0x8fc4,0x8fc5,0x8fc6,0x8fc7,
+ 0x8fc8,0x8fc9,0x8fca,0x8fcb,0x8fcc,0x8fcd,0x8fce,0x8fcf,
+ 0x8fd0,0x8fd1,0x8fd2,0x8fd3,0x8fd4,0x8fd5,0x8fd6,0x8fd7,
+ 0x8fd8,0x8fd9,0x8fda,0x8fdb,0x8fdc,0x8fdd,0x8fde,0x8fdf,
+ 0x8fe0,0x8fe1,0x8fe2,0x8fe3,0x8fe4,0x8fe5,0x8fe6,0x8fe7,
+ 0x8fe8,0x8fe9,0x8fea,0x8feb,0x8fec,0x8fed,0x8fee,0x8fef,
+ 0x8ff0,0x8ff1,0x8ff2,0x8ff3,0x8ff4,0x8ff5,0x8ff6,0x8ff7,
+ 0x8ff8,0x8ff9,0x8ffa,0x8ffb,0x8ffc,0x8ffd,0x8ffe,0x8fff,
+ 0x9000,0x9001,0x9002,0x9003,0x9004,0x9005,0x9006,0x9007,
+ 0x9008,0x9009,0x900a,0x900b,0x900c,0x900d,0x900e,0x900f,
+ 0x9010,0x9011,0x9012,0x9013,0x9014,0x9015,0x9016,0x9017,
+ 0x9018,0x9019,0x901a,0x901b,0x901c,0x901d,0x901e,0x901f,
+ 0x9020,0x9021,0x9022,0x9023,0x9024,0x9025,0x9026,0x9027,
+ 0x9028,0x9029,0x902a,0x902b,0x902c,0x902d,0x902e,0x902f,
+ 0x9030,0x9031,0x9032,0x9033,0x9034,0x9035,0x9036,0x9037,
+ 0x9038,0x9039,0x903a,0x903b,0x903c,0x903d,0x903e,0x903f,
+ 0x9040,0x9041,0x9042,0x9043,0x9044,0x9045,0x9046,0x9047,
+ 0x9048,0x9049,0x904a,0x904b,0x904c,0x904d,0x904e,0x904f,
+ 0x9050,0x9051,0x9052,0x9053,0x9054,0x9055,0x9056,0x9057,
+ 0x9058,0x9059,0x905a,0x905b,0x905c,0x905d,0x905e,0x905f,
+ 0x9060,0x9061,0x9062,0x9063,0x9064,0x9065,0x9066,0x9067,
+ 0x9068,0x9069,0x906a,0x906b,0x906c,0x906d,0x906e,0x906f,
+ 0x9070,0x9071,0x9072,0x9073,0x9074,0x9075,0x9076,0x9077,
+ 0x9078,0x9079,0x907a,0x907b,0x907c,0x907d,0x907e,0x907f,
+ 0x9080,0x9081,0x9082,0x9083,0x9084,0x9085,0x9086,0x9087,
+ 0x9088,0x9089,0x908a,0x908b,0x908c,0x908d,0x908e,0x908f,
+ 0x9090,0x9091,0x9092,0x9093,0x9094,0x9095,0x9096,0x9097,
+ 0x9098,0x9099,0x909a,0x909b,0x909c,0x909d,0x909e,0x909f,
+ 0x90a0,0x90a1,0x90a2,0x90a3,0x90a4,0x90a5,0x90a6,0x90a7,
+ 0x90a8,0x90a9,0x90aa,0x90ab,0x90ac,0x90ad,0x90ae,0x90af,
+ 0x90b0,0x90b1,0x90b2,0x90b3,0x90b4,0x90b5,0x90b6,0x90b7,
+ 0x90b8,0x90b9,0x90ba,0x90bb,0x90bc,0x90bd,0x90be,0x90bf,
+ 0x90c0,0x90c1,0x90c2,0x90c3,0x90c4,0x90c5,0x90c6,0x90c7,
+ 0x90c8,0x90c9,0x90ca,0x90cb,0x90cc,0x90cd,0x90ce,0x90cf,
+ 0x90d0,0x90d1,0x90d2,0x90d3,0x90d4,0x90d5,0x90d6,0x90d7,
+ 0x90d8,0x90d9,0x90da,0x90db,0x90dc,0x90dd,0x90de,0x90df,
+ 0x90e0,0x90e1,0x90e2,0x90e3,0x90e4,0x90e5,0x90e6,0x90e7,
+ 0x90e8,0x90e9,0x90ea,0x90eb,0x90ec,0x90ed,0x90ee,0x90ef,
+ 0x90f0,0x90f1,0x90f2,0x90f3,0x90f4,0x90f5,0x90f6,0x90f7,
+ 0x90f8,0x90f9,0x90fa,0x90fb,0x90fc,0x90fd,0x90fe,0x90ff,
+ 0x9100,0x9101,0x9102,0x9103,0x9104,0x9105,0x9106,0x9107,
+ 0x9108,0x9109,0x910a,0x910b,0x910c,0x910d,0x910e,0x910f,
+ 0x9110,0x9111,0x9112,0x9113,0x9114,0x9115,0x9116,0x9117,
+ 0x9118,0x9119,0x911a,0x911b,0x911c,0x911d,0x911e,0x911f,
+ 0x9120,0x9121,0x9122,0x9123,0x9124,0x9125,0x9126,0x9127,
+ 0x9128,0x9129,0x912a,0x912b,0x912c,0x912d,0x912e,0x912f,
+ 0x9130,0x9131,0x9132,0x9133,0x9134,0x9135,0x9136,0x9137,
+ 0x9138,0x9139,0x913a,0x913b,0x913c,0x913d,0x913e,0x913f,
+ 0x9140,0x9141,0x9142,0x9143,0x9144,0x9145,0x9146,0x9147,
+ 0x9148,0x9149,0x914a,0x914b,0x914c,0x914d,0x914e,0x914f,
+ 0x9150,0x9151,0x9152,0x9153,0x9154,0x9155,0x9156,0x9157,
+ 0x9158,0x9159,0x915a,0x915b,0x915c,0x915d,0x915e,0x915f,
+ 0x9160,0x9161,0x9162,0x9163,0x9164,0x9165,0x9166,0x9167,
+ 0x9168,0x9169,0x916a,0x916b,0x916c,0x916d,0x916e,0x916f,
+ 0x9170,0x9171,0x9172,0x9173,0x9174,0x9175,0x9176,0x9177,
+ 0x9178,0x9179,0x917a,0x917b,0x917c,0x917d,0x917e,0x917f,
+ 0x9180,0x9181,0x9182,0x9183,0x9184,0x9185,0x9186,0x9187,
+ 0x9188,0x9189,0x918a,0x918b,0x918c,0x918d,0x918e,0x918f,
+ 0x9190,0x9191,0x9192,0x9193,0x9194,0x9195,0x9196,0x9197,
+ 0x9198,0x9199,0x919a,0x919b,0x919c,0x919d,0x919e,0x919f,
+ 0x91a0,0x91a1,0x91a2,0x91a3,0x91a4,0x91a5,0x91a6,0x91a7,
+ 0x91a8,0x91a9,0x91aa,0x91ab,0x91ac,0x91ad,0x91ae,0x91af,
+ 0x91b0,0x91b1,0x91b2,0x91b3,0x91b4,0x91b5,0x91b6,0x91b7,
+ 0x91b8,0x91b9,0x91ba,0x91bb,0x91bc,0x91bd,0x91be,0x91bf,
+ 0x91c0,0x91c1,0x91c2,0x91c3,0x91c4,0x91c5,0x91c6,0x91c7,
+ 0x91c8,0x91c9,0x91ca,0x91cb,0x91cc,0x91cd,0x91ce,0x91cf,
+ 0x91d0,0x91d1,0x91d2,0x91d3,0x91d4,0x91d5,0x91d6,0x91d7,
+ 0x91d8,0x91d9,0x91da,0x91db,0x91dc,0x91dd,0x91de,0x91df,
+ 0x91e0,0x91e1,0x91e2,0x91e3,0x91e4,0x91e5,0x91e6,0x91e7,
+ 0x91e8,0x91e9,0x91ea,0x91eb,0x91ec,0x91ed,0x91ee,0x91ef,
+ 0x91f0,0x91f1,0x91f2,0x91f3,0x91f4,0x91f5,0x91f6,0x91f7,
+ 0x91f8,0x91f9,0x91fa,0x91fb,0x91fc,0x91fd,0x91fe,0x91ff,
+ 0x9200,0x9201,0x9202,0x9203,0x9204,0x9205,0x9206,0x9207,
+ 0x9208,0x9209,0x920a,0x920b,0x920c,0x920d,0x920e,0x920f,
+ 0x9210,0x9211,0x9212,0x9213,0x9214,0x9215,0x9216,0x9217,
+ 0x9218,0x9219,0x921a,0x921b,0x921c,0x921d,0x921e,0x921f,
+ 0x9220,0x9221,0x9222,0x9223,0x9224,0x9225,0x9226,0x9227,
+ 0x9228,0x9229,0x922a,0x922b,0x922c,0x922d,0x922e,0x922f,
+ 0x9230,0x9231,0x9232,0x9233,0x9234,0x9235,0x9236,0x9237,
+ 0x9238,0x9239,0x923a,0x923b,0x923c,0x923d,0x923e,0x923f,
+ 0x9240,0x9241,0x9242,0x9243,0x9244,0x9245,0x9246,0x9247,
+ 0x9248,0x9249,0x924a,0x924b,0x924c,0x924d,0x924e,0x924f,
+ 0x9250,0x9251,0x9252,0x9253,0x9254,0x9255,0x9256,0x9257,
+ 0x9258,0x9259,0x925a,0x925b,0x925c,0x925d,0x925e,0x925f,
+ 0x9260,0x9261,0x9262,0x9263,0x9264,0x9265,0x9266,0x9267,
+ 0x9268,0x9269,0x926a,0x926b,0x926c,0x926d,0x926e,0x926f,
+ 0x9270,0x9271,0x9272,0x9273,0x9274,0x9275,0x9276,0x9277,
+ 0x9278,0x9279,0x927a,0x927b,0x927c,0x927d,0x927e,0x927f,
+ 0x9280,0x9281,0x9282,0x9283,0x9284,0x9285,0x9286,0x9287,
+ 0x9288,0x9289,0x928a,0x928b,0x928c,0x928d,0x928e,0x928f,
+ 0x9290,0x9291,0x9292,0x9293,0x9294,0x9295,0x9296,0x9297,
+ 0x9298,0x9299,0x929a,0x929b,0x929c,0x929d,0x929e,0x929f,
+ 0x92a0,0x92a1,0x92a2,0x92a3,0x92a4,0x92a5,0x92a6,0x92a7,
+ 0x92a8,0x92a9,0x92aa,0x92ab,0x92ac,0x92ad,0x92ae,0x92af,
+ 0x92b0,0x92b1,0x92b2,0x92b3,0x92b4,0x92b5,0x92b6,0x92b7,
+ 0x92b8,0x92b9,0x92ba,0x92bb,0x92bc,0x92bd,0x92be,0x92bf,
+ 0x92c0,0x92c1,0x92c2,0x92c3,0x92c4,0x92c5,0x92c6,0x92c7,
+ 0x92c8,0x92c9,0x92ca,0x92cb,0x92cc,0x92cd,0x92ce,0x92cf,
+ 0x92d0,0x92d1,0x92d2,0x92d3,0x92d4,0x92d5,0x92d6,0x92d7,
+ 0x92d8,0x92d9,0x92da,0x92db,0x92dc,0x92dd,0x92de,0x92df,
+ 0x92e0,0x92e1,0x92e2,0x92e3,0x92e4,0x92e5,0x92e6,0x92e7,
+ 0x92e8,0x92e9,0x92ea,0x92eb,0x92ec,0x92ed,0x92ee,0x92ef,
+ 0x92f0,0x92f1,0x92f2,0x92f3,0x92f4,0x92f5,0x92f6,0x92f7,
+ 0x92f8,0x92f9,0x92fa,0x92fb,0x92fc,0x92fd,0x92fe,0x92ff,
+ 0x9300,0x9301,0x9302,0x9303,0x9304,0x9305,0x9306,0x9307,
+ 0x9308,0x9309,0x930a,0x930b,0x930c,0x930d,0x930e,0x930f,
+ 0x9310,0x9311,0x9312,0x9313,0x9314,0x9315,0x9316,0x9317,
+ 0x9318,0x9319,0x931a,0x931b,0x931c,0x931d,0x931e,0x931f,
+ 0x9320,0x9321,0x9322,0x9323,0x9324,0x9325,0x9326,0x9327,
+ 0x9328,0x9329,0x932a,0x932b,0x932c,0x932d,0x932e,0x932f,
+ 0x9330,0x9331,0x9332,0x9333,0x9334,0x9335,0x9336,0x9337,
+ 0x9338,0x9339,0x933a,0x933b,0x933c,0x933d,0x933e,0x933f,
+ 0x9340,0x9341,0x9342,0x9343,0x9344,0x9345,0x9346,0x9347,
+ 0x9348,0x9349,0x934a,0x934b,0x934c,0x934d,0x934e,0x934f,
+ 0x9350,0x9351,0x9352,0x9353,0x9354,0x9355,0x9356,0x9357,
+ 0x9358,0x9359,0x935a,0x935b,0x935c,0x935d,0x935e,0x935f,
+ 0x9360,0x9361,0x9362,0x9363,0x9364,0x9365,0x9366,0x9367,
+ 0x9368,0x9369,0x936a,0x936b,0x936c,0x936d,0x936e,0x936f,
+ 0x9370,0x9371,0x9372,0x9373,0x9374,0x9375,0x9376,0x9377,
+ 0x9378,0x9379,0x937a,0x937b,0x937c,0x937d,0x937e,0x937f,
+ 0x9380,0x9381,0x9382,0x9383,0x9384,0x9385,0x9386,0x9387,
+ 0x9388,0x9389,0x938a,0x938b,0x938c,0x938d,0x938e,0x938f,
+ 0x9390,0x9391,0x9392,0x9393,0x9394,0x9395,0x9396,0x9397,
+ 0x9398,0x9399,0x939a,0x939b,0x939c,0x939d,0x939e,0x939f,
+ 0x93a0,0x93a1,0x93a2,0x93a3,0x93a4,0x93a5,0x93a6,0x93a7,
+ 0x93a8,0x93a9,0x93aa,0x93ab,0x93ac,0x93ad,0x93ae,0x93af,
+ 0x93b0,0x93b1,0x93b2,0x93b3,0x93b4,0x93b5,0x93b6,0x93b7,
+ 0x93b8,0x93b9,0x93ba,0x93bb,0x93bc,0x93bd,0x93be,0x93bf,
+ 0x93c0,0x93c1,0x93c2,0x93c3,0x93c4,0x93c5,0x93c6,0x93c7,
+ 0x93c8,0x93c9,0x93ca,0x93cb,0x93cc,0x93cd,0x93ce,0x93cf,
+ 0x93d0,0x93d1,0x93d2,0x93d3,0x93d4,0x93d5,0x93d6,0x93d7,
+ 0x93d8,0x93d9,0x93da,0x93db,0x93dc,0x93dd,0x93de,0x93df,
+ 0x93e0,0x93e1,0x93e2,0x93e3,0x93e4,0x93e5,0x93e6,0x93e7,
+ 0x93e8,0x93e9,0x93ea,0x93eb,0x93ec,0x93ed,0x93ee,0x93ef,
+ 0x93f0,0x93f1,0x93f2,0x93f3,0x93f4,0x93f5,0x93f6,0x93f7,
+ 0x93f8,0x93f9,0x93fa,0x93fb,0x93fc,0x93fd,0x93fe,0x93ff,
+ 0x9400,0x9401,0x9402,0x9403,0x9404,0x9405,0x9406,0x9407,
+ 0x9408,0x9409,0x940a,0x940b,0x940c,0x940d,0x940e,0x940f,
+ 0x9410,0x9411,0x9412,0x9413,0x9414,0x9415,0x9416,0x9417,
+ 0x9418,0x9419,0x941a,0x941b,0x941c,0x941d,0x941e,0x941f,
+ 0x9420,0x9421,0x9422,0x9423,0x9424,0x9425,0x9426,0x9427,
+ 0x9428,0x9429,0x942a,0x942b,0x942c,0x942d,0x942e,0x942f,
+ 0x9430,0x9431,0x9432,0x9433,0x9434,0x9435,0x9436,0x9437,
+ 0x9438,0x9439,0x943a,0x943b,0x943c,0x943d,0x943e,0x943f,
+ 0x9440,0x9441,0x9442,0x9443,0x9444,0x9445,0x9446,0x9447,
+ 0x9448,0x9449,0x944a,0x944b,0x944c,0x944d,0x944e,0x944f,
+ 0x9450,0x9451,0x9452,0x9453,0x9454,0x9455,0x9456,0x9457,
+ 0x9458,0x9459,0x945a,0x945b,0x945c,0x945d,0x945e,0x945f,
+ 0x9460,0x9461,0x9462,0x9463,0x9464,0x9465,0x9466,0x9467,
+ 0x9468,0x9469,0x946a,0x946b,0x946c,0x946d,0x946e,0x946f,
+ 0x9470,0x9471,0x9472,0x9473,0x9474,0x9475,0x9476,0x9477,
+ 0x9478,0x9479,0x947a,0x947b,0x947c,0x947d,0x947e,0x947f,
+ 0x9480,0x9481,0x9482,0x9483,0x9484,0x9485,0x9486,0x9487,
+ 0x9488,0x9489,0x948a,0x948b,0x948c,0x948d,0x948e,0x948f,
+ 0x9490,0x9491,0x9492,0x9493,0x9494,0x9495,0x9496,0x9497,
+ 0x9498,0x9499,0x949a,0x949b,0x949c,0x949d,0x949e,0x949f,
+ 0x94a0,0x94a1,0x94a2,0x94a3,0x94a4,0x94a5,0x94a6,0x94a7,
+ 0x94a8,0x94a9,0x94aa,0x94ab,0x94ac,0x94ad,0x94ae,0x94af,
+ 0x94b0,0x94b1,0x94b2,0x94b3,0x94b4,0x94b5,0x94b6,0x94b7,
+ 0x94b8,0x94b9,0x94ba,0x94bb,0x94bc,0x94bd,0x94be,0x94bf,
+ 0x94c0,0x94c1,0x94c2,0x94c3,0x94c4,0x94c5,0x94c6,0x94c7,
+ 0x94c8,0x94c9,0x94ca,0x94cb,0x94cc,0x94cd,0x94ce,0x94cf,
+ 0x94d0,0x94d1,0x94d2,0x94d3,0x94d4,0x94d5,0x94d6,0x94d7,
+ 0x94d8,0x94d9,0x94da,0x94db,0x94dc,0x94dd,0x94de,0x94df,
+ 0x94e0,0x94e1,0x94e2,0x94e3,0x94e4,0x94e5,0x94e6,0x94e7,
+ 0x94e8,0x94e9,0x94ea,0x94eb,0x94ec,0x94ed,0x94ee,0x94ef,
+ 0x94f0,0x94f1,0x94f2,0x94f3,0x94f4,0x94f5,0x94f6,0x94f7,
+ 0x94f8,0x94f9,0x94fa,0x94fb,0x94fc,0x94fd,0x94fe,0x94ff,
+ 0x9500,0x9501,0x9502,0x9503,0x9504,0x9505,0x9506,0x9507,
+ 0x9508,0x9509,0x950a,0x950b,0x950c,0x950d,0x950e,0x950f,
+ 0x9510,0x9511,0x9512,0x9513,0x9514,0x9515,0x9516,0x9517,
+ 0x9518,0x9519,0x951a,0x951b,0x951c,0x951d,0x951e,0x951f,
+ 0x9520,0x9521,0x9522,0x9523,0x9524,0x9525,0x9526,0x9527,
+ 0x9528,0x9529,0x952a,0x952b,0x952c,0x952d,0x952e,0x952f,
+ 0x9530,0x9531,0x9532,0x9533,0x9534,0x9535,0x9536,0x9537,
+ 0x9538,0x9539,0x953a,0x953b,0x953c,0x953d,0x953e,0x953f,
+ 0x9540,0x9541,0x9542,0x9543,0x9544,0x9545,0x9546,0x9547,
+ 0x9548,0x9549,0x954a,0x954b,0x954c,0x954d,0x954e,0x954f,
+ 0x9550,0x9551,0x9552,0x9553,0x9554,0x9555,0x9556,0x9557,
+ 0x9558,0x9559,0x955a,0x955b,0x955c,0x955d,0x955e,0x955f,
+ 0x9560,0x9561,0x9562,0x9563,0x9564,0x9565,0x9566,0x9567,
+ 0x9568,0x9569,0x956a,0x956b,0x956c,0x956d,0x956e,0x956f,
+ 0x9570,0x9571,0x9572,0x9573,0x9574,0x9575,0x9576,0x9577,
+ 0x9578,0x9579,0x957a,0x957b,0x957c,0x957d,0x957e,0x957f,
+ 0x9580,0x9581,0x9582,0x9583,0x9584,0x9585,0x9586,0x9587,
+ 0x9588,0x9589,0x958a,0x958b,0x958c,0x958d,0x958e,0x958f,
+ 0x9590,0x9591,0x9592,0x9593,0x9594,0x9595,0x9596,0x9597,
+ 0x9598,0x9599,0x959a,0x959b,0x959c,0x959d,0x959e,0x959f,
+ 0x95a0,0x95a1,0x95a2,0x95a3,0x95a4,0x95a5,0x95a6,0x95a7,
+ 0x95a8,0x95a9,0x95aa,0x95ab,0x95ac,0x95ad,0x95ae,0x95af,
+ 0x95b0,0x95b1,0x95b2,0x95b3,0x95b4,0x95b5,0x95b6,0x95b7,
+ 0x95b8,0x95b9,0x95ba,0x95bb,0x95bc,0x95bd,0x95be,0x95bf,
+ 0x95c0,0x95c1,0x95c2,0x95c3,0x95c4,0x95c5,0x95c6,0x95c7,
+ 0x95c8,0x95c9,0x95ca,0x95cb,0x95cc,0x95cd,0x95ce,0x95cf,
+ 0x95d0,0x95d1,0x95d2,0x95d3,0x95d4,0x95d5,0x95d6,0x95d7,
+ 0x95d8,0x95d9,0x95da,0x95db,0x95dc,0x95dd,0x95de,0x95df,
+ 0x95e0,0x95e1,0x95e2,0x95e3,0x95e4,0x95e5,0x95e6,0x95e7,
+ 0x95e8,0x95e9,0x95ea,0x95eb,0x95ec,0x95ed,0x95ee,0x95ef,
+ 0x95f0,0x95f1,0x95f2,0x95f3,0x95f4,0x95f5,0x95f6,0x95f7,
+ 0x95f8,0x95f9,0x95fa,0x95fb,0x95fc,0x95fd,0x95fe,0x95ff,
+ 0x9600,0x9601,0x9602,0x9603,0x9604,0x9605,0x9606,0x9607,
+ 0x9608,0x9609,0x960a,0x960b,0x960c,0x960d,0x960e,0x960f,
+ 0x9610,0x9611,0x9612,0x9613,0x9614,0x9615,0x9616,0x9617,
+ 0x9618,0x9619,0x961a,0x961b,0x961c,0x961d,0x961e,0x961f,
+ 0x9620,0x9621,0x9622,0x9623,0x9624,0x9625,0x9626,0x9627,
+ 0x9628,0x9629,0x962a,0x962b,0x962c,0x962d,0x962e,0x962f,
+ 0x9630,0x9631,0x9632,0x9633,0x9634,0x9635,0x9636,0x9637,
+ 0x9638,0x9639,0x963a,0x963b,0x963c,0x963d,0x963e,0x963f,
+ 0x9640,0x9641,0x9642,0x9643,0x9644,0x9645,0x9646,0x9647,
+ 0x9648,0x9649,0x964a,0x964b,0x964c,0x964d,0x964e,0x964f,
+ 0x9650,0x9651,0x9652,0x9653,0x9654,0x9655,0x9656,0x9657,
+ 0x9658,0x9659,0x965a,0x965b,0x965c,0x965d,0x965e,0x965f,
+ 0x9660,0x9661,0x9662,0x9663,0x9664,0x9665,0x9666,0x9667,
+ 0x9668,0x9669,0x966a,0x966b,0x966c,0x966d,0x966e,0x966f,
+ 0x9670,0x9671,0x9672,0x9673,0x9674,0x9675,0x9676,0x9677,
+ 0x9678,0x9679,0x967a,0x967b,0x967c,0x967d,0x967e,0x967f,
+ 0x9680,0x9681,0x9682,0x9683,0x9684,0x9685,0x9686,0x9687,
+ 0x9688,0x9689,0x968a,0x968b,0x968c,0x968d,0x968e,0x968f,
+ 0x9690,0x9691,0x9692,0x9693,0x9694,0x9695,0x9696,0x9697,
+ 0x9698,0x9699,0x969a,0x969b,0x969c,0x969d,0x969e,0x969f,
+ 0x96a0,0x96a1,0x96a2,0x96a3,0x96a4,0x96a5,0x96a6,0x96a7,
+ 0x96a8,0x96a9,0x96aa,0x96ab,0x96ac,0x96ad,0x96ae,0x96af,
+ 0x96b0,0x96b1,0x96b2,0x96b3,0x96b4,0x96b5,0x96b6,0x96b7,
+ 0x96b8,0x96b9,0x96ba,0x96bb,0x96bc,0x96bd,0x96be,0x96bf,
+ 0x96c0,0x96c1,0x96c2,0x96c3,0x96c4,0x96c5,0x96c6,0x96c7,
+ 0x96c8,0x96c9,0x96ca,0x96cb,0x96cc,0x96cd,0x96ce,0x96cf,
+ 0x96d0,0x96d1,0x96d2,0x96d3,0x96d4,0x96d5,0x96d6,0x96d7,
+ 0x96d8,0x96d9,0x96da,0x96db,0x96dc,0x96dd,0x96de,0x96df,
+ 0x96e0,0x96e1,0x96e2,0x96e3,0x96e4,0x96e5,0x96e6,0x96e7,
+ 0x96e8,0x96e9,0x96ea,0x96eb,0x96ec,0x96ed,0x96ee,0x96ef,
+ 0x96f0,0x96f1,0x96f2,0x96f3,0x96f4,0x96f5,0x96f6,0x96f7,
+ 0x96f8,0x96f9,0x96fa,0x96fb,0x96fc,0x96fd,0x96fe,0x96ff,
+ 0x9700,0x9701,0x9702,0x9703,0x9704,0x9705,0x9706,0x9707,
+ 0x9708,0x9709,0x970a,0x970b,0x970c,0x970d,0x970e,0x970f,
+ 0x9710,0x9711,0x9712,0x9713,0x9714,0x9715,0x9716,0x9717,
+ 0x9718,0x9719,0x971a,0x971b,0x971c,0x971d,0x971e,0x971f,
+ 0x9720,0x9721,0x9722,0x9723,0x9724,0x9725,0x9726,0x9727,
+ 0x9728,0x9729,0x972a,0x972b,0x972c,0x972d,0x972e,0x972f,
+ 0x9730,0x9731,0x9732,0x9733,0x9734,0x9735,0x9736,0x9737,
+ 0x9738,0x9739,0x973a,0x973b,0x973c,0x973d,0x973e,0x973f,
+ 0x9740,0x9741,0x9742,0x9743,0x9744,0x9745,0x9746,0x9747,
+ 0x9748,0x9749,0x974a,0x974b,0x974c,0x974d,0x974e,0x974f,
+ 0x9750,0x9751,0x9752,0x9753,0x9754,0x9755,0x9756,0x9757,
+ 0x9758,0x9759,0x975a,0x975b,0x975c,0x975d,0x975e,0x975f,
+ 0x9760,0x9761,0x9762,0x9763,0x9764,0x9765,0x9766,0x9767,
+ 0x9768,0x9769,0x976a,0x976b,0x976c,0x976d,0x976e,0x976f,
+ 0x9770,0x9771,0x9772,0x9773,0x9774,0x9775,0x9776,0x9777,
+ 0x9778,0x9779,0x977a,0x977b,0x977c,0x977d,0x977e,0x977f,
+ 0x9780,0x9781,0x9782,0x9783,0x9784,0x9785,0x9786,0x9787,
+ 0x9788,0x9789,0x978a,0x978b,0x978c,0x978d,0x978e,0x978f,
+ 0x9790,0x9791,0x9792,0x9793,0x9794,0x9795,0x9796,0x9797,
+ 0x9798,0x9799,0x979a,0x979b,0x979c,0x979d,0x979e,0x979f,
+ 0x97a0,0x97a1,0x97a2,0x97a3,0x97a4,0x97a5,0x97a6,0x97a7,
+ 0x97a8,0x97a9,0x97aa,0x97ab,0x97ac,0x97ad,0x97ae,0x97af,
+ 0x97b0,0x97b1,0x97b2,0x97b3,0x97b4,0x97b5,0x97b6,0x97b7,
+ 0x97b8,0x97b9,0x97ba,0x97bb,0x97bc,0x97bd,0x97be,0x97bf,
+ 0x97c0,0x97c1,0x97c2,0x97c3,0x97c4,0x97c5,0x97c6,0x97c7,
+ 0x97c8,0x97c9,0x97ca,0x97cb,0x97cc,0x97cd,0x97ce,0x97cf,
+ 0x97d0,0x97d1,0x97d2,0x97d3,0x97d4,0x97d5,0x97d6,0x97d7,
+ 0x97d8,0x97d9,0x97da,0x97db,0x97dc,0x97dd,0x97de,0x97df,
+ 0x97e0,0x97e1,0x97e2,0x97e3,0x97e4,0x97e5,0x97e6,0x97e7,
+ 0x97e8,0x97e9,0x97ea,0x97eb,0x97ec,0x97ed,0x97ee,0x97ef,
+ 0x97f0,0x97f1,0x97f2,0x97f3,0x97f4,0x97f5,0x97f6,0x97f7,
+ 0x97f8,0x97f9,0x97fa,0x97fb,0x97fc,0x97fd,0x97fe,0x97ff,
+ 0x9800,0x9801,0x9802,0x9803,0x9804,0x9805,0x9806,0x9807,
+ 0x9808,0x9809,0x980a,0x980b,0x980c,0x980d,0x980e,0x980f,
+ 0x9810,0x9811,0x9812,0x9813,0x9814,0x9815,0x9816,0x9817,
+ 0x9818,0x9819,0x981a,0x981b,0x981c,0x981d,0x981e,0x981f,
+ 0x9820,0x9821,0x9822,0x9823,0x9824,0x9825,0x9826,0x9827,
+ 0x9828,0x9829,0x982a,0x982b,0x982c,0x982d,0x982e,0x982f,
+ 0x9830,0x9831,0x9832,0x9833,0x9834,0x9835,0x9836,0x9837,
+ 0x9838,0x9839,0x983a,0x983b,0x983c,0x983d,0x983e,0x983f,
+ 0x9840,0x9841,0x9842,0x9843,0x9844,0x9845,0x9846,0x9847,
+ 0x9848,0x9849,0x984a,0x984b,0x984c,0x984d,0x984e,0x984f,
+ 0x9850,0x9851,0x9852,0x9853,0x9854,0x9855,0x9856,0x9857,
+ 0x9858,0x9859,0x985a,0x985b,0x985c,0x985d,0x985e,0x985f,
+ 0x9860,0x9861,0x9862,0x9863,0x9864,0x9865,0x9866,0x9867,
+ 0x9868,0x9869,0x986a,0x986b,0x986c,0x986d,0x986e,0x986f,
+ 0x9870,0x9871,0x9872,0x9873,0x9874,0x9875,0x9876,0x9877,
+ 0x9878,0x9879,0x987a,0x987b,0x987c,0x987d,0x987e,0x987f,
+ 0x9880,0x9881,0x9882,0x9883,0x9884,0x9885,0x9886,0x9887,
+ 0x9888,0x9889,0x988a,0x988b,0x988c,0x988d,0x988e,0x988f,
+ 0x9890,0x9891,0x9892,0x9893,0x9894,0x9895,0x9896,0x9897,
+ 0x9898,0x9899,0x989a,0x989b,0x989c,0x989d,0x989e,0x989f,
+ 0x98a0,0x98a1,0x98a2,0x98a3,0x98a4,0x98a5,0x98a6,0x98a7,
+ 0x98a8,0x98a9,0x98aa,0x98ab,0x98ac,0x98ad,0x98ae,0x98af,
+ 0x98b0,0x98b1,0x98b2,0x98b3,0x98b4,0x98b5,0x98b6,0x98b7,
+ 0x98b8,0x98b9,0x98ba,0x98bb,0x98bc,0x98bd,0x98be,0x98bf,
+ 0x98c0,0x98c1,0x98c2,0x98c3,0x98c4,0x98c5,0x98c6,0x98c7,
+ 0x98c8,0x98c9,0x98ca,0x98cb,0x98cc,0x98cd,0x98ce,0x98cf,
+ 0x98d0,0x98d1,0x98d2,0x98d3,0x98d4,0x98d5,0x98d6,0x98d7,
+ 0x98d8,0x98d9,0x98da,0x98db,0x98dc,0x98dd,0x98de,0x98df,
+ 0x98e0,0x98e1,0x98e2,0x98e3,0x98e4,0x98e5,0x98e6,0x98e7,
+ 0x98e8,0x98e9,0x98ea,0x98eb,0x98ec,0x98ed,0x98ee,0x98ef,
+ 0x98f0,0x98f1,0x98f2,0x98f3,0x98f4,0x98f5,0x98f6,0x98f7,
+ 0x98f8,0x98f9,0x98fa,0x98fb,0x98fc,0x98fd,0x98fe,0x98ff,
+ 0x9900,0x9901,0x9902,0x9903,0x9904,0x9905,0x9906,0x9907,
+ 0x9908,0x9909,0x990a,0x990b,0x990c,0x990d,0x990e,0x990f,
+ 0x9910,0x9911,0x9912,0x9913,0x9914,0x9915,0x9916,0x9917,
+ 0x9918,0x9919,0x991a,0x991b,0x991c,0x991d,0x991e,0x991f,
+ 0x9920,0x9921,0x9922,0x9923,0x9924,0x9925,0x9926,0x9927,
+ 0x9928,0x9929,0x992a,0x992b,0x992c,0x992d,0x992e,0x992f,
+ 0x9930,0x9931,0x9932,0x9933,0x9934,0x9935,0x9936,0x9937,
+ 0x9938,0x9939,0x993a,0x993b,0x993c,0x993d,0x993e,0x993f,
+ 0x9940,0x9941,0x9942,0x9943,0x9944,0x9945,0x9946,0x9947,
+ 0x9948,0x9949,0x994a,0x994b,0x994c,0x994d,0x994e,0x994f,
+ 0x9950,0x9951,0x9952,0x9953,0x9954,0x9955,0x9956,0x9957,
+ 0x9958,0x9959,0x995a,0x995b,0x995c,0x995d,0x995e,0x995f,
+ 0x9960,0x9961,0x9962,0x9963,0x9964,0x9965,0x9966,0x9967,
+ 0x9968,0x9969,0x996a,0x996b,0x996c,0x996d,0x996e,0x996f,
+ 0x9970,0x9971,0x9972,0x9973,0x9974,0x9975,0x9976,0x9977,
+ 0x9978,0x9979,0x997a,0x997b,0x997c,0x997d,0x997e,0x997f,
+ 0x9980,0x9981,0x9982,0x9983,0x9984,0x9985,0x9986,0x9987,
+ 0x9988,0x9989,0x998a,0x998b,0x998c,0x998d,0x998e,0x998f,
+ 0x9990,0x9991,0x9992,0x9993,0x9994,0x9995,0x9996,0x9997,
+ 0x9998,0x9999,0x999a,0x999b,0x999c,0x999d,0x999e,0x999f,
+ 0x99a0,0x99a1,0x99a2,0x99a3,0x99a4,0x99a5,0x99a6,0x99a7,
+ 0x99a8,0x99a9,0x99aa,0x99ab,0x99ac,0x99ad,0x99ae,0x99af,
+ 0x99b0,0x99b1,0x99b2,0x99b3,0x99b4,0x99b5,0x99b6,0x99b7,
+ 0x99b8,0x99b9,0x99ba,0x99bb,0x99bc,0x99bd,0x99be,0x99bf,
+ 0x99c0,0x99c1,0x99c2,0x99c3,0x99c4,0x99c5,0x99c6,0x99c7,
+ 0x99c8,0x99c9,0x99ca,0x99cb,0x99cc,0x99cd,0x99ce,0x99cf,
+ 0x99d0,0x99d1,0x99d2,0x99d3,0x99d4,0x99d5,0x99d6,0x99d7,
+ 0x99d8,0x99d9,0x99da,0x99db,0x99dc,0x99dd,0x99de,0x99df,
+ 0x99e0,0x99e1,0x99e2,0x99e3,0x99e4,0x99e5,0x99e6,0x99e7,
+ 0x99e8,0x99e9,0x99ea,0x99eb,0x99ec,0x99ed,0x99ee,0x99ef,
+ 0x99f0,0x99f1,0x99f2,0x99f3,0x99f4,0x99f5,0x99f6,0x99f7,
+ 0x99f8,0x99f9,0x99fa,0x99fb,0x99fc,0x99fd,0x99fe,0x99ff,
+ 0x9a00,0x9a01,0x9a02,0x9a03,0x9a04,0x9a05,0x9a06,0x9a07,
+ 0x9a08,0x9a09,0x9a0a,0x9a0b,0x9a0c,0x9a0d,0x9a0e,0x9a0f,
+ 0x9a10,0x9a11,0x9a12,0x9a13,0x9a14,0x9a15,0x9a16,0x9a17,
+ 0x9a18,0x9a19,0x9a1a,0x9a1b,0x9a1c,0x9a1d,0x9a1e,0x9a1f,
+ 0x9a20,0x9a21,0x9a22,0x9a23,0x9a24,0x9a25,0x9a26,0x9a27,
+ 0x9a28,0x9a29,0x9a2a,0x9a2b,0x9a2c,0x9a2d,0x9a2e,0x9a2f,
+ 0x9a30,0x9a31,0x9a32,0x9a33,0x9a34,0x9a35,0x9a36,0x9a37,
+ 0x9a38,0x9a39,0x9a3a,0x9a3b,0x9a3c,0x9a3d,0x9a3e,0x9a3f,
+ 0x9a40,0x9a41,0x9a42,0x9a43,0x9a44,0x9a45,0x9a46,0x9a47,
+ 0x9a48,0x9a49,0x9a4a,0x9a4b,0x9a4c,0x9a4d,0x9a4e,0x9a4f,
+ 0x9a50,0x9a51,0x9a52,0x9a53,0x9a54,0x9a55,0x9a56,0x9a57,
+ 0x9a58,0x9a59,0x9a5a,0x9a5b,0x9a5c,0x9a5d,0x9a5e,0x9a5f,
+ 0x9a60,0x9a61,0x9a62,0x9a63,0x9a64,0x9a65,0x9a66,0x9a67,
+ 0x9a68,0x9a69,0x9a6a,0x9a6b,0x9a6c,0x9a6d,0x9a6e,0x9a6f,
+ 0x9a70,0x9a71,0x9a72,0x9a73,0x9a74,0x9a75,0x9a76,0x9a77,
+ 0x9a78,0x9a79,0x9a7a,0x9a7b,0x9a7c,0x9a7d,0x9a7e,0x9a7f,
+ 0x9a80,0x9a81,0x9a82,0x9a83,0x9a84,0x9a85,0x9a86,0x9a87,
+ 0x9a88,0x9a89,0x9a8a,0x9a8b,0x9a8c,0x9a8d,0x9a8e,0x9a8f,
+ 0x9a90,0x9a91,0x9a92,0x9a93,0x9a94,0x9a95,0x9a96,0x9a97,
+ 0x9a98,0x9a99,0x9a9a,0x9a9b,0x9a9c,0x9a9d,0x9a9e,0x9a9f,
+ 0x9aa0,0x9aa1,0x9aa2,0x9aa3,0x9aa4,0x9aa5,0x9aa6,0x9aa7,
+ 0x9aa8,0x9aa9,0x9aaa,0x9aab,0x9aac,0x9aad,0x9aae,0x9aaf,
+ 0x9ab0,0x9ab1,0x9ab2,0x9ab3,0x9ab4,0x9ab5,0x9ab6,0x9ab7,
+ 0x9ab8,0x9ab9,0x9aba,0x9abb,0x9abc,0x9abd,0x9abe,0x9abf,
+ 0x9ac0,0x9ac1,0x9ac2,0x9ac3,0x9ac4,0x9ac5,0x9ac6,0x9ac7,
+ 0x9ac8,0x9ac9,0x9aca,0x9acb,0x9acc,0x9acd,0x9ace,0x9acf,
+ 0x9ad0,0x9ad1,0x9ad2,0x9ad3,0x9ad4,0x9ad5,0x9ad6,0x9ad7,
+ 0x9ad8,0x9ad9,0x9ada,0x9adb,0x9adc,0x9add,0x9ade,0x9adf,
+ 0x9ae0,0x9ae1,0x9ae2,0x9ae3,0x9ae4,0x9ae5,0x9ae6,0x9ae7,
+ 0x9ae8,0x9ae9,0x9aea,0x9aeb,0x9aec,0x9aed,0x9aee,0x9aef,
+ 0x9af0,0x9af1,0x9af2,0x9af3,0x9af4,0x9af5,0x9af6,0x9af7,
+ 0x9af8,0x9af9,0x9afa,0x9afb,0x9afc,0x9afd,0x9afe,0x9aff,
+ 0x9b00,0x9b01,0x9b02,0x9b03,0x9b04,0x9b05,0x9b06,0x9b07,
+ 0x9b08,0x9b09,0x9b0a,0x9b0b,0x9b0c,0x9b0d,0x9b0e,0x9b0f,
+ 0x9b10,0x9b11,0x9b12,0x9b13,0x9b14,0x9b15,0x9b16,0x9b17,
+ 0x9b18,0x9b19,0x9b1a,0x9b1b,0x9b1c,0x9b1d,0x9b1e,0x9b1f,
+ 0x9b20,0x9b21,0x9b22,0x9b23,0x9b24,0x9b25,0x9b26,0x9b27,
+ 0x9b28,0x9b29,0x9b2a,0x9b2b,0x9b2c,0x9b2d,0x9b2e,0x9b2f,
+ 0x9b30,0x9b31,0x9b32,0x9b33,0x9b34,0x9b35,0x9b36,0x9b37,
+ 0x9b38,0x9b39,0x9b3a,0x9b3b,0x9b3c,0x9b3d,0x9b3e,0x9b3f,
+ 0x9b40,0x9b41,0x9b42,0x9b43,0x9b44,0x9b45,0x9b46,0x9b47,
+ 0x9b48,0x9b49,0x9b4a,0x9b4b,0x9b4c,0x9b4d,0x9b4e,0x9b4f,
+ 0x9b50,0x9b51,0x9b52,0x9b53,0x9b54,0x9b55,0x9b56,0x9b57,
+ 0x9b58,0x9b59,0x9b5a,0x9b5b,0x9b5c,0x9b5d,0x9b5e,0x9b5f,
+ 0x9b60,0x9b61,0x9b62,0x9b63,0x9b64,0x9b65,0x9b66,0x9b67,
+ 0x9b68,0x9b69,0x9b6a,0x9b6b,0x9b6c,0x9b6d,0x9b6e,0x9b6f,
+ 0x9b70,0x9b71,0x9b72,0x9b73,0x9b74,0x9b75,0x9b76,0x9b77,
+ 0x9b78,0x9b79,0x9b7a,0x9b7b,0x9b7c,0x9b7d,0x9b7e,0x9b7f,
+ 0x9b80,0x9b81,0x9b82,0x9b83,0x9b84,0x9b85,0x9b86,0x9b87,
+ 0x9b88,0x9b89,0x9b8a,0x9b8b,0x9b8c,0x9b8d,0x9b8e,0x9b8f,
+ 0x9b90,0x9b91,0x9b92,0x9b93,0x9b94,0x9b95,0x9b96,0x9b97,
+ 0x9b98,0x9b99,0x9b9a,0x9b9b,0x9b9c,0x9b9d,0x9b9e,0x9b9f,
+ 0x9ba0,0x9ba1,0x9ba2,0x9ba3,0x9ba4,0x9ba5,0x9ba6,0x9ba7,
+ 0x9ba8,0x9ba9,0x9baa,0x9bab,0x9bac,0x9bad,0x9bae,0x9baf,
+ 0x9bb0,0x9bb1,0x9bb2,0x9bb3,0x9bb4,0x9bb5,0x9bb6,0x9bb7,
+ 0x9bb8,0x9bb9,0x9bba,0x9bbb,0x9bbc,0x9bbd,0x9bbe,0x9bbf,
+ 0x9bc0,0x9bc1,0x9bc2,0x9bc3,0x9bc4,0x9bc5,0x9bc6,0x9bc7,
+ 0x9bc8,0x9bc9,0x9bca,0x9bcb,0x9bcc,0x9bcd,0x9bce,0x9bcf,
+ 0x9bd0,0x9bd1,0x9bd2,0x9bd3,0x9bd4,0x9bd5,0x9bd6,0x9bd7,
+ 0x9bd8,0x9bd9,0x9bda,0x9bdb,0x9bdc,0x9bdd,0x9bde,0x9bdf,
+ 0x9be0,0x9be1,0x9be2,0x9be3,0x9be4,0x9be5,0x9be6,0x9be7,
+ 0x9be8,0x9be9,0x9bea,0x9beb,0x9bec,0x9bed,0x9bee,0x9bef,
+ 0x9bf0,0x9bf1,0x9bf2,0x9bf3,0x9bf4,0x9bf5,0x9bf6,0x9bf7,
+ 0x9bf8,0x9bf9,0x9bfa,0x9bfb,0x9bfc,0x9bfd,0x9bfe,0x9bff,
+ 0x9c00,0x9c01,0x9c02,0x9c03,0x9c04,0x9c05,0x9c06,0x9c07,
+ 0x9c08,0x9c09,0x9c0a,0x9c0b,0x9c0c,0x9c0d,0x9c0e,0x9c0f,
+ 0x9c10,0x9c11,0x9c12,0x9c13,0x9c14,0x9c15,0x9c16,0x9c17,
+ 0x9c18,0x9c19,0x9c1a,0x9c1b,0x9c1c,0x9c1d,0x9c1e,0x9c1f,
+ 0x9c20,0x9c21,0x9c22,0x9c23,0x9c24,0x9c25,0x9c26,0x9c27,
+ 0x9c28,0x9c29,0x9c2a,0x9c2b,0x9c2c,0x9c2d,0x9c2e,0x9c2f,
+ 0x9c30,0x9c31,0x9c32,0x9c33,0x9c34,0x9c35,0x9c36,0x9c37,
+ 0x9c38,0x9c39,0x9c3a,0x9c3b,0x9c3c,0x9c3d,0x9c3e,0x9c3f,
+ 0x9c40,0x9c41,0x9c42,0x9c43,0x9c44,0x9c45,0x9c46,0x9c47,
+ 0x9c48,0x9c49,0x9c4a,0x9c4b,0x9c4c,0x9c4d,0x9c4e,0x9c4f,
+ 0x9c50,0x9c51,0x9c52,0x9c53,0x9c54,0x9c55,0x9c56,0x9c57,
+ 0x9c58,0x9c59,0x9c5a,0x9c5b,0x9c5c,0x9c5d,0x9c5e,0x9c5f,
+ 0x9c60,0x9c61,0x9c62,0x9c63,0x9c64,0x9c65,0x9c66,0x9c67,
+ 0x9c68,0x9c69,0x9c6a,0x9c6b,0x9c6c,0x9c6d,0x9c6e,0x9c6f,
+ 0x9c70,0x9c71,0x9c72,0x9c73,0x9c74,0x9c75,0x9c76,0x9c77,
+ 0x9c78,0x9c79,0x9c7a,0x9c7b,0x9c7c,0x9c7d,0x9c7e,0x9c7f,
+ 0x9c80,0x9c81,0x9c82,0x9c83,0x9c84,0x9c85,0x9c86,0x9c87,
+ 0x9c88,0x9c89,0x9c8a,0x9c8b,0x9c8c,0x9c8d,0x9c8e,0x9c8f,
+ 0x9c90,0x9c91,0x9c92,0x9c93,0x9c94,0x9c95,0x9c96,0x9c97,
+ 0x9c98,0x9c99,0x9c9a,0x9c9b,0x9c9c,0x9c9d,0x9c9e,0x9c9f,
+ 0x9ca0,0x9ca1,0x9ca2,0x9ca3,0x9ca4,0x9ca5,0x9ca6,0x9ca7,
+ 0x9ca8,0x9ca9,0x9caa,0x9cab,0x9cac,0x9cad,0x9cae,0x9caf,
+ 0x9cb0,0x9cb1,0x9cb2,0x9cb3,0x9cb4,0x9cb5,0x9cb6,0x9cb7,
+ 0x9cb8,0x9cb9,0x9cba,0x9cbb,0x9cbc,0x9cbd,0x9cbe,0x9cbf,
+ 0x9cc0,0x9cc1,0x9cc2,0x9cc3,0x9cc4,0x9cc5,0x9cc6,0x9cc7,
+ 0x9cc8,0x9cc9,0x9cca,0x9ccb,0x9ccc,0x9ccd,0x9cce,0x9ccf,
+ 0x9cd0,0x9cd1,0x9cd2,0x9cd3,0x9cd4,0x9cd5,0x9cd6,0x9cd7,
+ 0x9cd8,0x9cd9,0x9cda,0x9cdb,0x9cdc,0x9cdd,0x9cde,0x9cdf,
+ 0x9ce0,0x9ce1,0x9ce2,0x9ce3,0x9ce4,0x9ce5,0x9ce6,0x9ce7,
+ 0x9ce8,0x9ce9,0x9cea,0x9ceb,0x9cec,0x9ced,0x9cee,0x9cef,
+ 0x9cf0,0x9cf1,0x9cf2,0x9cf3,0x9cf4,0x9cf5,0x9cf6,0x9cf7,
+ 0x9cf8,0x9cf9,0x9cfa,0x9cfb,0x9cfc,0x9cfd,0x9cfe,0x9cff,
+ 0x9d00,0x9d01,0x9d02,0x9d03,0x9d04,0x9d05,0x9d06,0x9d07,
+ 0x9d08,0x9d09,0x9d0a,0x9d0b,0x9d0c,0x9d0d,0x9d0e,0x9d0f,
+ 0x9d10,0x9d11,0x9d12,0x9d13,0x9d14,0x9d15,0x9d16,0x9d17,
+ 0x9d18,0x9d19,0x9d1a,0x9d1b,0x9d1c,0x9d1d,0x9d1e,0x9d1f,
+ 0x9d20,0x9d21,0x9d22,0x9d23,0x9d24,0x9d25,0x9d26,0x9d27,
+ 0x9d28,0x9d29,0x9d2a,0x9d2b,0x9d2c,0x9d2d,0x9d2e,0x9d2f,
+ 0x9d30,0x9d31,0x9d32,0x9d33,0x9d34,0x9d35,0x9d36,0x9d37,
+ 0x9d38,0x9d39,0x9d3a,0x9d3b,0x9d3c,0x9d3d,0x9d3e,0x9d3f,
+ 0x9d40,0x9d41,0x9d42,0x9d43,0x9d44,0x9d45,0x9d46,0x9d47,
+ 0x9d48,0x9d49,0x9d4a,0x9d4b,0x9d4c,0x9d4d,0x9d4e,0x9d4f,
+ 0x9d50,0x9d51,0x9d52,0x9d53,0x9d54,0x9d55,0x9d56,0x9d57,
+ 0x9d58,0x9d59,0x9d5a,0x9d5b,0x9d5c,0x9d5d,0x9d5e,0x9d5f,
+ 0x9d60,0x9d61,0x9d62,0x9d63,0x9d64,0x9d65,0x9d66,0x9d67,
+ 0x9d68,0x9d69,0x9d6a,0x9d6b,0x9d6c,0x9d6d,0x9d6e,0x9d6f,
+ 0x9d70,0x9d71,0x9d72,0x9d73,0x9d74,0x9d75,0x9d76,0x9d77,
+ 0x9d78,0x9d79,0x9d7a,0x9d7b,0x9d7c,0x9d7d,0x9d7e,0x9d7f,
+ 0x9d80,0x9d81,0x9d82,0x9d83,0x9d84,0x9d85,0x9d86,0x9d87,
+ 0x9d88,0x9d89,0x9d8a,0x9d8b,0x9d8c,0x9d8d,0x9d8e,0x9d8f,
+ 0x9d90,0x9d91,0x9d92,0x9d93,0x9d94,0x9d95,0x9d96,0x9d97,
+ 0x9d98,0x9d99,0x9d9a,0x9d9b,0x9d9c,0x9d9d,0x9d9e,0x9d9f,
+ 0x9da0,0x9da1,0x9da2,0x9da3,0x9da4,0x9da5,0x9da6,0x9da7,
+ 0x9da8,0x9da9,0x9daa,0x9dab,0x9dac,0x9dad,0x9dae,0x9daf,
+ 0x9db0,0x9db1,0x9db2,0x9db3,0x9db4,0x9db5,0x9db6,0x9db7,
+ 0x9db8,0x9db9,0x9dba,0x9dbb,0x9dbc,0x9dbd,0x9dbe,0x9dbf,
+ 0x9dc0,0x9dc1,0x9dc2,0x9dc3,0x9dc4,0x9dc5,0x9dc6,0x9dc7,
+ 0x9dc8,0x9dc9,0x9dca,0x9dcb,0x9dcc,0x9dcd,0x9dce,0x9dcf,
+ 0x9dd0,0x9dd1,0x9dd2,0x9dd3,0x9dd4,0x9dd5,0x9dd6,0x9dd7,
+ 0x9dd8,0x9dd9,0x9dda,0x9ddb,0x9ddc,0x9ddd,0x9dde,0x9ddf,
+ 0x9de0,0x9de1,0x9de2,0x9de3,0x9de4,0x9de5,0x9de6,0x9de7,
+ 0x9de8,0x9de9,0x9dea,0x9deb,0x9dec,0x9ded,0x9dee,0x9def,
+ 0x9df0,0x9df1,0x9df2,0x9df3,0x9df4,0x9df5,0x9df6,0x9df7,
+ 0x9df8,0x9df9,0x9dfa,0x9dfb,0x9dfc,0x9dfd,0x9dfe,0x9dff,
+ 0x9e00,0x9e01,0x9e02,0x9e03,0x9e04,0x9e05,0x9e06,0x9e07,
+ 0x9e08,0x9e09,0x9e0a,0x9e0b,0x9e0c,0x9e0d,0x9e0e,0x9e0f,
+ 0x9e10,0x9e11,0x9e12,0x9e13,0x9e14,0x9e15,0x9e16,0x9e17,
+ 0x9e18,0x9e19,0x9e1a,0x9e1b,0x9e1c,0x9e1d,0x9e1e,0x9e1f,
+ 0x9e20,0x9e21,0x9e22,0x9e23,0x9e24,0x9e25,0x9e26,0x9e27,
+ 0x9e28,0x9e29,0x9e2a,0x9e2b,0x9e2c,0x9e2d,0x9e2e,0x9e2f,
+ 0x9e30,0x9e31,0x9e32,0x9e33,0x9e34,0x9e35,0x9e36,0x9e37,
+ 0x9e38,0x9e39,0x9e3a,0x9e3b,0x9e3c,0x9e3d,0x9e3e,0x9e3f,
+ 0x9e40,0x9e41,0x9e42,0x9e43,0x9e44,0x9e45,0x9e46,0x9e47,
+ 0x9e48,0x9e49,0x9e4a,0x9e4b,0x9e4c,0x9e4d,0x9e4e,0x9e4f,
+ 0x9e50,0x9e51,0x9e52,0x9e53,0x9e54,0x9e55,0x9e56,0x9e57,
+ 0x9e58,0x9e59,0x9e5a,0x9e5b,0x9e5c,0x9e5d,0x9e5e,0x9e5f,
+ 0x9e60,0x9e61,0x9e62,0x9e63,0x9e64,0x9e65,0x9e66,0x9e67,
+ 0x9e68,0x9e69,0x9e6a,0x9e6b,0x9e6c,0x9e6d,0x9e6e,0x9e6f,
+ 0x9e70,0x9e71,0x9e72,0x9e73,0x9e74,0x9e75,0x9e76,0x9e77,
+ 0x9e78,0x9e79,0x9e7a,0x9e7b,0x9e7c,0x9e7d,0x9e7e,0x9e7f,
+ 0x9e80,0x9e81,0x9e82,0x9e83,0x9e84,0x9e85,0x9e86,0x9e87,
+ 0x9e88,0x9e89,0x9e8a,0x9e8b,0x9e8c,0x9e8d,0x9e8e,0x9e8f,
+ 0x9e90,0x9e91,0x9e92,0x9e93,0x9e94,0x9e95,0x9e96,0x9e97,
+ 0x9e98,0x9e99,0x9e9a,0x9e9b,0x9e9c,0x9e9d,0x9e9e,0x9e9f,
+ 0x9ea0,0x9ea1,0x9ea2,0x9ea3,0x9ea4,0x9ea5,0x9ea6,0x9ea7,
+ 0x9ea8,0x9ea9,0x9eaa,0x9eab,0x9eac,0x9ead,0x9eae,0x9eaf,
+ 0x9eb0,0x9eb1,0x9eb2,0x9eb3,0x9eb4,0x9eb5,0x9eb6,0x9eb7,
+ 0x9eb8,0x9eb9,0x9eba,0x9ebb,0x9ebc,0x9ebd,0x9ebe,0x9ebf,
+ 0x9ec0,0x9ec1,0x9ec2,0x9ec3,0x9ec4,0x9ec5,0x9ec6,0x9ec7,
+ 0x9ec8,0x9ec9,0x9eca,0x9ecb,0x9ecc,0x9ecd,0x9ece,0x9ecf,
+ 0x9ed0,0x9ed1,0x9ed2,0x9ed3,0x9ed4,0x9ed5,0x9ed6,0x9ed7,
+ 0x9ed8,0x9ed9,0x9eda,0x9edb,0x9edc,0x9edd,0x9ede,0x9edf,
+ 0x9ee0,0x9ee1,0x9ee2,0x9ee3,0x9ee4,0x9ee5,0x9ee6,0x9ee7,
+ 0x9ee8,0x9ee9,0x9eea,0x9eeb,0x9eec,0x9eed,0x9eee,0x9eef,
+ 0x9ef0,0x9ef1,0x9ef2,0x9ef3,0x9ef4,0x9ef5,0x9ef6,0x9ef7,
+ 0x9ef8,0x9ef9,0x9efa,0x9efb,0x9efc,0x9efd,0x9efe,0x9eff,
+ 0x9f00,0x9f01,0x9f02,0x9f03,0x9f04,0x9f05,0x9f06,0x9f07,
+ 0x9f08,0x9f09,0x9f0a,0x9f0b,0x9f0c,0x9f0d,0x9f0e,0x9f0f,
+ 0x9f10,0x9f11,0x9f12,0x9f13,0x9f14,0x9f15,0x9f16,0x9f17,
+ 0x9f18,0x9f19,0x9f1a,0x9f1b,0x9f1c,0x9f1d,0x9f1e,0x9f1f,
+ 0x9f20,0x9f21,0x9f22,0x9f23,0x9f24,0x9f25,0x9f26,0x9f27,
+ 0x9f28,0x9f29,0x9f2a,0x9f2b,0x9f2c,0x9f2d,0x9f2e,0x9f2f,
+ 0x9f30,0x9f31,0x9f32,0x9f33,0x9f34,0x9f35,0x9f36,0x9f37,
+ 0x9f38,0x9f39,0x9f3a,0x9f3b,0x9f3c,0x9f3d,0x9f3e,0x9f3f,
+ 0x9f40,0x9f41,0x9f42,0x9f43,0x9f44,0x9f45,0x9f46,0x9f47,
+ 0x9f48,0x9f49,0x9f4a,0x9f4b,0x9f4c,0x9f4d,0x9f4e,0x9f4f,
+ 0x9f50,0x9f51,0x9f52,0x9f53,0x9f54,0x9f55,0x9f56,0x9f57,
+ 0x9f58,0x9f59,0x9f5a,0x9f5b,0x9f5c,0x9f5d,0x9f5e,0x9f5f,
+ 0x9f60,0x9f61,0x9f62,0x9f63,0x9f64,0x9f65,0x9f66,0x9f67,
+ 0x9f68,0x9f69,0x9f6a,0x9f6b,0x9f6c,0x9f6d,0x9f6e,0x9f6f,
+ 0x9f70,0x9f71,0x9f72,0x9f73,0x9f74,0x9f75,0x9f76,0x9f77,
+ 0x9f78,0x9f79,0x9f7a,0x9f7b,0x9f7c,0x9f7d,0x9f7e,0x9f7f,
+ 0x9f80,0x9f81,0x9f82,0x9f83,0x9f84,0x9f85,0x9f86,0x9f87,
+ 0x9f88,0x9f89,0x9f8a,0x9f8b,0x9f8c,0x9f8d,0x9f8e,0x9f8f,
+ 0x9f90,0x9f91,0x9f92,0x9f93,0x9f94,0x9f95,0x9f96,0x9f97,
+ 0x9f98,0x9f99,0x9f9a,0x9f9b,0x9f9c,0x9f9d,0x9f9e,0x9f9f,
+ 0x9fa0,0x9fa1,0x9fa2,0x9fa3,0x9fa4,0x9fa5,0x9fa6,0x9fa7,
+ 0x9fa8,0x9fa9,0x9faa,0x9fab,0x9fac,0x9fad,0x9fae,0x9faf,
+ 0x9fb0,0x9fb1,0x9fb2,0x9fb3,0x9fb4,0x9fb5,0x9fb6,0x9fb7,
+ 0x9fb8,0x9fb9,0x9fba,0x9fbb,0x9fbc,0x9fbd,0x9fbe,0x9fbf,
+ 0x9fc0,0x9fc1,0x9fc2,0x9fc3,0x9fc4,0x9fc5,0x9fc6,0x9fc7,
+ 0x9fc8,0x9fc9,0x9fca,0x9fcb,0x9fcc,0x9fcd,0x9fce,0x9fcf,
+ 0x9fd0,0x9fd1,0x9fd2,0x9fd3,0x9fd4,0x9fd5,0x9fd6,0x9fd7,
+ 0x9fd8,0x9fd9,0x9fda,0x9fdb,0x9fdc,0x9fdd,0x9fde,0x9fdf,
+ 0x9fe0,0x9fe1,0x9fe2,0x9fe3,0x9fe4,0x9fe5,0x9fe6,0x9fe7,
+ 0x9fe8,0x9fe9,0x9fea,0x9feb,0x9fec,0x9fed,0x9fee,0x9fef,
+ 0x9ff0,0x9ff1,0x9ff2,0x9ff3,0x9ff4,0x9ff5,0x9ff6,0x9ff7,
+ 0x9ff8,0x9ff9,0x9ffa,0x9ffb,0x9ffc,0x9ffd,0x9ffe,0x9fff,
+ 0xa000,0xa001,0xa002,0xa003,0xa004,0xa005,0xa006,0xa007,
+ 0xa008,0xa009,0xa00a,0xa00b,0xa00c,0xa00d,0xa00e,0xa00f,
+ 0xa010,0xa011,0xa012,0xa013,0xa014,0xa015,0xa016,0xa017,
+ 0xa018,0xa019,0xa01a,0xa01b,0xa01c,0xa01d,0xa01e,0xa01f,
+ 0xa020,0xa021,0xa022,0xa023,0xa024,0xa025,0xa026,0xa027,
+ 0xa028,0xa029,0xa02a,0xa02b,0xa02c,0xa02d,0xa02e,0xa02f,
+ 0xa030,0xa031,0xa032,0xa033,0xa034,0xa035,0xa036,0xa037,
+ 0xa038,0xa039,0xa03a,0xa03b,0xa03c,0xa03d,0xa03e,0xa03f,
+ 0xa040,0xa041,0xa042,0xa043,0xa044,0xa045,0xa046,0xa047,
+ 0xa048,0xa049,0xa04a,0xa04b,0xa04c,0xa04d,0xa04e,0xa04f,
+ 0xa050,0xa051,0xa052,0xa053,0xa054,0xa055,0xa056,0xa057,
+ 0xa058,0xa059,0xa05a,0xa05b,0xa05c,0xa05d,0xa05e,0xa05f,
+ 0xa060,0xa061,0xa062,0xa063,0xa064,0xa065,0xa066,0xa067,
+ 0xa068,0xa069,0xa06a,0xa06b,0xa06c,0xa06d,0xa06e,0xa06f,
+ 0xa070,0xa071,0xa072,0xa073,0xa074,0xa075,0xa076,0xa077,
+ 0xa078,0xa079,0xa07a,0xa07b,0xa07c,0xa07d,0xa07e,0xa07f,
+ 0xa080,0xa081,0xa082,0xa083,0xa084,0xa085,0xa086,0xa087,
+ 0xa088,0xa089,0xa08a,0xa08b,0xa08c,0xa08d,0xa08e,0xa08f,
+ 0xa090,0xa091,0xa092,0xa093,0xa094,0xa095,0xa096,0xa097,
+ 0xa098,0xa099,0xa09a,0xa09b,0xa09c,0xa09d,0xa09e,0xa09f,
+ 0xa0a0,0xa0a1,0xa0a2,0xa0a3,0xa0a4,0xa0a5,0xa0a6,0xa0a7,
+ 0xa0a8,0xa0a9,0xa0aa,0xa0ab,0xa0ac,0xa0ad,0xa0ae,0xa0af,
+ 0xa0b0,0xa0b1,0xa0b2,0xa0b3,0xa0b4,0xa0b5,0xa0b6,0xa0b7,
+ 0xa0b8,0xa0b9,0xa0ba,0xa0bb,0xa0bc,0xa0bd,0xa0be,0xa0bf,
+ 0xa0c0,0xa0c1,0xa0c2,0xa0c3,0xa0c4,0xa0c5,0xa0c6,0xa0c7,
+ 0xa0c8,0xa0c9,0xa0ca,0xa0cb,0xa0cc,0xa0cd,0xa0ce,0xa0cf,
+ 0xa0d0,0xa0d1,0xa0d2,0xa0d3,0xa0d4,0xa0d5,0xa0d6,0xa0d7,
+ 0xa0d8,0xa0d9,0xa0da,0xa0db,0xa0dc,0xa0dd,0xa0de,0xa0df,
+ 0xa0e0,0xa0e1,0xa0e2,0xa0e3,0xa0e4,0xa0e5,0xa0e6,0xa0e7,
+ 0xa0e8,0xa0e9,0xa0ea,0xa0eb,0xa0ec,0xa0ed,0xa0ee,0xa0ef,
+ 0xa0f0,0xa0f1,0xa0f2,0xa0f3,0xa0f4,0xa0f5,0xa0f6,0xa0f7,
+ 0xa0f8,0xa0f9,0xa0fa,0xa0fb,0xa0fc,0xa0fd,0xa0fe,0xa0ff,
+ 0xa100,0xa101,0xa102,0xa103,0xa104,0xa105,0xa106,0xa107,
+ 0xa108,0xa109,0xa10a,0xa10b,0xa10c,0xa10d,0xa10e,0xa10f,
+ 0xa110,0xa111,0xa112,0xa113,0xa114,0xa115,0xa116,0xa117,
+ 0xa118,0xa119,0xa11a,0xa11b,0xa11c,0xa11d,0xa11e,0xa11f,
+ 0xa120,0xa121,0xa122,0xa123,0xa124,0xa125,0xa126,0xa127,
+ 0xa128,0xa129,0xa12a,0xa12b,0xa12c,0xa12d,0xa12e,0xa12f,
+ 0xa130,0xa131,0xa132,0xa133,0xa134,0xa135,0xa136,0xa137,
+ 0xa138,0xa139,0xa13a,0xa13b,0xa13c,0xa13d,0xa13e,0xa13f,
+ 0xa140,0xa141,0xa142,0xa143,0xa144,0xa145,0xa146,0xa147,
+ 0xa148,0xa149,0xa14a,0xa14b,0xa14c,0xa14d,0xa14e,0xa14f,
+ 0xa150,0xa151,0xa152,0xa153,0xa154,0xa155,0xa156,0xa157,
+ 0xa158,0xa159,0xa15a,0xa15b,0xa15c,0xa15d,0xa15e,0xa15f,
+ 0xa160,0xa161,0xa162,0xa163,0xa164,0xa165,0xa166,0xa167,
+ 0xa168,0xa169,0xa16a,0xa16b,0xa16c,0xa16d,0xa16e,0xa16f,
+ 0xa170,0xa171,0xa172,0xa173,0xa174,0xa175,0xa176,0xa177,
+ 0xa178,0xa179,0xa17a,0xa17b,0xa17c,0xa17d,0xa17e,0xa17f,
+ 0xa180,0xa181,0xa182,0xa183,0xa184,0xa185,0xa186,0xa187,
+ 0xa188,0xa189,0xa18a,0xa18b,0xa18c,0xa18d,0xa18e,0xa18f,
+ 0xa190,0xa191,0xa192,0xa193,0xa194,0xa195,0xa196,0xa197,
+ 0xa198,0xa199,0xa19a,0xa19b,0xa19c,0xa19d,0xa19e,0xa19f,
+ 0xa1a0,0xa1a1,0xa1a2,0xa1a3,0xa1a4,0xa1a5,0xa1a6,0xa1a7,
+ 0xa1a8,0xa1a9,0xa1aa,0xa1ab,0xa1ac,0xa1ad,0xa1ae,0xa1af,
+ 0xa1b0,0xa1b1,0xa1b2,0xa1b3,0xa1b4,0xa1b5,0xa1b6,0xa1b7,
+ 0xa1b8,0xa1b9,0xa1ba,0xa1bb,0xa1bc,0xa1bd,0xa1be,0xa1bf,
+ 0xa1c0,0xa1c1,0xa1c2,0xa1c3,0xa1c4,0xa1c5,0xa1c6,0xa1c7,
+ 0xa1c8,0xa1c9,0xa1ca,0xa1cb,0xa1cc,0xa1cd,0xa1ce,0xa1cf,
+ 0xa1d0,0xa1d1,0xa1d2,0xa1d3,0xa1d4,0xa1d5,0xa1d6,0xa1d7,
+ 0xa1d8,0xa1d9,0xa1da,0xa1db,0xa1dc,0xa1dd,0xa1de,0xa1df,
+ 0xa1e0,0xa1e1,0xa1e2,0xa1e3,0xa1e4,0xa1e5,0xa1e6,0xa1e7,
+ 0xa1e8,0xa1e9,0xa1ea,0xa1eb,0xa1ec,0xa1ed,0xa1ee,0xa1ef,
+ 0xa1f0,0xa1f1,0xa1f2,0xa1f3,0xa1f4,0xa1f5,0xa1f6,0xa1f7,
+ 0xa1f8,0xa1f9,0xa1fa,0xa1fb,0xa1fc,0xa1fd,0xa1fe,0xa1ff,
+ 0xa200,0xa201,0xa202,0xa203,0xa204,0xa205,0xa206,0xa207,
+ 0xa208,0xa209,0xa20a,0xa20b,0xa20c,0xa20d,0xa20e,0xa20f,
+ 0xa210,0xa211,0xa212,0xa213,0xa214,0xa215,0xa216,0xa217,
+ 0xa218,0xa219,0xa21a,0xa21b,0xa21c,0xa21d,0xa21e,0xa21f,
+ 0xa220,0xa221,0xa222,0xa223,0xa224,0xa225,0xa226,0xa227,
+ 0xa228,0xa229,0xa22a,0xa22b,0xa22c,0xa22d,0xa22e,0xa22f,
+ 0xa230,0xa231,0xa232,0xa233,0xa234,0xa235,0xa236,0xa237,
+ 0xa238,0xa239,0xa23a,0xa23b,0xa23c,0xa23d,0xa23e,0xa23f,
+ 0xa240,0xa241,0xa242,0xa243,0xa244,0xa245,0xa246,0xa247,
+ 0xa248,0xa249,0xa24a,0xa24b,0xa24c,0xa24d,0xa24e,0xa24f,
+ 0xa250,0xa251,0xa252,0xa253,0xa254,0xa255,0xa256,0xa257,
+ 0xa258,0xa259,0xa25a,0xa25b,0xa25c,0xa25d,0xa25e,0xa25f,
+ 0xa260,0xa261,0xa262,0xa263,0xa264,0xa265,0xa266,0xa267,
+ 0xa268,0xa269,0xa26a,0xa26b,0xa26c,0xa26d,0xa26e,0xa26f,
+ 0xa270,0xa271,0xa272,0xa273,0xa274,0xa275,0xa276,0xa277,
+ 0xa278,0xa279,0xa27a,0xa27b,0xa27c,0xa27d,0xa27e,0xa27f,
+ 0xa280,0xa281,0xa282,0xa283,0xa284,0xa285,0xa286,0xa287,
+ 0xa288,0xa289,0xa28a,0xa28b,0xa28c,0xa28d,0xa28e,0xa28f,
+ 0xa290,0xa291,0xa292,0xa293,0xa294,0xa295,0xa296,0xa297,
+ 0xa298,0xa299,0xa29a,0xa29b,0xa29c,0xa29d,0xa29e,0xa29f,
+ 0xa2a0,0xa2a1,0xa2a2,0xa2a3,0xa2a4,0xa2a5,0xa2a6,0xa2a7,
+ 0xa2a8,0xa2a9,0xa2aa,0xa2ab,0xa2ac,0xa2ad,0xa2ae,0xa2af,
+ 0xa2b0,0xa2b1,0xa2b2,0xa2b3,0xa2b4,0xa2b5,0xa2b6,0xa2b7,
+ 0xa2b8,0xa2b9,0xa2ba,0xa2bb,0xa2bc,0xa2bd,0xa2be,0xa2bf,
+ 0xa2c0,0xa2c1,0xa2c2,0xa2c3,0xa2c4,0xa2c5,0xa2c6,0xa2c7,
+ 0xa2c8,0xa2c9,0xa2ca,0xa2cb,0xa2cc,0xa2cd,0xa2ce,0xa2cf,
+ 0xa2d0,0xa2d1,0xa2d2,0xa2d3,0xa2d4,0xa2d5,0xa2d6,0xa2d7,
+ 0xa2d8,0xa2d9,0xa2da,0xa2db,0xa2dc,0xa2dd,0xa2de,0xa2df,
+ 0xa2e0,0xa2e1,0xa2e2,0xa2e3,0xa2e4,0xa2e5,0xa2e6,0xa2e7,
+ 0xa2e8,0xa2e9,0xa2ea,0xa2eb,0xa2ec,0xa2ed,0xa2ee,0xa2ef,
+ 0xa2f0,0xa2f1,0xa2f2,0xa2f3,0xa2f4,0xa2f5,0xa2f6,0xa2f7,
+ 0xa2f8,0xa2f9,0xa2fa,0xa2fb,0xa2fc,0xa2fd,0xa2fe,0xa2ff,
+ 0xa300,0xa301,0xa302,0xa303,0xa304,0xa305,0xa306,0xa307,
+ 0xa308,0xa309,0xa30a,0xa30b,0xa30c,0xa30d,0xa30e,0xa30f,
+ 0xa310,0xa311,0xa312,0xa313,0xa314,0xa315,0xa316,0xa317,
+ 0xa318,0xa319,0xa31a,0xa31b,0xa31c,0xa31d,0xa31e,0xa31f,
+ 0xa320,0xa321,0xa322,0xa323,0xa324,0xa325,0xa326,0xa327,
+ 0xa328,0xa329,0xa32a,0xa32b,0xa32c,0xa32d,0xa32e,0xa32f,
+ 0xa330,0xa331,0xa332,0xa333,0xa334,0xa335,0xa336,0xa337,
+ 0xa338,0xa339,0xa33a,0xa33b,0xa33c,0xa33d,0xa33e,0xa33f,
+ 0xa340,0xa341,0xa342,0xa343,0xa344,0xa345,0xa346,0xa347,
+ 0xa348,0xa349,0xa34a,0xa34b,0xa34c,0xa34d,0xa34e,0xa34f,
+ 0xa350,0xa351,0xa352,0xa353,0xa354,0xa355,0xa356,0xa357,
+ 0xa358,0xa359,0xa35a,0xa35b,0xa35c,0xa35d,0xa35e,0xa35f,
+ 0xa360,0xa361,0xa362,0xa363,0xa364,0xa365,0xa366,0xa367,
+ 0xa368,0xa369,0xa36a,0xa36b,0xa36c,0xa36d,0xa36e,0xa36f,
+ 0xa370,0xa371,0xa372,0xa373,0xa374,0xa375,0xa376,0xa377,
+ 0xa378,0xa379,0xa37a,0xa37b,0xa37c,0xa37d,0xa37e,0xa37f,
+ 0xa380,0xa381,0xa382,0xa383,0xa384,0xa385,0xa386,0xa387,
+ 0xa388,0xa389,0xa38a,0xa38b,0xa38c,0xa38d,0xa38e,0xa38f,
+ 0xa390,0xa391,0xa392,0xa393,0xa394,0xa395,0xa396,0xa397,
+ 0xa398,0xa399,0xa39a,0xa39b,0xa39c,0xa39d,0xa39e,0xa39f,
+ 0xa3a0,0xa3a1,0xa3a2,0xa3a3,0xa3a4,0xa3a5,0xa3a6,0xa3a7,
+ 0xa3a8,0xa3a9,0xa3aa,0xa3ab,0xa3ac,0xa3ad,0xa3ae,0xa3af,
+ 0xa3b0,0xa3b1,0xa3b2,0xa3b3,0xa3b4,0xa3b5,0xa3b6,0xa3b7,
+ 0xa3b8,0xa3b9,0xa3ba,0xa3bb,0xa3bc,0xa3bd,0xa3be,0xa3bf,
+ 0xa3c0,0xa3c1,0xa3c2,0xa3c3,0xa3c4,0xa3c5,0xa3c6,0xa3c7,
+ 0xa3c8,0xa3c9,0xa3ca,0xa3cb,0xa3cc,0xa3cd,0xa3ce,0xa3cf,
+ 0xa3d0,0xa3d1,0xa3d2,0xa3d3,0xa3d4,0xa3d5,0xa3d6,0xa3d7,
+ 0xa3d8,0xa3d9,0xa3da,0xa3db,0xa3dc,0xa3dd,0xa3de,0xa3df,
+ 0xa3e0,0xa3e1,0xa3e2,0xa3e3,0xa3e4,0xa3e5,0xa3e6,0xa3e7,
+ 0xa3e8,0xa3e9,0xa3ea,0xa3eb,0xa3ec,0xa3ed,0xa3ee,0xa3ef,
+ 0xa3f0,0xa3f1,0xa3f2,0xa3f3,0xa3f4,0xa3f5,0xa3f6,0xa3f7,
+ 0xa3f8,0xa3f9,0xa3fa,0xa3fb,0xa3fc,0xa3fd,0xa3fe,0xa3ff,
+ 0xa400,0xa401,0xa402,0xa403,0xa404,0xa405,0xa406,0xa407,
+ 0xa408,0xa409,0xa40a,0xa40b,0xa40c,0xa40d,0xa40e,0xa40f,
+ 0xa410,0xa411,0xa412,0xa413,0xa414,0xa415,0xa416,0xa417,
+ 0xa418,0xa419,0xa41a,0xa41b,0xa41c,0xa41d,0xa41e,0xa41f,
+ 0xa420,0xa421,0xa422,0xa423,0xa424,0xa425,0xa426,0xa427,
+ 0xa428,0xa429,0xa42a,0xa42b,0xa42c,0xa42d,0xa42e,0xa42f,
+ 0xa430,0xa431,0xa432,0xa433,0xa434,0xa435,0xa436,0xa437,
+ 0xa438,0xa439,0xa43a,0xa43b,0xa43c,0xa43d,0xa43e,0xa43f,
+ 0xa440,0xa441,0xa442,0xa443,0xa444,0xa445,0xa446,0xa447,
+ 0xa448,0xa449,0xa44a,0xa44b,0xa44c,0xa44d,0xa44e,0xa44f,
+ 0xa450,0xa451,0xa452,0xa453,0xa454,0xa455,0xa456,0xa457,
+ 0xa458,0xa459,0xa45a,0xa45b,0xa45c,0xa45d,0xa45e,0xa45f,
+ 0xa460,0xa461,0xa462,0xa463,0xa464,0xa465,0xa466,0xa467,
+ 0xa468,0xa469,0xa46a,0xa46b,0xa46c,0xa46d,0xa46e,0xa46f,
+ 0xa470,0xa471,0xa472,0xa473,0xa474,0xa475,0xa476,0xa477,
+ 0xa478,0xa479,0xa47a,0xa47b,0xa47c,0xa47d,0xa47e,0xa47f,
+ 0xa480,0xa481,0xa482,0xa483,0xa484,0xa485,0xa486,0xa487,
+ 0xa488,0xa489,0xa48a,0xa48b,0xa48c,0xa48d,0xa48e,0xa48f,
+ 0xa490,0xa491,0xa492,0xa493,0xa494,0xa495,0xa496,0xa497,
+ 0xa498,0xa499,0xa49a,0xa49b,0xa49c,0xa49d,0xa49e,0xa49f,
+ 0xa4a0,0xa4a1,0xa4a2,0xa4a3,0xa4a4,0xa4a5,0xa4a6,0xa4a7,
+ 0xa4a8,0xa4a9,0xa4aa,0xa4ab,0xa4ac,0xa4ad,0xa4ae,0xa4af,
+ 0xa4b0,0xa4b1,0xa4b2,0xa4b3,0xa4b4,0xa4b5,0xa4b6,0xa4b7,
+ 0xa4b8,0xa4b9,0xa4ba,0xa4bb,0xa4bc,0xa4bd,0xa4be,0xa4bf,
+ 0xa4c0,0xa4c1,0xa4c2,0xa4c3,0xa4c4,0xa4c5,0xa4c6,0xa4c7,
+ 0xa4c8,0xa4c9,0xa4ca,0xa4cb,0xa4cc,0xa4cd,0xa4ce,0xa4cf,
+ 0xa4d0,0xa4d1,0xa4d2,0xa4d3,0xa4d4,0xa4d5,0xa4d6,0xa4d7,
+ 0xa4d8,0xa4d9,0xa4da,0xa4db,0xa4dc,0xa4dd,0xa4de,0xa4df,
+ 0xa4e0,0xa4e1,0xa4e2,0xa4e3,0xa4e4,0xa4e5,0xa4e6,0xa4e7,
+ 0xa4e8,0xa4e9,0xa4ea,0xa4eb,0xa4ec,0xa4ed,0xa4ee,0xa4ef,
+ 0xa4f0,0xa4f1,0xa4f2,0xa4f3,0xa4f4,0xa4f5,0xa4f6,0xa4f7,
+ 0xa4f8,0xa4f9,0xa4fa,0xa4fb,0xa4fc,0xa4fd,0xa4fe,0xa4ff,
+ 0xa500,0xa501,0xa502,0xa503,0xa504,0xa505,0xa506,0xa507,
+ 0xa508,0xa509,0xa50a,0xa50b,0xa50c,0xa50d,0xa50e,0xa50f,
+ 0xa510,0xa511,0xa512,0xa513,0xa514,0xa515,0xa516,0xa517,
+ 0xa518,0xa519,0xa51a,0xa51b,0xa51c,0xa51d,0xa51e,0xa51f,
+ 0xa520,0xa521,0xa522,0xa523,0xa524,0xa525,0xa526,0xa527,
+ 0xa528,0xa529,0xa52a,0xa52b,0xa52c,0xa52d,0xa52e,0xa52f,
+ 0xa530,0xa531,0xa532,0xa533,0xa534,0xa535,0xa536,0xa537,
+ 0xa538,0xa539,0xa53a,0xa53b,0xa53c,0xa53d,0xa53e,0xa53f,
+ 0xa540,0xa541,0xa542,0xa543,0xa544,0xa545,0xa546,0xa547,
+ 0xa548,0xa549,0xa54a,0xa54b,0xa54c,0xa54d,0xa54e,0xa54f,
+ 0xa550,0xa551,0xa552,0xa553,0xa554,0xa555,0xa556,0xa557,
+ 0xa558,0xa559,0xa55a,0xa55b,0xa55c,0xa55d,0xa55e,0xa55f,
+ 0xa560,0xa561,0xa562,0xa563,0xa564,0xa565,0xa566,0xa567,
+ 0xa568,0xa569,0xa56a,0xa56b,0xa56c,0xa56d,0xa56e,0xa56f,
+ 0xa570,0xa571,0xa572,0xa573,0xa574,0xa575,0xa576,0xa577,
+ 0xa578,0xa579,0xa57a,0xa57b,0xa57c,0xa57d,0xa57e,0xa57f,
+ 0xa580,0xa581,0xa582,0xa583,0xa584,0xa585,0xa586,0xa587,
+ 0xa588,0xa589,0xa58a,0xa58b,0xa58c,0xa58d,0xa58e,0xa58f,
+ 0xa590,0xa591,0xa592,0xa593,0xa594,0xa595,0xa596,0xa597,
+ 0xa598,0xa599,0xa59a,0xa59b,0xa59c,0xa59d,0xa59e,0xa59f,
+ 0xa5a0,0xa5a1,0xa5a2,0xa5a3,0xa5a4,0xa5a5,0xa5a6,0xa5a7,
+ 0xa5a8,0xa5a9,0xa5aa,0xa5ab,0xa5ac,0xa5ad,0xa5ae,0xa5af,
+ 0xa5b0,0xa5b1,0xa5b2,0xa5b3,0xa5b4,0xa5b5,0xa5b6,0xa5b7,
+ 0xa5b8,0xa5b9,0xa5ba,0xa5bb,0xa5bc,0xa5bd,0xa5be,0xa5bf,
+ 0xa5c0,0xa5c1,0xa5c2,0xa5c3,0xa5c4,0xa5c5,0xa5c6,0xa5c7,
+ 0xa5c8,0xa5c9,0xa5ca,0xa5cb,0xa5cc,0xa5cd,0xa5ce,0xa5cf,
+ 0xa5d0,0xa5d1,0xa5d2,0xa5d3,0xa5d4,0xa5d5,0xa5d6,0xa5d7,
+ 0xa5d8,0xa5d9,0xa5da,0xa5db,0xa5dc,0xa5dd,0xa5de,0xa5df,
+ 0xa5e0,0xa5e1,0xa5e2,0xa5e3,0xa5e4,0xa5e5,0xa5e6,0xa5e7,
+ 0xa5e8,0xa5e9,0xa5ea,0xa5eb,0xa5ec,0xa5ed,0xa5ee,0xa5ef,
+ 0xa5f0,0xa5f1,0xa5f2,0xa5f3,0xa5f4,0xa5f5,0xa5f6,0xa5f7,
+ 0xa5f8,0xa5f9,0xa5fa,0xa5fb,0xa5fc,0xa5fd,0xa5fe,0xa5ff,
+ 0xa600,0xa601,0xa602,0xa603,0xa604,0xa605,0xa606,0xa607,
+ 0xa608,0xa609,0xa60a,0xa60b,0xa60c,0xa60d,0xa60e,0xa60f,
+ 0xa610,0xa611,0xa612,0xa613,0xa614,0xa615,0xa616,0xa617,
+ 0xa618,0xa619,0xa61a,0xa61b,0xa61c,0xa61d,0xa61e,0xa61f,
+ 0xa620,0xa621,0xa622,0xa623,0xa624,0xa625,0xa626,0xa627,
+ 0xa628,0xa629,0xa62a,0xa62b,0xa62c,0xa62d,0xa62e,0xa62f,
+ 0xa630,0xa631,0xa632,0xa633,0xa634,0xa635,0xa636,0xa637,
+ 0xa638,0xa639,0xa63a,0xa63b,0xa63c,0xa63d,0xa63e,0xa63f,
+ 0xa640,0xa641,0xa642,0xa643,0xa644,0xa645,0xa646,0xa647,
+ 0xa648,0xa649,0xa64a,0xa64b,0xa64c,0xa64d,0xa64e,0xa64f,
+ 0xa650,0xa651,0xa652,0xa653,0xa654,0xa655,0xa656,0xa657,
+ 0xa658,0xa659,0xa65a,0xa65b,0xa65c,0xa65d,0xa65e,0xa65f,
+ 0xa660,0xa661,0xa662,0xa663,0xa664,0xa665,0xa666,0xa667,
+ 0xa668,0xa669,0xa66a,0xa66b,0xa66c,0xa66d,0xa66e,0xa66f,
+ 0xa670,0xa671,0xa672,0xa673,0xa674,0xa675,0xa676,0xa677,
+ 0xa678,0xa679,0xa67a,0xa67b,0xa67c,0xa67d,0xa67e,0xa67f,
+ 0xa680,0xa681,0xa682,0xa683,0xa684,0xa685,0xa686,0xa687,
+ 0xa688,0xa689,0xa68a,0xa68b,0xa68c,0xa68d,0xa68e,0xa68f,
+ 0xa690,0xa691,0xa692,0xa693,0xa694,0xa695,0xa696,0xa697,
+ 0xa698,0xa699,0xa69a,0xa69b,0xa69c,0xa69d,0xa69e,0xa69f,
+ 0xa6a0,0xa6a1,0xa6a2,0xa6a3,0xa6a4,0xa6a5,0xa6a6,0xa6a7,
+ 0xa6a8,0xa6a9,0xa6aa,0xa6ab,0xa6ac,0xa6ad,0xa6ae,0xa6af,
+ 0xa6b0,0xa6b1,0xa6b2,0xa6b3,0xa6b4,0xa6b5,0xa6b6,0xa6b7,
+ 0xa6b8,0xa6b9,0xa6ba,0xa6bb,0xa6bc,0xa6bd,0xa6be,0xa6bf,
+ 0xa6c0,0xa6c1,0xa6c2,0xa6c3,0xa6c4,0xa6c5,0xa6c6,0xa6c7,
+ 0xa6c8,0xa6c9,0xa6ca,0xa6cb,0xa6cc,0xa6cd,0xa6ce,0xa6cf,
+ 0xa6d0,0xa6d1,0xa6d2,0xa6d3,0xa6d4,0xa6d5,0xa6d6,0xa6d7,
+ 0xa6d8,0xa6d9,0xa6da,0xa6db,0xa6dc,0xa6dd,0xa6de,0xa6df,
+ 0xa6e0,0xa6e1,0xa6e2,0xa6e3,0xa6e4,0xa6e5,0xa6e6,0xa6e7,
+ 0xa6e8,0xa6e9,0xa6ea,0xa6eb,0xa6ec,0xa6ed,0xa6ee,0xa6ef,
+ 0xa6f0,0xa6f1,0xa6f2,0xa6f3,0xa6f4,0xa6f5,0xa6f6,0xa6f7,
+ 0xa6f8,0xa6f9,0xa6fa,0xa6fb,0xa6fc,0xa6fd,0xa6fe,0xa6ff,
+ 0xa700,0xa701,0xa702,0xa703,0xa704,0xa705,0xa706,0xa707,
+ 0xa708,0xa709,0xa70a,0xa70b,0xa70c,0xa70d,0xa70e,0xa70f,
+ 0xa710,0xa711,0xa712,0xa713,0xa714,0xa715,0xa716,0xa717,
+ 0xa718,0xa719,0xa71a,0xa71b,0xa71c,0xa71d,0xa71e,0xa71f,
+ 0xa720,0xa721,0xa722,0xa723,0xa724,0xa725,0xa726,0xa727,
+ 0xa728,0xa729,0xa72a,0xa72b,0xa72c,0xa72d,0xa72e,0xa72f,
+ 0xa730,0xa731,0xa732,0xa733,0xa734,0xa735,0xa736,0xa737,
+ 0xa738,0xa739,0xa73a,0xa73b,0xa73c,0xa73d,0xa73e,0xa73f,
+ 0xa740,0xa741,0xa742,0xa743,0xa744,0xa745,0xa746,0xa747,
+ 0xa748,0xa749,0xa74a,0xa74b,0xa74c,0xa74d,0xa74e,0xa74f,
+ 0xa750,0xa751,0xa752,0xa753,0xa754,0xa755,0xa756,0xa757,
+ 0xa758,0xa759,0xa75a,0xa75b,0xa75c,0xa75d,0xa75e,0xa75f,
+ 0xa760,0xa761,0xa762,0xa763,0xa764,0xa765,0xa766,0xa767,
+ 0xa768,0xa769,0xa76a,0xa76b,0xa76c,0xa76d,0xa76e,0xa76f,
+ 0xa770,0xa771,0xa772,0xa773,0xa774,0xa775,0xa776,0xa777,
+ 0xa778,0xa779,0xa77a,0xa77b,0xa77c,0xa77d,0xa77e,0xa77f,
+ 0xa780,0xa781,0xa782,0xa783,0xa784,0xa785,0xa786,0xa787,
+ 0xa788,0xa789,0xa78a,0xa78b,0xa78c,0xa78d,0xa78e,0xa78f,
+ 0xa790,0xa791,0xa792,0xa793,0xa794,0xa795,0xa796,0xa797,
+ 0xa798,0xa799,0xa79a,0xa79b,0xa79c,0xa79d,0xa79e,0xa79f,
+ 0xa7a0,0xa7a1,0xa7a2,0xa7a3,0xa7a4,0xa7a5,0xa7a6,0xa7a7,
+ 0xa7a8,0xa7a9,0xa7aa,0xa7ab,0xa7ac,0xa7ad,0xa7ae,0xa7af,
+ 0xa7b0,0xa7b1,0xa7b2,0xa7b3,0xa7b4,0xa7b5,0xa7b6,0xa7b7,
+ 0xa7b8,0xa7b9,0xa7ba,0xa7bb,0xa7bc,0xa7bd,0xa7be,0xa7bf,
+ 0xa7c0,0xa7c1,0xa7c2,0xa7c3,0xa7c4,0xa7c5,0xa7c6,0xa7c7,
+ 0xa7c8,0xa7c9,0xa7ca,0xa7cb,0xa7cc,0xa7cd,0xa7ce,0xa7cf,
+ 0xa7d0,0xa7d1,0xa7d2,0xa7d3,0xa7d4,0xa7d5,0xa7d6,0xa7d7,
+ 0xa7d8,0xa7d9,0xa7da,0xa7db,0xa7dc,0xa7dd,0xa7de,0xa7df,
+ 0xa7e0,0xa7e1,0xa7e2,0xa7e3,0xa7e4,0xa7e5,0xa7e6,0xa7e7,
+ 0xa7e8,0xa7e9,0xa7ea,0xa7eb,0xa7ec,0xa7ed,0xa7ee,0xa7ef,
+ 0xa7f0,0xa7f1,0xa7f2,0xa7f3,0xa7f4,0xa7f5,0xa7f6,0xa7f7,
+ 0xa7f8,0xa7f9,0xa7fa,0xa7fb,0xa7fc,0xa7fd,0xa7fe,0xa7ff,
+ 0xa800,0xa801,0xa802,0xa803,0xa804,0xa805,0xa806,0xa807,
+ 0xa808,0xa809,0xa80a,0xa80b,0xa80c,0xa80d,0xa80e,0xa80f,
+ 0xa810,0xa811,0xa812,0xa813,0xa814,0xa815,0xa816,0xa817,
+ 0xa818,0xa819,0xa81a,0xa81b,0xa81c,0xa81d,0xa81e,0xa81f,
+ 0xa820,0xa821,0xa822,0xa823,0xa824,0xa825,0xa826,0xa827,
+ 0xa828,0xa829,0xa82a,0xa82b,0xa82c,0xa82d,0xa82e,0xa82f,
+ 0xa830,0xa831,0xa832,0xa833,0xa834,0xa835,0xa836,0xa837,
+ 0xa838,0xa839,0xa83a,0xa83b,0xa83c,0xa83d,0xa83e,0xa83f,
+ 0xa840,0xa841,0xa842,0xa843,0xa844,0xa845,0xa846,0xa847,
+ 0xa848,0xa849,0xa84a,0xa84b,0xa84c,0xa84d,0xa84e,0xa84f,
+ 0xa850,0xa851,0xa852,0xa853,0xa854,0xa855,0xa856,0xa857,
+ 0xa858,0xa859,0xa85a,0xa85b,0xa85c,0xa85d,0xa85e,0xa85f,
+ 0xa860,0xa861,0xa862,0xa863,0xa864,0xa865,0xa866,0xa867,
+ 0xa868,0xa869,0xa86a,0xa86b,0xa86c,0xa86d,0xa86e,0xa86f,
+ 0xa870,0xa871,0xa872,0xa873,0xa874,0xa875,0xa876,0xa877,
+ 0xa878,0xa879,0xa87a,0xa87b,0xa87c,0xa87d,0xa87e,0xa87f,
+ 0xa880,0xa881,0xa882,0xa883,0xa884,0xa885,0xa886,0xa887,
+ 0xa888,0xa889,0xa88a,0xa88b,0xa88c,0xa88d,0xa88e,0xa88f,
+ 0xa890,0xa891,0xa892,0xa893,0xa894,0xa895,0xa896,0xa897,
+ 0xa898,0xa899,0xa89a,0xa89b,0xa89c,0xa89d,0xa89e,0xa89f,
+ 0xa8a0,0xa8a1,0xa8a2,0xa8a3,0xa8a4,0xa8a5,0xa8a6,0xa8a7,
+ 0xa8a8,0xa8a9,0xa8aa,0xa8ab,0xa8ac,0xa8ad,0xa8ae,0xa8af,
+ 0xa8b0,0xa8b1,0xa8b2,0xa8b3,0xa8b4,0xa8b5,0xa8b6,0xa8b7,
+ 0xa8b8,0xa8b9,0xa8ba,0xa8bb,0xa8bc,0xa8bd,0xa8be,0xa8bf,
+ 0xa8c0,0xa8c1,0xa8c2,0xa8c3,0xa8c4,0xa8c5,0xa8c6,0xa8c7,
+ 0xa8c8,0xa8c9,0xa8ca,0xa8cb,0xa8cc,0xa8cd,0xa8ce,0xa8cf,
+ 0xa8d0,0xa8d1,0xa8d2,0xa8d3,0xa8d4,0xa8d5,0xa8d6,0xa8d7,
+ 0xa8d8,0xa8d9,0xa8da,0xa8db,0xa8dc,0xa8dd,0xa8de,0xa8df,
+ 0xa8e0,0xa8e1,0xa8e2,0xa8e3,0xa8e4,0xa8e5,0xa8e6,0xa8e7,
+ 0xa8e8,0xa8e9,0xa8ea,0xa8eb,0xa8ec,0xa8ed,0xa8ee,0xa8ef,
+ 0xa8f0,0xa8f1,0xa8f2,0xa8f3,0xa8f4,0xa8f5,0xa8f6,0xa8f7,
+ 0xa8f8,0xa8f9,0xa8fa,0xa8fb,0xa8fc,0xa8fd,0xa8fe,0xa8ff,
+ 0xa900,0xa901,0xa902,0xa903,0xa904,0xa905,0xa906,0xa907,
+ 0xa908,0xa909,0xa90a,0xa90b,0xa90c,0xa90d,0xa90e,0xa90f,
+ 0xa910,0xa911,0xa912,0xa913,0xa914,0xa915,0xa916,0xa917,
+ 0xa918,0xa919,0xa91a,0xa91b,0xa91c,0xa91d,0xa91e,0xa91f,
+ 0xa920,0xa921,0xa922,0xa923,0xa924,0xa925,0xa926,0xa927,
+ 0xa928,0xa929,0xa92a,0xa92b,0xa92c,0xa92d,0xa92e,0xa92f,
+ 0xa930,0xa931,0xa932,0xa933,0xa934,0xa935,0xa936,0xa937,
+ 0xa938,0xa939,0xa93a,0xa93b,0xa93c,0xa93d,0xa93e,0xa93f,
+ 0xa940,0xa941,0xa942,0xa943,0xa944,0xa945,0xa946,0xa947,
+ 0xa948,0xa949,0xa94a,0xa94b,0xa94c,0xa94d,0xa94e,0xa94f,
+ 0xa950,0xa951,0xa952,0xa953,0xa954,0xa955,0xa956,0xa957,
+ 0xa958,0xa959,0xa95a,0xa95b,0xa95c,0xa95d,0xa95e,0xa95f,
+ 0xa960,0xa961,0xa962,0xa963,0xa964,0xa965,0xa966,0xa967,
+ 0xa968,0xa969,0xa96a,0xa96b,0xa96c,0xa96d,0xa96e,0xa96f,
+ 0xa970,0xa971,0xa972,0xa973,0xa974,0xa975,0xa976,0xa977,
+ 0xa978,0xa979,0xa97a,0xa97b,0xa97c,0xa97d,0xa97e,0xa97f,
+ 0xa980,0xa981,0xa982,0xa983,0xa984,0xa985,0xa986,0xa987,
+ 0xa988,0xa989,0xa98a,0xa98b,0xa98c,0xa98d,0xa98e,0xa98f,
+ 0xa990,0xa991,0xa992,0xa993,0xa994,0xa995,0xa996,0xa997,
+ 0xa998,0xa999,0xa99a,0xa99b,0xa99c,0xa99d,0xa99e,0xa99f,
+ 0xa9a0,0xa9a1,0xa9a2,0xa9a3,0xa9a4,0xa9a5,0xa9a6,0xa9a7,
+ 0xa9a8,0xa9a9,0xa9aa,0xa9ab,0xa9ac,0xa9ad,0xa9ae,0xa9af,
+ 0xa9b0,0xa9b1,0xa9b2,0xa9b3,0xa9b4,0xa9b5,0xa9b6,0xa9b7,
+ 0xa9b8,0xa9b9,0xa9ba,0xa9bb,0xa9bc,0xa9bd,0xa9be,0xa9bf,
+ 0xa9c0,0xa9c1,0xa9c2,0xa9c3,0xa9c4,0xa9c5,0xa9c6,0xa9c7,
+ 0xa9c8,0xa9c9,0xa9ca,0xa9cb,0xa9cc,0xa9cd,0xa9ce,0xa9cf,
+ 0xa9d0,0xa9d1,0xa9d2,0xa9d3,0xa9d4,0xa9d5,0xa9d6,0xa9d7,
+ 0xa9d8,0xa9d9,0xa9da,0xa9db,0xa9dc,0xa9dd,0xa9de,0xa9df,
+ 0xa9e0,0xa9e1,0xa9e2,0xa9e3,0xa9e4,0xa9e5,0xa9e6,0xa9e7,
+ 0xa9e8,0xa9e9,0xa9ea,0xa9eb,0xa9ec,0xa9ed,0xa9ee,0xa9ef,
+ 0xa9f0,0xa9f1,0xa9f2,0xa9f3,0xa9f4,0xa9f5,0xa9f6,0xa9f7,
+ 0xa9f8,0xa9f9,0xa9fa,0xa9fb,0xa9fc,0xa9fd,0xa9fe,0xa9ff,
+ 0xaa00,0xaa01,0xaa02,0xaa03,0xaa04,0xaa05,0xaa06,0xaa07,
+ 0xaa08,0xaa09,0xaa0a,0xaa0b,0xaa0c,0xaa0d,0xaa0e,0xaa0f,
+ 0xaa10,0xaa11,0xaa12,0xaa13,0xaa14,0xaa15,0xaa16,0xaa17,
+ 0xaa18,0xaa19,0xaa1a,0xaa1b,0xaa1c,0xaa1d,0xaa1e,0xaa1f,
+ 0xaa20,0xaa21,0xaa22,0xaa23,0xaa24,0xaa25,0xaa26,0xaa27,
+ 0xaa28,0xaa29,0xaa2a,0xaa2b,0xaa2c,0xaa2d,0xaa2e,0xaa2f,
+ 0xaa30,0xaa31,0xaa32,0xaa33,0xaa34,0xaa35,0xaa36,0xaa37,
+ 0xaa38,0xaa39,0xaa3a,0xaa3b,0xaa3c,0xaa3d,0xaa3e,0xaa3f,
+ 0xaa40,0xaa41,0xaa42,0xaa43,0xaa44,0xaa45,0xaa46,0xaa47,
+ 0xaa48,0xaa49,0xaa4a,0xaa4b,0xaa4c,0xaa4d,0xaa4e,0xaa4f,
+ 0xaa50,0xaa51,0xaa52,0xaa53,0xaa54,0xaa55,0xaa56,0xaa57,
+ 0xaa58,0xaa59,0xaa5a,0xaa5b,0xaa5c,0xaa5d,0xaa5e,0xaa5f,
+ 0xaa60,0xaa61,0xaa62,0xaa63,0xaa64,0xaa65,0xaa66,0xaa67,
+ 0xaa68,0xaa69,0xaa6a,0xaa6b,0xaa6c,0xaa6d,0xaa6e,0xaa6f,
+ 0xaa70,0xaa71,0xaa72,0xaa73,0xaa74,0xaa75,0xaa76,0xaa77,
+ 0xaa78,0xaa79,0xaa7a,0xaa7b,0xaa7c,0xaa7d,0xaa7e,0xaa7f,
+ 0xaa80,0xaa81,0xaa82,0xaa83,0xaa84,0xaa85,0xaa86,0xaa87,
+ 0xaa88,0xaa89,0xaa8a,0xaa8b,0xaa8c,0xaa8d,0xaa8e,0xaa8f,
+ 0xaa90,0xaa91,0xaa92,0xaa93,0xaa94,0xaa95,0xaa96,0xaa97,
+ 0xaa98,0xaa99,0xaa9a,0xaa9b,0xaa9c,0xaa9d,0xaa9e,0xaa9f,
+ 0xaaa0,0xaaa1,0xaaa2,0xaaa3,0xaaa4,0xaaa5,0xaaa6,0xaaa7,
+ 0xaaa8,0xaaa9,0xaaaa,0xaaab,0xaaac,0xaaad,0xaaae,0xaaaf,
+ 0xaab0,0xaab1,0xaab2,0xaab3,0xaab4,0xaab5,0xaab6,0xaab7,
+ 0xaab8,0xaab9,0xaaba,0xaabb,0xaabc,0xaabd,0xaabe,0xaabf,
+ 0xaac0,0xaac1,0xaac2,0xaac3,0xaac4,0xaac5,0xaac6,0xaac7,
+ 0xaac8,0xaac9,0xaaca,0xaacb,0xaacc,0xaacd,0xaace,0xaacf,
+ 0xaad0,0xaad1,0xaad2,0xaad3,0xaad4,0xaad5,0xaad6,0xaad7,
+ 0xaad8,0xaad9,0xaada,0xaadb,0xaadc,0xaadd,0xaade,0xaadf,
+ 0xaae0,0xaae1,0xaae2,0xaae3,0xaae4,0xaae5,0xaae6,0xaae7,
+ 0xaae8,0xaae9,0xaaea,0xaaeb,0xaaec,0xaaed,0xaaee,0xaaef,
+ 0xaaf0,0xaaf1,0xaaf2,0xaaf3,0xaaf4,0xaaf5,0xaaf6,0xaaf7,
+ 0xaaf8,0xaaf9,0xaafa,0xaafb,0xaafc,0xaafd,0xaafe,0xaaff,
+ 0xab00,0xab01,0xab02,0xab03,0xab04,0xab05,0xab06,0xab07,
+ 0xab08,0xab09,0xab0a,0xab0b,0xab0c,0xab0d,0xab0e,0xab0f,
+ 0xab10,0xab11,0xab12,0xab13,0xab14,0xab15,0xab16,0xab17,
+ 0xab18,0xab19,0xab1a,0xab1b,0xab1c,0xab1d,0xab1e,0xab1f,
+ 0xab20,0xab21,0xab22,0xab23,0xab24,0xab25,0xab26,0xab27,
+ 0xab28,0xab29,0xab2a,0xab2b,0xab2c,0xab2d,0xab2e,0xab2f,
+ 0xab30,0xab31,0xab32,0xab33,0xab34,0xab35,0xab36,0xab37,
+ 0xab38,0xab39,0xab3a,0xab3b,0xab3c,0xab3d,0xab3e,0xab3f,
+ 0xab40,0xab41,0xab42,0xab43,0xab44,0xab45,0xab46,0xab47,
+ 0xab48,0xab49,0xab4a,0xab4b,0xab4c,0xab4d,0xab4e,0xab4f,
+ 0xab50,0xab51,0xab52,0xab53,0xab54,0xab55,0xab56,0xab57,
+ 0xab58,0xab59,0xab5a,0xab5b,0xab5c,0xab5d,0xab5e,0xab5f,
+ 0xab60,0xab61,0xab62,0xab63,0xab64,0xab65,0xab66,0xab67,
+ 0xab68,0xab69,0xab6a,0xab6b,0xab6c,0xab6d,0xab6e,0xab6f,
+ 0xab70,0xab71,0xab72,0xab73,0xab74,0xab75,0xab76,0xab77,
+ 0xab78,0xab79,0xab7a,0xab7b,0xab7c,0xab7d,0xab7e,0xab7f,
+ 0xab80,0xab81,0xab82,0xab83,0xab84,0xab85,0xab86,0xab87,
+ 0xab88,0xab89,0xab8a,0xab8b,0xab8c,0xab8d,0xab8e,0xab8f,
+ 0xab90,0xab91,0xab92,0xab93,0xab94,0xab95,0xab96,0xab97,
+ 0xab98,0xab99,0xab9a,0xab9b,0xab9c,0xab9d,0xab9e,0xab9f,
+ 0xaba0,0xaba1,0xaba2,0xaba3,0xaba4,0xaba5,0xaba6,0xaba7,
+ 0xaba8,0xaba9,0xabaa,0xabab,0xabac,0xabad,0xabae,0xabaf,
+ 0xabb0,0xabb1,0xabb2,0xabb3,0xabb4,0xabb5,0xabb6,0xabb7,
+ 0xabb8,0xabb9,0xabba,0xabbb,0xabbc,0xabbd,0xabbe,0xabbf,
+ 0xabc0,0xabc1,0xabc2,0xabc3,0xabc4,0xabc5,0xabc6,0xabc7,
+ 0xabc8,0xabc9,0xabca,0xabcb,0xabcc,0xabcd,0xabce,0xabcf,
+ 0xabd0,0xabd1,0xabd2,0xabd3,0xabd4,0xabd5,0xabd6,0xabd7,
+ 0xabd8,0xabd9,0xabda,0xabdb,0xabdc,0xabdd,0xabde,0xabdf,
+ 0xabe0,0xabe1,0xabe2,0xabe3,0xabe4,0xabe5,0xabe6,0xabe7,
+ 0xabe8,0xabe9,0xabea,0xabeb,0xabec,0xabed,0xabee,0xabef,
+ 0xabf0,0xabf1,0xabf2,0xabf3,0xabf4,0xabf5,0xabf6,0xabf7,
+ 0xabf8,0xabf9,0xabfa,0xabfb,0xabfc,0xabfd,0xabfe,0xabff,
+ 0xac00,0xac01,0xac02,0xac03,0xac04,0xac05,0xac06,0xac07,
+ 0xac08,0xac09,0xac0a,0xac0b,0xac0c,0xac0d,0xac0e,0xac0f,
+ 0xac10,0xac11,0xac12,0xac13,0xac14,0xac15,0xac16,0xac17,
+ 0xac18,0xac19,0xac1a,0xac1b,0xac1c,0xac1d,0xac1e,0xac1f,
+ 0xac20,0xac21,0xac22,0xac23,0xac24,0xac25,0xac26,0xac27,
+ 0xac28,0xac29,0xac2a,0xac2b,0xac2c,0xac2d,0xac2e,0xac2f,
+ 0xac30,0xac31,0xac32,0xac33,0xac34,0xac35,0xac36,0xac37,
+ 0xac38,0xac39,0xac3a,0xac3b,0xac3c,0xac3d,0xac3e,0xac3f,
+ 0xac40,0xac41,0xac42,0xac43,0xac44,0xac45,0xac46,0xac47,
+ 0xac48,0xac49,0xac4a,0xac4b,0xac4c,0xac4d,0xac4e,0xac4f,
+ 0xac50,0xac51,0xac52,0xac53,0xac54,0xac55,0xac56,0xac57,
+ 0xac58,0xac59,0xac5a,0xac5b,0xac5c,0xac5d,0xac5e,0xac5f,
+ 0xac60,0xac61,0xac62,0xac63,0xac64,0xac65,0xac66,0xac67,
+ 0xac68,0xac69,0xac6a,0xac6b,0xac6c,0xac6d,0xac6e,0xac6f,
+ 0xac70,0xac71,0xac72,0xac73,0xac74,0xac75,0xac76,0xac77,
+ 0xac78,0xac79,0xac7a,0xac7b,0xac7c,0xac7d,0xac7e,0xac7f,
+ 0xac80,0xac81,0xac82,0xac83,0xac84,0xac85,0xac86,0xac87,
+ 0xac88,0xac89,0xac8a,0xac8b,0xac8c,0xac8d,0xac8e,0xac8f,
+ 0xac90,0xac91,0xac92,0xac93,0xac94,0xac95,0xac96,0xac97,
+ 0xac98,0xac99,0xac9a,0xac9b,0xac9c,0xac9d,0xac9e,0xac9f,
+ 0xaca0,0xaca1,0xaca2,0xaca3,0xaca4,0xaca5,0xaca6,0xaca7,
+ 0xaca8,0xaca9,0xacaa,0xacab,0xacac,0xacad,0xacae,0xacaf,
+ 0xacb0,0xacb1,0xacb2,0xacb3,0xacb4,0xacb5,0xacb6,0xacb7,
+ 0xacb8,0xacb9,0xacba,0xacbb,0xacbc,0xacbd,0xacbe,0xacbf,
+ 0xacc0,0xacc1,0xacc2,0xacc3,0xacc4,0xacc5,0xacc6,0xacc7,
+ 0xacc8,0xacc9,0xacca,0xaccb,0xaccc,0xaccd,0xacce,0xaccf,
+ 0xacd0,0xacd1,0xacd2,0xacd3,0xacd4,0xacd5,0xacd6,0xacd7,
+ 0xacd8,0xacd9,0xacda,0xacdb,0xacdc,0xacdd,0xacde,0xacdf,
+ 0xace0,0xace1,0xace2,0xace3,0xace4,0xace5,0xace6,0xace7,
+ 0xace8,0xace9,0xacea,0xaceb,0xacec,0xaced,0xacee,0xacef,
+ 0xacf0,0xacf1,0xacf2,0xacf3,0xacf4,0xacf5,0xacf6,0xacf7,
+ 0xacf8,0xacf9,0xacfa,0xacfb,0xacfc,0xacfd,0xacfe,0xacff,
+ 0xad00,0xad01,0xad02,0xad03,0xad04,0xad05,0xad06,0xad07,
+ 0xad08,0xad09,0xad0a,0xad0b,0xad0c,0xad0d,0xad0e,0xad0f,
+ 0xad10,0xad11,0xad12,0xad13,0xad14,0xad15,0xad16,0xad17,
+ 0xad18,0xad19,0xad1a,0xad1b,0xad1c,0xad1d,0xad1e,0xad1f,
+ 0xad20,0xad21,0xad22,0xad23,0xad24,0xad25,0xad26,0xad27,
+ 0xad28,0xad29,0xad2a,0xad2b,0xad2c,0xad2d,0xad2e,0xad2f,
+ 0xad30,0xad31,0xad32,0xad33,0xad34,0xad35,0xad36,0xad37,
+ 0xad38,0xad39,0xad3a,0xad3b,0xad3c,0xad3d,0xad3e,0xad3f,
+ 0xad40,0xad41,0xad42,0xad43,0xad44,0xad45,0xad46,0xad47,
+ 0xad48,0xad49,0xad4a,0xad4b,0xad4c,0xad4d,0xad4e,0xad4f,
+ 0xad50,0xad51,0xad52,0xad53,0xad54,0xad55,0xad56,0xad57,
+ 0xad58,0xad59,0xad5a,0xad5b,0xad5c,0xad5d,0xad5e,0xad5f,
+ 0xad60,0xad61,0xad62,0xad63,0xad64,0xad65,0xad66,0xad67,
+ 0xad68,0xad69,0xad6a,0xad6b,0xad6c,0xad6d,0xad6e,0xad6f,
+ 0xad70,0xad71,0xad72,0xad73,0xad74,0xad75,0xad76,0xad77,
+ 0xad78,0xad79,0xad7a,0xad7b,0xad7c,0xad7d,0xad7e,0xad7f,
+ 0xad80,0xad81,0xad82,0xad83,0xad84,0xad85,0xad86,0xad87,
+ 0xad88,0xad89,0xad8a,0xad8b,0xad8c,0xad8d,0xad8e,0xad8f,
+ 0xad90,0xad91,0xad92,0xad93,0xad94,0xad95,0xad96,0xad97,
+ 0xad98,0xad99,0xad9a,0xad9b,0xad9c,0xad9d,0xad9e,0xad9f,
+ 0xada0,0xada1,0xada2,0xada3,0xada4,0xada5,0xada6,0xada7,
+ 0xada8,0xada9,0xadaa,0xadab,0xadac,0xadad,0xadae,0xadaf,
+ 0xadb0,0xadb1,0xadb2,0xadb3,0xadb4,0xadb5,0xadb6,0xadb7,
+ 0xadb8,0xadb9,0xadba,0xadbb,0xadbc,0xadbd,0xadbe,0xadbf,
+ 0xadc0,0xadc1,0xadc2,0xadc3,0xadc4,0xadc5,0xadc6,0xadc7,
+ 0xadc8,0xadc9,0xadca,0xadcb,0xadcc,0xadcd,0xadce,0xadcf,
+ 0xadd0,0xadd1,0xadd2,0xadd3,0xadd4,0xadd5,0xadd6,0xadd7,
+ 0xadd8,0xadd9,0xadda,0xaddb,0xaddc,0xaddd,0xadde,0xaddf,
+ 0xade0,0xade1,0xade2,0xade3,0xade4,0xade5,0xade6,0xade7,
+ 0xade8,0xade9,0xadea,0xadeb,0xadec,0xaded,0xadee,0xadef,
+ 0xadf0,0xadf1,0xadf2,0xadf3,0xadf4,0xadf5,0xadf6,0xadf7,
+ 0xadf8,0xadf9,0xadfa,0xadfb,0xadfc,0xadfd,0xadfe,0xadff,
+ 0xae00,0xae01,0xae02,0xae03,0xae04,0xae05,0xae06,0xae07,
+ 0xae08,0xae09,0xae0a,0xae0b,0xae0c,0xae0d,0xae0e,0xae0f,
+ 0xae10,0xae11,0xae12,0xae13,0xae14,0xae15,0xae16,0xae17,
+ 0xae18,0xae19,0xae1a,0xae1b,0xae1c,0xae1d,0xae1e,0xae1f,
+ 0xae20,0xae21,0xae22,0xae23,0xae24,0xae25,0xae26,0xae27,
+ 0xae28,0xae29,0xae2a,0xae2b,0xae2c,0xae2d,0xae2e,0xae2f,
+ 0xae30,0xae31,0xae32,0xae33,0xae34,0xae35,0xae36,0xae37,
+ 0xae38,0xae39,0xae3a,0xae3b,0xae3c,0xae3d,0xae3e,0xae3f,
+ 0xae40,0xae41,0xae42,0xae43,0xae44,0xae45,0xae46,0xae47,
+ 0xae48,0xae49,0xae4a,0xae4b,0xae4c,0xae4d,0xae4e,0xae4f,
+ 0xae50,0xae51,0xae52,0xae53,0xae54,0xae55,0xae56,0xae57,
+ 0xae58,0xae59,0xae5a,0xae5b,0xae5c,0xae5d,0xae5e,0xae5f,
+ 0xae60,0xae61,0xae62,0xae63,0xae64,0xae65,0xae66,0xae67,
+ 0xae68,0xae69,0xae6a,0xae6b,0xae6c,0xae6d,0xae6e,0xae6f,
+ 0xae70,0xae71,0xae72,0xae73,0xae74,0xae75,0xae76,0xae77,
+ 0xae78,0xae79,0xae7a,0xae7b,0xae7c,0xae7d,0xae7e,0xae7f,
+ 0xae80,0xae81,0xae82,0xae83,0xae84,0xae85,0xae86,0xae87,
+ 0xae88,0xae89,0xae8a,0xae8b,0xae8c,0xae8d,0xae8e,0xae8f,
+ 0xae90,0xae91,0xae92,0xae93,0xae94,0xae95,0xae96,0xae97,
+ 0xae98,0xae99,0xae9a,0xae9b,0xae9c,0xae9d,0xae9e,0xae9f,
+ 0xaea0,0xaea1,0xaea2,0xaea3,0xaea4,0xaea5,0xaea6,0xaea7,
+ 0xaea8,0xaea9,0xaeaa,0xaeab,0xaeac,0xaead,0xaeae,0xaeaf,
+ 0xaeb0,0xaeb1,0xaeb2,0xaeb3,0xaeb4,0xaeb5,0xaeb6,0xaeb7,
+ 0xaeb8,0xaeb9,0xaeba,0xaebb,0xaebc,0xaebd,0xaebe,0xaebf,
+ 0xaec0,0xaec1,0xaec2,0xaec3,0xaec4,0xaec5,0xaec6,0xaec7,
+ 0xaec8,0xaec9,0xaeca,0xaecb,0xaecc,0xaecd,0xaece,0xaecf,
+ 0xaed0,0xaed1,0xaed2,0xaed3,0xaed4,0xaed5,0xaed6,0xaed7,
+ 0xaed8,0xaed9,0xaeda,0xaedb,0xaedc,0xaedd,0xaede,0xaedf,
+ 0xaee0,0xaee1,0xaee2,0xaee3,0xaee4,0xaee5,0xaee6,0xaee7,
+ 0xaee8,0xaee9,0xaeea,0xaeeb,0xaeec,0xaeed,0xaeee,0xaeef,
+ 0xaef0,0xaef1,0xaef2,0xaef3,0xaef4,0xaef5,0xaef6,0xaef7,
+ 0xaef8,0xaef9,0xaefa,0xaefb,0xaefc,0xaefd,0xaefe,0xaeff,
+ 0xaf00,0xaf01,0xaf02,0xaf03,0xaf04,0xaf05,0xaf06,0xaf07,
+ 0xaf08,0xaf09,0xaf0a,0xaf0b,0xaf0c,0xaf0d,0xaf0e,0xaf0f,
+ 0xaf10,0xaf11,0xaf12,0xaf13,0xaf14,0xaf15,0xaf16,0xaf17,
+ 0xaf18,0xaf19,0xaf1a,0xaf1b,0xaf1c,0xaf1d,0xaf1e,0xaf1f,
+ 0xaf20,0xaf21,0xaf22,0xaf23,0xaf24,0xaf25,0xaf26,0xaf27,
+ 0xaf28,0xaf29,0xaf2a,0xaf2b,0xaf2c,0xaf2d,0xaf2e,0xaf2f,
+ 0xaf30,0xaf31,0xaf32,0xaf33,0xaf34,0xaf35,0xaf36,0xaf37,
+ 0xaf38,0xaf39,0xaf3a,0xaf3b,0xaf3c,0xaf3d,0xaf3e,0xaf3f,
+ 0xaf40,0xaf41,0xaf42,0xaf43,0xaf44,0xaf45,0xaf46,0xaf47,
+ 0xaf48,0xaf49,0xaf4a,0xaf4b,0xaf4c,0xaf4d,0xaf4e,0xaf4f,
+ 0xaf50,0xaf51,0xaf52,0xaf53,0xaf54,0xaf55,0xaf56,0xaf57,
+ 0xaf58,0xaf59,0xaf5a,0xaf5b,0xaf5c,0xaf5d,0xaf5e,0xaf5f,
+ 0xaf60,0xaf61,0xaf62,0xaf63,0xaf64,0xaf65,0xaf66,0xaf67,
+ 0xaf68,0xaf69,0xaf6a,0xaf6b,0xaf6c,0xaf6d,0xaf6e,0xaf6f,
+ 0xaf70,0xaf71,0xaf72,0xaf73,0xaf74,0xaf75,0xaf76,0xaf77,
+ 0xaf78,0xaf79,0xaf7a,0xaf7b,0xaf7c,0xaf7d,0xaf7e,0xaf7f,
+ 0xaf80,0xaf81,0xaf82,0xaf83,0xaf84,0xaf85,0xaf86,0xaf87,
+ 0xaf88,0xaf89,0xaf8a,0xaf8b,0xaf8c,0xaf8d,0xaf8e,0xaf8f,
+ 0xaf90,0xaf91,0xaf92,0xaf93,0xaf94,0xaf95,0xaf96,0xaf97,
+ 0xaf98,0xaf99,0xaf9a,0xaf9b,0xaf9c,0xaf9d,0xaf9e,0xaf9f,
+ 0xafa0,0xafa1,0xafa2,0xafa3,0xafa4,0xafa5,0xafa6,0xafa7,
+ 0xafa8,0xafa9,0xafaa,0xafab,0xafac,0xafad,0xafae,0xafaf,
+ 0xafb0,0xafb1,0xafb2,0xafb3,0xafb4,0xafb5,0xafb6,0xafb7,
+ 0xafb8,0xafb9,0xafba,0xafbb,0xafbc,0xafbd,0xafbe,0xafbf,
+ 0xafc0,0xafc1,0xafc2,0xafc3,0xafc4,0xafc5,0xafc6,0xafc7,
+ 0xafc8,0xafc9,0xafca,0xafcb,0xafcc,0xafcd,0xafce,0xafcf,
+ 0xafd0,0xafd1,0xafd2,0xafd3,0xafd4,0xafd5,0xafd6,0xafd7,
+ 0xafd8,0xafd9,0xafda,0xafdb,0xafdc,0xafdd,0xafde,0xafdf,
+ 0xafe0,0xafe1,0xafe2,0xafe3,0xafe4,0xafe5,0xafe6,0xafe7,
+ 0xafe8,0xafe9,0xafea,0xafeb,0xafec,0xafed,0xafee,0xafef,
+ 0xaff0,0xaff1,0xaff2,0xaff3,0xaff4,0xaff5,0xaff6,0xaff7,
+ 0xaff8,0xaff9,0xaffa,0xaffb,0xaffc,0xaffd,0xaffe,0xafff,
+ 0xb000,0xb001,0xb002,0xb003,0xb004,0xb005,0xb006,0xb007,
+ 0xb008,0xb009,0xb00a,0xb00b,0xb00c,0xb00d,0xb00e,0xb00f,
+ 0xb010,0xb011,0xb012,0xb013,0xb014,0xb015,0xb016,0xb017,
+ 0xb018,0xb019,0xb01a,0xb01b,0xb01c,0xb01d,0xb01e,0xb01f,
+ 0xb020,0xb021,0xb022,0xb023,0xb024,0xb025,0xb026,0xb027,
+ 0xb028,0xb029,0xb02a,0xb02b,0xb02c,0xb02d,0xb02e,0xb02f,
+ 0xb030,0xb031,0xb032,0xb033,0xb034,0xb035,0xb036,0xb037,
+ 0xb038,0xb039,0xb03a,0xb03b,0xb03c,0xb03d,0xb03e,0xb03f,
+ 0xb040,0xb041,0xb042,0xb043,0xb044,0xb045,0xb046,0xb047,
+ 0xb048,0xb049,0xb04a,0xb04b,0xb04c,0xb04d,0xb04e,0xb04f,
+ 0xb050,0xb051,0xb052,0xb053,0xb054,0xb055,0xb056,0xb057,
+ 0xb058,0xb059,0xb05a,0xb05b,0xb05c,0xb05d,0xb05e,0xb05f,
+ 0xb060,0xb061,0xb062,0xb063,0xb064,0xb065,0xb066,0xb067,
+ 0xb068,0xb069,0xb06a,0xb06b,0xb06c,0xb06d,0xb06e,0xb06f,
+ 0xb070,0xb071,0xb072,0xb073,0xb074,0xb075,0xb076,0xb077,
+ 0xb078,0xb079,0xb07a,0xb07b,0xb07c,0xb07d,0xb07e,0xb07f,
+ 0xb080,0xb081,0xb082,0xb083,0xb084,0xb085,0xb086,0xb087,
+ 0xb088,0xb089,0xb08a,0xb08b,0xb08c,0xb08d,0xb08e,0xb08f,
+ 0xb090,0xb091,0xb092,0xb093,0xb094,0xb095,0xb096,0xb097,
+ 0xb098,0xb099,0xb09a,0xb09b,0xb09c,0xb09d,0xb09e,0xb09f,
+ 0xb0a0,0xb0a1,0xb0a2,0xb0a3,0xb0a4,0xb0a5,0xb0a6,0xb0a7,
+ 0xb0a8,0xb0a9,0xb0aa,0xb0ab,0xb0ac,0xb0ad,0xb0ae,0xb0af,
+ 0xb0b0,0xb0b1,0xb0b2,0xb0b3,0xb0b4,0xb0b5,0xb0b6,0xb0b7,
+ 0xb0b8,0xb0b9,0xb0ba,0xb0bb,0xb0bc,0xb0bd,0xb0be,0xb0bf,
+ 0xb0c0,0xb0c1,0xb0c2,0xb0c3,0xb0c4,0xb0c5,0xb0c6,0xb0c7,
+ 0xb0c8,0xb0c9,0xb0ca,0xb0cb,0xb0cc,0xb0cd,0xb0ce,0xb0cf,
+ 0xb0d0,0xb0d1,0xb0d2,0xb0d3,0xb0d4,0xb0d5,0xb0d6,0xb0d7,
+ 0xb0d8,0xb0d9,0xb0da,0xb0db,0xb0dc,0xb0dd,0xb0de,0xb0df,
+ 0xb0e0,0xb0e1,0xb0e2,0xb0e3,0xb0e4,0xb0e5,0xb0e6,0xb0e7,
+ 0xb0e8,0xb0e9,0xb0ea,0xb0eb,0xb0ec,0xb0ed,0xb0ee,0xb0ef,
+ 0xb0f0,0xb0f1,0xb0f2,0xb0f3,0xb0f4,0xb0f5,0xb0f6,0xb0f7,
+ 0xb0f8,0xb0f9,0xb0fa,0xb0fb,0xb0fc,0xb0fd,0xb0fe,0xb0ff,
+ 0xb100,0xb101,0xb102,0xb103,0xb104,0xb105,0xb106,0xb107,
+ 0xb108,0xb109,0xb10a,0xb10b,0xb10c,0xb10d,0xb10e,0xb10f,
+ 0xb110,0xb111,0xb112,0xb113,0xb114,0xb115,0xb116,0xb117,
+ 0xb118,0xb119,0xb11a,0xb11b,0xb11c,0xb11d,0xb11e,0xb11f,
+ 0xb120,0xb121,0xb122,0xb123,0xb124,0xb125,0xb126,0xb127,
+ 0xb128,0xb129,0xb12a,0xb12b,0xb12c,0xb12d,0xb12e,0xb12f,
+ 0xb130,0xb131,0xb132,0xb133,0xb134,0xb135,0xb136,0xb137,
+ 0xb138,0xb139,0xb13a,0xb13b,0xb13c,0xb13d,0xb13e,0xb13f,
+ 0xb140,0xb141,0xb142,0xb143,0xb144,0xb145,0xb146,0xb147,
+ 0xb148,0xb149,0xb14a,0xb14b,0xb14c,0xb14d,0xb14e,0xb14f,
+ 0xb150,0xb151,0xb152,0xb153,0xb154,0xb155,0xb156,0xb157,
+ 0xb158,0xb159,0xb15a,0xb15b,0xb15c,0xb15d,0xb15e,0xb15f,
+ 0xb160,0xb161,0xb162,0xb163,0xb164,0xb165,0xb166,0xb167,
+ 0xb168,0xb169,0xb16a,0xb16b,0xb16c,0xb16d,0xb16e,0xb16f,
+ 0xb170,0xb171,0xb172,0xb173,0xb174,0xb175,0xb176,0xb177,
+ 0xb178,0xb179,0xb17a,0xb17b,0xb17c,0xb17d,0xb17e,0xb17f,
+ 0xb180,0xb181,0xb182,0xb183,0xb184,0xb185,0xb186,0xb187,
+ 0xb188,0xb189,0xb18a,0xb18b,0xb18c,0xb18d,0xb18e,0xb18f,
+ 0xb190,0xb191,0xb192,0xb193,0xb194,0xb195,0xb196,0xb197,
+ 0xb198,0xb199,0xb19a,0xb19b,0xb19c,0xb19d,0xb19e,0xb19f,
+ 0xb1a0,0xb1a1,0xb1a2,0xb1a3,0xb1a4,0xb1a5,0xb1a6,0xb1a7,
+ 0xb1a8,0xb1a9,0xb1aa,0xb1ab,0xb1ac,0xb1ad,0xb1ae,0xb1af,
+ 0xb1b0,0xb1b1,0xb1b2,0xb1b3,0xb1b4,0xb1b5,0xb1b6,0xb1b7,
+ 0xb1b8,0xb1b9,0xb1ba,0xb1bb,0xb1bc,0xb1bd,0xb1be,0xb1bf,
+ 0xb1c0,0xb1c1,0xb1c2,0xb1c3,0xb1c4,0xb1c5,0xb1c6,0xb1c7,
+ 0xb1c8,0xb1c9,0xb1ca,0xb1cb,0xb1cc,0xb1cd,0xb1ce,0xb1cf,
+ 0xb1d0,0xb1d1,0xb1d2,0xb1d3,0xb1d4,0xb1d5,0xb1d6,0xb1d7,
+ 0xb1d8,0xb1d9,0xb1da,0xb1db,0xb1dc,0xb1dd,0xb1de,0xb1df,
+ 0xb1e0,0xb1e1,0xb1e2,0xb1e3,0xb1e4,0xb1e5,0xb1e6,0xb1e7,
+ 0xb1e8,0xb1e9,0xb1ea,0xb1eb,0xb1ec,0xb1ed,0xb1ee,0xb1ef,
+ 0xb1f0,0xb1f1,0xb1f2,0xb1f3,0xb1f4,0xb1f5,0xb1f6,0xb1f7,
+ 0xb1f8,0xb1f9,0xb1fa,0xb1fb,0xb1fc,0xb1fd,0xb1fe,0xb1ff,
+ 0xb200,0xb201,0xb202,0xb203,0xb204,0xb205,0xb206,0xb207,
+ 0xb208,0xb209,0xb20a,0xb20b,0xb20c,0xb20d,0xb20e,0xb20f,
+ 0xb210,0xb211,0xb212,0xb213,0xb214,0xb215,0xb216,0xb217,
+ 0xb218,0xb219,0xb21a,0xb21b,0xb21c,0xb21d,0xb21e,0xb21f,
+ 0xb220,0xb221,0xb222,0xb223,0xb224,0xb225,0xb226,0xb227,
+ 0xb228,0xb229,0xb22a,0xb22b,0xb22c,0xb22d,0xb22e,0xb22f,
+ 0xb230,0xb231,0xb232,0xb233,0xb234,0xb235,0xb236,0xb237,
+ 0xb238,0xb239,0xb23a,0xb23b,0xb23c,0xb23d,0xb23e,0xb23f,
+ 0xb240,0xb241,0xb242,0xb243,0xb244,0xb245,0xb246,0xb247,
+ 0xb248,0xb249,0xb24a,0xb24b,0xb24c,0xb24d,0xb24e,0xb24f,
+ 0xb250,0xb251,0xb252,0xb253,0xb254,0xb255,0xb256,0xb257,
+ 0xb258,0xb259,0xb25a,0xb25b,0xb25c,0xb25d,0xb25e,0xb25f,
+ 0xb260,0xb261,0xb262,0xb263,0xb264,0xb265,0xb266,0xb267,
+ 0xb268,0xb269,0xb26a,0xb26b,0xb26c,0xb26d,0xb26e,0xb26f,
+ 0xb270,0xb271,0xb272,0xb273,0xb274,0xb275,0xb276,0xb277,
+ 0xb278,0xb279,0xb27a,0xb27b,0xb27c,0xb27d,0xb27e,0xb27f,
+ 0xb280,0xb281,0xb282,0xb283,0xb284,0xb285,0xb286,0xb287,
+ 0xb288,0xb289,0xb28a,0xb28b,0xb28c,0xb28d,0xb28e,0xb28f,
+ 0xb290,0xb291,0xb292,0xb293,0xb294,0xb295,0xb296,0xb297,
+ 0xb298,0xb299,0xb29a,0xb29b,0xb29c,0xb29d,0xb29e,0xb29f,
+ 0xb2a0,0xb2a1,0xb2a2,0xb2a3,0xb2a4,0xb2a5,0xb2a6,0xb2a7,
+ 0xb2a8,0xb2a9,0xb2aa,0xb2ab,0xb2ac,0xb2ad,0xb2ae,0xb2af,
+ 0xb2b0,0xb2b1,0xb2b2,0xb2b3,0xb2b4,0xb2b5,0xb2b6,0xb2b7,
+ 0xb2b8,0xb2b9,0xb2ba,0xb2bb,0xb2bc,0xb2bd,0xb2be,0xb2bf,
+ 0xb2c0,0xb2c1,0xb2c2,0xb2c3,0xb2c4,0xb2c5,0xb2c6,0xb2c7,
+ 0xb2c8,0xb2c9,0xb2ca,0xb2cb,0xb2cc,0xb2cd,0xb2ce,0xb2cf,
+ 0xb2d0,0xb2d1,0xb2d2,0xb2d3,0xb2d4,0xb2d5,0xb2d6,0xb2d7,
+ 0xb2d8,0xb2d9,0xb2da,0xb2db,0xb2dc,0xb2dd,0xb2de,0xb2df,
+ 0xb2e0,0xb2e1,0xb2e2,0xb2e3,0xb2e4,0xb2e5,0xb2e6,0xb2e7,
+ 0xb2e8,0xb2e9,0xb2ea,0xb2eb,0xb2ec,0xb2ed,0xb2ee,0xb2ef,
+ 0xb2f0,0xb2f1,0xb2f2,0xb2f3,0xb2f4,0xb2f5,0xb2f6,0xb2f7,
+ 0xb2f8,0xb2f9,0xb2fa,0xb2fb,0xb2fc,0xb2fd,0xb2fe,0xb2ff,
+ 0xb300,0xb301,0xb302,0xb303,0xb304,0xb305,0xb306,0xb307,
+ 0xb308,0xb309,0xb30a,0xb30b,0xb30c,0xb30d,0xb30e,0xb30f,
+ 0xb310,0xb311,0xb312,0xb313,0xb314,0xb315,0xb316,0xb317,
+ 0xb318,0xb319,0xb31a,0xb31b,0xb31c,0xb31d,0xb31e,0xb31f,
+ 0xb320,0xb321,0xb322,0xb323,0xb324,0xb325,0xb326,0xb327,
+ 0xb328,0xb329,0xb32a,0xb32b,0xb32c,0xb32d,0xb32e,0xb32f,
+ 0xb330,0xb331,0xb332,0xb333,0xb334,0xb335,0xb336,0xb337,
+ 0xb338,0xb339,0xb33a,0xb33b,0xb33c,0xb33d,0xb33e,0xb33f,
+ 0xb340,0xb341,0xb342,0xb343,0xb344,0xb345,0xb346,0xb347,
+ 0xb348,0xb349,0xb34a,0xb34b,0xb34c,0xb34d,0xb34e,0xb34f,
+ 0xb350,0xb351,0xb352,0xb353,0xb354,0xb355,0xb356,0xb357,
+ 0xb358,0xb359,0xb35a,0xb35b,0xb35c,0xb35d,0xb35e,0xb35f,
+ 0xb360,0xb361,0xb362,0xb363,0xb364,0xb365,0xb366,0xb367,
+ 0xb368,0xb369,0xb36a,0xb36b,0xb36c,0xb36d,0xb36e,0xb36f,
+ 0xb370,0xb371,0xb372,0xb373,0xb374,0xb375,0xb376,0xb377,
+ 0xb378,0xb379,0xb37a,0xb37b,0xb37c,0xb37d,0xb37e,0xb37f,
+ 0xb380,0xb381,0xb382,0xb383,0xb384,0xb385,0xb386,0xb387,
+ 0xb388,0xb389,0xb38a,0xb38b,0xb38c,0xb38d,0xb38e,0xb38f,
+ 0xb390,0xb391,0xb392,0xb393,0xb394,0xb395,0xb396,0xb397,
+ 0xb398,0xb399,0xb39a,0xb39b,0xb39c,0xb39d,0xb39e,0xb39f,
+ 0xb3a0,0xb3a1,0xb3a2,0xb3a3,0xb3a4,0xb3a5,0xb3a6,0xb3a7,
+ 0xb3a8,0xb3a9,0xb3aa,0xb3ab,0xb3ac,0xb3ad,0xb3ae,0xb3af,
+ 0xb3b0,0xb3b1,0xb3b2,0xb3b3,0xb3b4,0xb3b5,0xb3b6,0xb3b7,
+ 0xb3b8,0xb3b9,0xb3ba,0xb3bb,0xb3bc,0xb3bd,0xb3be,0xb3bf,
+ 0xb3c0,0xb3c1,0xb3c2,0xb3c3,0xb3c4,0xb3c5,0xb3c6,0xb3c7,
+ 0xb3c8,0xb3c9,0xb3ca,0xb3cb,0xb3cc,0xb3cd,0xb3ce,0xb3cf,
+ 0xb3d0,0xb3d1,0xb3d2,0xb3d3,0xb3d4,0xb3d5,0xb3d6,0xb3d7,
+ 0xb3d8,0xb3d9,0xb3da,0xb3db,0xb3dc,0xb3dd,0xb3de,0xb3df,
+ 0xb3e0,0xb3e1,0xb3e2,0xb3e3,0xb3e4,0xb3e5,0xb3e6,0xb3e7,
+ 0xb3e8,0xb3e9,0xb3ea,0xb3eb,0xb3ec,0xb3ed,0xb3ee,0xb3ef,
+ 0xb3f0,0xb3f1,0xb3f2,0xb3f3,0xb3f4,0xb3f5,0xb3f6,0xb3f7,
+ 0xb3f8,0xb3f9,0xb3fa,0xb3fb,0xb3fc,0xb3fd,0xb3fe,0xb3ff,
+ 0xb400,0xb401,0xb402,0xb403,0xb404,0xb405,0xb406,0xb407,
+ 0xb408,0xb409,0xb40a,0xb40b,0xb40c,0xb40d,0xb40e,0xb40f,
+ 0xb410,0xb411,0xb412,0xb413,0xb414,0xb415,0xb416,0xb417,
+ 0xb418,0xb419,0xb41a,0xb41b,0xb41c,0xb41d,0xb41e,0xb41f,
+ 0xb420,0xb421,0xb422,0xb423,0xb424,0xb425,0xb426,0xb427,
+ 0xb428,0xb429,0xb42a,0xb42b,0xb42c,0xb42d,0xb42e,0xb42f,
+ 0xb430,0xb431,0xb432,0xb433,0xb434,0xb435,0xb436,0xb437,
+ 0xb438,0xb439,0xb43a,0xb43b,0xb43c,0xb43d,0xb43e,0xb43f,
+ 0xb440,0xb441,0xb442,0xb443,0xb444,0xb445,0xb446,0xb447,
+ 0xb448,0xb449,0xb44a,0xb44b,0xb44c,0xb44d,0xb44e,0xb44f,
+ 0xb450,0xb451,0xb452,0xb453,0xb454,0xb455,0xb456,0xb457,
+ 0xb458,0xb459,0xb45a,0xb45b,0xb45c,0xb45d,0xb45e,0xb45f,
+ 0xb460,0xb461,0xb462,0xb463,0xb464,0xb465,0xb466,0xb467,
+ 0xb468,0xb469,0xb46a,0xb46b,0xb46c,0xb46d,0xb46e,0xb46f,
+ 0xb470,0xb471,0xb472,0xb473,0xb474,0xb475,0xb476,0xb477,
+ 0xb478,0xb479,0xb47a,0xb47b,0xb47c,0xb47d,0xb47e,0xb47f,
+ 0xb480,0xb481,0xb482,0xb483,0xb484,0xb485,0xb486,0xb487,
+ 0xb488,0xb489,0xb48a,0xb48b,0xb48c,0xb48d,0xb48e,0xb48f,
+ 0xb490,0xb491,0xb492,0xb493,0xb494,0xb495,0xb496,0xb497,
+ 0xb498,0xb499,0xb49a,0xb49b,0xb49c,0xb49d,0xb49e,0xb49f,
+ 0xb4a0,0xb4a1,0xb4a2,0xb4a3,0xb4a4,0xb4a5,0xb4a6,0xb4a7,
+ 0xb4a8,0xb4a9,0xb4aa,0xb4ab,0xb4ac,0xb4ad,0xb4ae,0xb4af,
+ 0xb4b0,0xb4b1,0xb4b2,0xb4b3,0xb4b4,0xb4b5,0xb4b6,0xb4b7,
+ 0xb4b8,0xb4b9,0xb4ba,0xb4bb,0xb4bc,0xb4bd,0xb4be,0xb4bf,
+ 0xb4c0,0xb4c1,0xb4c2,0xb4c3,0xb4c4,0xb4c5,0xb4c6,0xb4c7,
+ 0xb4c8,0xb4c9,0xb4ca,0xb4cb,0xb4cc,0xb4cd,0xb4ce,0xb4cf,
+ 0xb4d0,0xb4d1,0xb4d2,0xb4d3,0xb4d4,0xb4d5,0xb4d6,0xb4d7,
+ 0xb4d8,0xb4d9,0xb4da,0xb4db,0xb4dc,0xb4dd,0xb4de,0xb4df,
+ 0xb4e0,0xb4e1,0xb4e2,0xb4e3,0xb4e4,0xb4e5,0xb4e6,0xb4e7,
+ 0xb4e8,0xb4e9,0xb4ea,0xb4eb,0xb4ec,0xb4ed,0xb4ee,0xb4ef,
+ 0xb4f0,0xb4f1,0xb4f2,0xb4f3,0xb4f4,0xb4f5,0xb4f6,0xb4f7,
+ 0xb4f8,0xb4f9,0xb4fa,0xb4fb,0xb4fc,0xb4fd,0xb4fe,0xb4ff,
+ 0xb500,0xb501,0xb502,0xb503,0xb504,0xb505,0xb506,0xb507,
+ 0xb508,0xb509,0xb50a,0xb50b,0xb50c,0xb50d,0xb50e,0xb50f,
+ 0xb510,0xb511,0xb512,0xb513,0xb514,0xb515,0xb516,0xb517,
+ 0xb518,0xb519,0xb51a,0xb51b,0xb51c,0xb51d,0xb51e,0xb51f,
+ 0xb520,0xb521,0xb522,0xb523,0xb524,0xb525,0xb526,0xb527,
+ 0xb528,0xb529,0xb52a,0xb52b,0xb52c,0xb52d,0xb52e,0xb52f,
+ 0xb530,0xb531,0xb532,0xb533,0xb534,0xb535,0xb536,0xb537,
+ 0xb538,0xb539,0xb53a,0xb53b,0xb53c,0xb53d,0xb53e,0xb53f,
+ 0xb540,0xb541,0xb542,0xb543,0xb544,0xb545,0xb546,0xb547,
+ 0xb548,0xb549,0xb54a,0xb54b,0xb54c,0xb54d,0xb54e,0xb54f,
+ 0xb550,0xb551,0xb552,0xb553,0xb554,0xb555,0xb556,0xb557,
+ 0xb558,0xb559,0xb55a,0xb55b,0xb55c,0xb55d,0xb55e,0xb55f,
+ 0xb560,0xb561,0xb562,0xb563,0xb564,0xb565,0xb566,0xb567,
+ 0xb568,0xb569,0xb56a,0xb56b,0xb56c,0xb56d,0xb56e,0xb56f,
+ 0xb570,0xb571,0xb572,0xb573,0xb574,0xb575,0xb576,0xb577,
+ 0xb578,0xb579,0xb57a,0xb57b,0xb57c,0xb57d,0xb57e,0xb57f,
+ 0xb580,0xb581,0xb582,0xb583,0xb584,0xb585,0xb586,0xb587,
+ 0xb588,0xb589,0xb58a,0xb58b,0xb58c,0xb58d,0xb58e,0xb58f,
+ 0xb590,0xb591,0xb592,0xb593,0xb594,0xb595,0xb596,0xb597,
+ 0xb598,0xb599,0xb59a,0xb59b,0xb59c,0xb59d,0xb59e,0xb59f,
+ 0xb5a0,0xb5a1,0xb5a2,0xb5a3,0xb5a4,0xb5a5,0xb5a6,0xb5a7,
+ 0xb5a8,0xb5a9,0xb5aa,0xb5ab,0xb5ac,0xb5ad,0xb5ae,0xb5af,
+ 0xb5b0,0xb5b1,0xb5b2,0xb5b3,0xb5b4,0xb5b5,0xb5b6,0xb5b7,
+ 0xb5b8,0xb5b9,0xb5ba,0xb5bb,0xb5bc,0xb5bd,0xb5be,0xb5bf,
+ 0xb5c0,0xb5c1,0xb5c2,0xb5c3,0xb5c4,0xb5c5,0xb5c6,0xb5c7,
+ 0xb5c8,0xb5c9,0xb5ca,0xb5cb,0xb5cc,0xb5cd,0xb5ce,0xb5cf,
+ 0xb5d0,0xb5d1,0xb5d2,0xb5d3,0xb5d4,0xb5d5,0xb5d6,0xb5d7,
+ 0xb5d8,0xb5d9,0xb5da,0xb5db,0xb5dc,0xb5dd,0xb5de,0xb5df,
+ 0xb5e0,0xb5e1,0xb5e2,0xb5e3,0xb5e4,0xb5e5,0xb5e6,0xb5e7,
+ 0xb5e8,0xb5e9,0xb5ea,0xb5eb,0xb5ec,0xb5ed,0xb5ee,0xb5ef,
+ 0xb5f0,0xb5f1,0xb5f2,0xb5f3,0xb5f4,0xb5f5,0xb5f6,0xb5f7,
+ 0xb5f8,0xb5f9,0xb5fa,0xb5fb,0xb5fc,0xb5fd,0xb5fe,0xb5ff,
+ 0xb600,0xb601,0xb602,0xb603,0xb604,0xb605,0xb606,0xb607,
+ 0xb608,0xb609,0xb60a,0xb60b,0xb60c,0xb60d,0xb60e,0xb60f,
+ 0xb610,0xb611,0xb612,0xb613,0xb614,0xb615,0xb616,0xb617,
+ 0xb618,0xb619,0xb61a,0xb61b,0xb61c,0xb61d,0xb61e,0xb61f,
+ 0xb620,0xb621,0xb622,0xb623,0xb624,0xb625,0xb626,0xb627,
+ 0xb628,0xb629,0xb62a,0xb62b,0xb62c,0xb62d,0xb62e,0xb62f,
+ 0xb630,0xb631,0xb632,0xb633,0xb634,0xb635,0xb636,0xb637,
+ 0xb638,0xb639,0xb63a,0xb63b,0xb63c,0xb63d,0xb63e,0xb63f,
+ 0xb640,0xb641,0xb642,0xb643,0xb644,0xb645,0xb646,0xb647,
+ 0xb648,0xb649,0xb64a,0xb64b,0xb64c,0xb64d,0xb64e,0xb64f,
+ 0xb650,0xb651,0xb652,0xb653,0xb654,0xb655,0xb656,0xb657,
+ 0xb658,0xb659,0xb65a,0xb65b,0xb65c,0xb65d,0xb65e,0xb65f,
+ 0xb660,0xb661,0xb662,0xb663,0xb664,0xb665,0xb666,0xb667,
+ 0xb668,0xb669,0xb66a,0xb66b,0xb66c,0xb66d,0xb66e,0xb66f,
+ 0xb670,0xb671,0xb672,0xb673,0xb674,0xb675,0xb676,0xb677,
+ 0xb678,0xb679,0xb67a,0xb67b,0xb67c,0xb67d,0xb67e,0xb67f,
+ 0xb680,0xb681,0xb682,0xb683,0xb684,0xb685,0xb686,0xb687,
+ 0xb688,0xb689,0xb68a,0xb68b,0xb68c,0xb68d,0xb68e,0xb68f,
+ 0xb690,0xb691,0xb692,0xb693,0xb694,0xb695,0xb696,0xb697,
+ 0xb698,0xb699,0xb69a,0xb69b,0xb69c,0xb69d,0xb69e,0xb69f,
+ 0xb6a0,0xb6a1,0xb6a2,0xb6a3,0xb6a4,0xb6a5,0xb6a6,0xb6a7,
+ 0xb6a8,0xb6a9,0xb6aa,0xb6ab,0xb6ac,0xb6ad,0xb6ae,0xb6af,
+ 0xb6b0,0xb6b1,0xb6b2,0xb6b3,0xb6b4,0xb6b5,0xb6b6,0xb6b7,
+ 0xb6b8,0xb6b9,0xb6ba,0xb6bb,0xb6bc,0xb6bd,0xb6be,0xb6bf,
+ 0xb6c0,0xb6c1,0xb6c2,0xb6c3,0xb6c4,0xb6c5,0xb6c6,0xb6c7,
+ 0xb6c8,0xb6c9,0xb6ca,0xb6cb,0xb6cc,0xb6cd,0xb6ce,0xb6cf,
+ 0xb6d0,0xb6d1,0xb6d2,0xb6d3,0xb6d4,0xb6d5,0xb6d6,0xb6d7,
+ 0xb6d8,0xb6d9,0xb6da,0xb6db,0xb6dc,0xb6dd,0xb6de,0xb6df,
+ 0xb6e0,0xb6e1,0xb6e2,0xb6e3,0xb6e4,0xb6e5,0xb6e6,0xb6e7,
+ 0xb6e8,0xb6e9,0xb6ea,0xb6eb,0xb6ec,0xb6ed,0xb6ee,0xb6ef,
+ 0xb6f0,0xb6f1,0xb6f2,0xb6f3,0xb6f4,0xb6f5,0xb6f6,0xb6f7,
+ 0xb6f8,0xb6f9,0xb6fa,0xb6fb,0xb6fc,0xb6fd,0xb6fe,0xb6ff,
+ 0xb700,0xb701,0xb702,0xb703,0xb704,0xb705,0xb706,0xb707,
+ 0xb708,0xb709,0xb70a,0xb70b,0xb70c,0xb70d,0xb70e,0xb70f,
+ 0xb710,0xb711,0xb712,0xb713,0xb714,0xb715,0xb716,0xb717,
+ 0xb718,0xb719,0xb71a,0xb71b,0xb71c,0xb71d,0xb71e,0xb71f,
+ 0xb720,0xb721,0xb722,0xb723,0xb724,0xb725,0xb726,0xb727,
+ 0xb728,0xb729,0xb72a,0xb72b,0xb72c,0xb72d,0xb72e,0xb72f,
+ 0xb730,0xb731,0xb732,0xb733,0xb734,0xb735,0xb736,0xb737,
+ 0xb738,0xb739,0xb73a,0xb73b,0xb73c,0xb73d,0xb73e,0xb73f,
+ 0xb740,0xb741,0xb742,0xb743,0xb744,0xb745,0xb746,0xb747,
+ 0xb748,0xb749,0xb74a,0xb74b,0xb74c,0xb74d,0xb74e,0xb74f,
+ 0xb750,0xb751,0xb752,0xb753,0xb754,0xb755,0xb756,0xb757,
+ 0xb758,0xb759,0xb75a,0xb75b,0xb75c,0xb75d,0xb75e,0xb75f,
+ 0xb760,0xb761,0xb762,0xb763,0xb764,0xb765,0xb766,0xb767,
+ 0xb768,0xb769,0xb76a,0xb76b,0xb76c,0xb76d,0xb76e,0xb76f,
+ 0xb770,0xb771,0xb772,0xb773,0xb774,0xb775,0xb776,0xb777,
+ 0xb778,0xb779,0xb77a,0xb77b,0xb77c,0xb77d,0xb77e,0xb77f,
+ 0xb780,0xb781,0xb782,0xb783,0xb784,0xb785,0xb786,0xb787,
+ 0xb788,0xb789,0xb78a,0xb78b,0xb78c,0xb78d,0xb78e,0xb78f,
+ 0xb790,0xb791,0xb792,0xb793,0xb794,0xb795,0xb796,0xb797,
+ 0xb798,0xb799,0xb79a,0xb79b,0xb79c,0xb79d,0xb79e,0xb79f,
+ 0xb7a0,0xb7a1,0xb7a2,0xb7a3,0xb7a4,0xb7a5,0xb7a6,0xb7a7,
+ 0xb7a8,0xb7a9,0xb7aa,0xb7ab,0xb7ac,0xb7ad,0xb7ae,0xb7af,
+ 0xb7b0,0xb7b1,0xb7b2,0xb7b3,0xb7b4,0xb7b5,0xb7b6,0xb7b7,
+ 0xb7b8,0xb7b9,0xb7ba,0xb7bb,0xb7bc,0xb7bd,0xb7be,0xb7bf,
+ 0xb7c0,0xb7c1,0xb7c2,0xb7c3,0xb7c4,0xb7c5,0xb7c6,0xb7c7,
+ 0xb7c8,0xb7c9,0xb7ca,0xb7cb,0xb7cc,0xb7cd,0xb7ce,0xb7cf,
+ 0xb7d0,0xb7d1,0xb7d2,0xb7d3,0xb7d4,0xb7d5,0xb7d6,0xb7d7,
+ 0xb7d8,0xb7d9,0xb7da,0xb7db,0xb7dc,0xb7dd,0xb7de,0xb7df,
+ 0xb7e0,0xb7e1,0xb7e2,0xb7e3,0xb7e4,0xb7e5,0xb7e6,0xb7e7,
+ 0xb7e8,0xb7e9,0xb7ea,0xb7eb,0xb7ec,0xb7ed,0xb7ee,0xb7ef,
+ 0xb7f0,0xb7f1,0xb7f2,0xb7f3,0xb7f4,0xb7f5,0xb7f6,0xb7f7,
+ 0xb7f8,0xb7f9,0xb7fa,0xb7fb,0xb7fc,0xb7fd,0xb7fe,0xb7ff,
+ 0xb800,0xb801,0xb802,0xb803,0xb804,0xb805,0xb806,0xb807,
+ 0xb808,0xb809,0xb80a,0xb80b,0xb80c,0xb80d,0xb80e,0xb80f,
+ 0xb810,0xb811,0xb812,0xb813,0xb814,0xb815,0xb816,0xb817,
+ 0xb818,0xb819,0xb81a,0xb81b,0xb81c,0xb81d,0xb81e,0xb81f,
+ 0xb820,0xb821,0xb822,0xb823,0xb824,0xb825,0xb826,0xb827,
+ 0xb828,0xb829,0xb82a,0xb82b,0xb82c,0xb82d,0xb82e,0xb82f,
+ 0xb830,0xb831,0xb832,0xb833,0xb834,0xb835,0xb836,0xb837,
+ 0xb838,0xb839,0xb83a,0xb83b,0xb83c,0xb83d,0xb83e,0xb83f,
+ 0xb840,0xb841,0xb842,0xb843,0xb844,0xb845,0xb846,0xb847,
+ 0xb848,0xb849,0xb84a,0xb84b,0xb84c,0xb84d,0xb84e,0xb84f,
+ 0xb850,0xb851,0xb852,0xb853,0xb854,0xb855,0xb856,0xb857,
+ 0xb858,0xb859,0xb85a,0xb85b,0xb85c,0xb85d,0xb85e,0xb85f,
+ 0xb860,0xb861,0xb862,0xb863,0xb864,0xb865,0xb866,0xb867,
+ 0xb868,0xb869,0xb86a,0xb86b,0xb86c,0xb86d,0xb86e,0xb86f,
+ 0xb870,0xb871,0xb872,0xb873,0xb874,0xb875,0xb876,0xb877,
+ 0xb878,0xb879,0xb87a,0xb87b,0xb87c,0xb87d,0xb87e,0xb87f,
+ 0xb880,0xb881,0xb882,0xb883,0xb884,0xb885,0xb886,0xb887,
+ 0xb888,0xb889,0xb88a,0xb88b,0xb88c,0xb88d,0xb88e,0xb88f,
+ 0xb890,0xb891,0xb892,0xb893,0xb894,0xb895,0xb896,0xb897,
+ 0xb898,0xb899,0xb89a,0xb89b,0xb89c,0xb89d,0xb89e,0xb89f,
+ 0xb8a0,0xb8a1,0xb8a2,0xb8a3,0xb8a4,0xb8a5,0xb8a6,0xb8a7,
+ 0xb8a8,0xb8a9,0xb8aa,0xb8ab,0xb8ac,0xb8ad,0xb8ae,0xb8af,
+ 0xb8b0,0xb8b1,0xb8b2,0xb8b3,0xb8b4,0xb8b5,0xb8b6,0xb8b7,
+ 0xb8b8,0xb8b9,0xb8ba,0xb8bb,0xb8bc,0xb8bd,0xb8be,0xb8bf,
+ 0xb8c0,0xb8c1,0xb8c2,0xb8c3,0xb8c4,0xb8c5,0xb8c6,0xb8c7,
+ 0xb8c8,0xb8c9,0xb8ca,0xb8cb,0xb8cc,0xb8cd,0xb8ce,0xb8cf,
+ 0xb8d0,0xb8d1,0xb8d2,0xb8d3,0xb8d4,0xb8d5,0xb8d6,0xb8d7,
+ 0xb8d8,0xb8d9,0xb8da,0xb8db,0xb8dc,0xb8dd,0xb8de,0xb8df,
+ 0xb8e0,0xb8e1,0xb8e2,0xb8e3,0xb8e4,0xb8e5,0xb8e6,0xb8e7,
+ 0xb8e8,0xb8e9,0xb8ea,0xb8eb,0xb8ec,0xb8ed,0xb8ee,0xb8ef,
+ 0xb8f0,0xb8f1,0xb8f2,0xb8f3,0xb8f4,0xb8f5,0xb8f6,0xb8f7,
+ 0xb8f8,0xb8f9,0xb8fa,0xb8fb,0xb8fc,0xb8fd,0xb8fe,0xb8ff,
+ 0xb900,0xb901,0xb902,0xb903,0xb904,0xb905,0xb906,0xb907,
+ 0xb908,0xb909,0xb90a,0xb90b,0xb90c,0xb90d,0xb90e,0xb90f,
+ 0xb910,0xb911,0xb912,0xb913,0xb914,0xb915,0xb916,0xb917,
+ 0xb918,0xb919,0xb91a,0xb91b,0xb91c,0xb91d,0xb91e,0xb91f,
+ 0xb920,0xb921,0xb922,0xb923,0xb924,0xb925,0xb926,0xb927,
+ 0xb928,0xb929,0xb92a,0xb92b,0xb92c,0xb92d,0xb92e,0xb92f,
+ 0xb930,0xb931,0xb932,0xb933,0xb934,0xb935,0xb936,0xb937,
+ 0xb938,0xb939,0xb93a,0xb93b,0xb93c,0xb93d,0xb93e,0xb93f,
+ 0xb940,0xb941,0xb942,0xb943,0xb944,0xb945,0xb946,0xb947,
+ 0xb948,0xb949,0xb94a,0xb94b,0xb94c,0xb94d,0xb94e,0xb94f,
+ 0xb950,0xb951,0xb952,0xb953,0xb954,0xb955,0xb956,0xb957,
+ 0xb958,0xb959,0xb95a,0xb95b,0xb95c,0xb95d,0xb95e,0xb95f,
+ 0xb960,0xb961,0xb962,0xb963,0xb964,0xb965,0xb966,0xb967,
+ 0xb968,0xb969,0xb96a,0xb96b,0xb96c,0xb96d,0xb96e,0xb96f,
+ 0xb970,0xb971,0xb972,0xb973,0xb974,0xb975,0xb976,0xb977,
+ 0xb978,0xb979,0xb97a,0xb97b,0xb97c,0xb97d,0xb97e,0xb97f,
+ 0xb980,0xb981,0xb982,0xb983,0xb984,0xb985,0xb986,0xb987,
+ 0xb988,0xb989,0xb98a,0xb98b,0xb98c,0xb98d,0xb98e,0xb98f,
+ 0xb990,0xb991,0xb992,0xb993,0xb994,0xb995,0xb996,0xb997,
+ 0xb998,0xb999,0xb99a,0xb99b,0xb99c,0xb99d,0xb99e,0xb99f,
+ 0xb9a0,0xb9a1,0xb9a2,0xb9a3,0xb9a4,0xb9a5,0xb9a6,0xb9a7,
+ 0xb9a8,0xb9a9,0xb9aa,0xb9ab,0xb9ac,0xb9ad,0xb9ae,0xb9af,
+ 0xb9b0,0xb9b1,0xb9b2,0xb9b3,0xb9b4,0xb9b5,0xb9b6,0xb9b7,
+ 0xb9b8,0xb9b9,0xb9ba,0xb9bb,0xb9bc,0xb9bd,0xb9be,0xb9bf,
+ 0xb9c0,0xb9c1,0xb9c2,0xb9c3,0xb9c4,0xb9c5,0xb9c6,0xb9c7,
+ 0xb9c8,0xb9c9,0xb9ca,0xb9cb,0xb9cc,0xb9cd,0xb9ce,0xb9cf,
+ 0xb9d0,0xb9d1,0xb9d2,0xb9d3,0xb9d4,0xb9d5,0xb9d6,0xb9d7,
+ 0xb9d8,0xb9d9,0xb9da,0xb9db,0xb9dc,0xb9dd,0xb9de,0xb9df,
+ 0xb9e0,0xb9e1,0xb9e2,0xb9e3,0xb9e4,0xb9e5,0xb9e6,0xb9e7,
+ 0xb9e8,0xb9e9,0xb9ea,0xb9eb,0xb9ec,0xb9ed,0xb9ee,0xb9ef,
+ 0xb9f0,0xb9f1,0xb9f2,0xb9f3,0xb9f4,0xb9f5,0xb9f6,0xb9f7,
+ 0xb9f8,0xb9f9,0xb9fa,0xb9fb,0xb9fc,0xb9fd,0xb9fe,0xb9ff,
+ 0xba00,0xba01,0xba02,0xba03,0xba04,0xba05,0xba06,0xba07,
+ 0xba08,0xba09,0xba0a,0xba0b,0xba0c,0xba0d,0xba0e,0xba0f,
+ 0xba10,0xba11,0xba12,0xba13,0xba14,0xba15,0xba16,0xba17,
+ 0xba18,0xba19,0xba1a,0xba1b,0xba1c,0xba1d,0xba1e,0xba1f,
+ 0xba20,0xba21,0xba22,0xba23,0xba24,0xba25,0xba26,0xba27,
+ 0xba28,0xba29,0xba2a,0xba2b,0xba2c,0xba2d,0xba2e,0xba2f,
+ 0xba30,0xba31,0xba32,0xba33,0xba34,0xba35,0xba36,0xba37,
+ 0xba38,0xba39,0xba3a,0xba3b,0xba3c,0xba3d,0xba3e,0xba3f,
+ 0xba40,0xba41,0xba42,0xba43,0xba44,0xba45,0xba46,0xba47,
+ 0xba48,0xba49,0xba4a,0xba4b,0xba4c,0xba4d,0xba4e,0xba4f,
+ 0xba50,0xba51,0xba52,0xba53,0xba54,0xba55,0xba56,0xba57,
+ 0xba58,0xba59,0xba5a,0xba5b,0xba5c,0xba5d,0xba5e,0xba5f,
+ 0xba60,0xba61,0xba62,0xba63,0xba64,0xba65,0xba66,0xba67,
+ 0xba68,0xba69,0xba6a,0xba6b,0xba6c,0xba6d,0xba6e,0xba6f,
+ 0xba70,0xba71,0xba72,0xba73,0xba74,0xba75,0xba76,0xba77,
+ 0xba78,0xba79,0xba7a,0xba7b,0xba7c,0xba7d,0xba7e,0xba7f,
+ 0xba80,0xba81,0xba82,0xba83,0xba84,0xba85,0xba86,0xba87,
+ 0xba88,0xba89,0xba8a,0xba8b,0xba8c,0xba8d,0xba8e,0xba8f,
+ 0xba90,0xba91,0xba92,0xba93,0xba94,0xba95,0xba96,0xba97,
+ 0xba98,0xba99,0xba9a,0xba9b,0xba9c,0xba9d,0xba9e,0xba9f,
+ 0xbaa0,0xbaa1,0xbaa2,0xbaa3,0xbaa4,0xbaa5,0xbaa6,0xbaa7,
+ 0xbaa8,0xbaa9,0xbaaa,0xbaab,0xbaac,0xbaad,0xbaae,0xbaaf,
+ 0xbab0,0xbab1,0xbab2,0xbab3,0xbab4,0xbab5,0xbab6,0xbab7,
+ 0xbab8,0xbab9,0xbaba,0xbabb,0xbabc,0xbabd,0xbabe,0xbabf,
+ 0xbac0,0xbac1,0xbac2,0xbac3,0xbac4,0xbac5,0xbac6,0xbac7,
+ 0xbac8,0xbac9,0xbaca,0xbacb,0xbacc,0xbacd,0xbace,0xbacf,
+ 0xbad0,0xbad1,0xbad2,0xbad3,0xbad4,0xbad5,0xbad6,0xbad7,
+ 0xbad8,0xbad9,0xbada,0xbadb,0xbadc,0xbadd,0xbade,0xbadf,
+ 0xbae0,0xbae1,0xbae2,0xbae3,0xbae4,0xbae5,0xbae6,0xbae7,
+ 0xbae8,0xbae9,0xbaea,0xbaeb,0xbaec,0xbaed,0xbaee,0xbaef,
+ 0xbaf0,0xbaf1,0xbaf2,0xbaf3,0xbaf4,0xbaf5,0xbaf6,0xbaf7,
+ 0xbaf8,0xbaf9,0xbafa,0xbafb,0xbafc,0xbafd,0xbafe,0xbaff,
+ 0xbb00,0xbb01,0xbb02,0xbb03,0xbb04,0xbb05,0xbb06,0xbb07,
+ 0xbb08,0xbb09,0xbb0a,0xbb0b,0xbb0c,0xbb0d,0xbb0e,0xbb0f,
+ 0xbb10,0xbb11,0xbb12,0xbb13,0xbb14,0xbb15,0xbb16,0xbb17,
+ 0xbb18,0xbb19,0xbb1a,0xbb1b,0xbb1c,0xbb1d,0xbb1e,0xbb1f,
+ 0xbb20,0xbb21,0xbb22,0xbb23,0xbb24,0xbb25,0xbb26,0xbb27,
+ 0xbb28,0xbb29,0xbb2a,0xbb2b,0xbb2c,0xbb2d,0xbb2e,0xbb2f,
+ 0xbb30,0xbb31,0xbb32,0xbb33,0xbb34,0xbb35,0xbb36,0xbb37,
+ 0xbb38,0xbb39,0xbb3a,0xbb3b,0xbb3c,0xbb3d,0xbb3e,0xbb3f,
+ 0xbb40,0xbb41,0xbb42,0xbb43,0xbb44,0xbb45,0xbb46,0xbb47,
+ 0xbb48,0xbb49,0xbb4a,0xbb4b,0xbb4c,0xbb4d,0xbb4e,0xbb4f,
+ 0xbb50,0xbb51,0xbb52,0xbb53,0xbb54,0xbb55,0xbb56,0xbb57,
+ 0xbb58,0xbb59,0xbb5a,0xbb5b,0xbb5c,0xbb5d,0xbb5e,0xbb5f,
+ 0xbb60,0xbb61,0xbb62,0xbb63,0xbb64,0xbb65,0xbb66,0xbb67,
+ 0xbb68,0xbb69,0xbb6a,0xbb6b,0xbb6c,0xbb6d,0xbb6e,0xbb6f,
+ 0xbb70,0xbb71,0xbb72,0xbb73,0xbb74,0xbb75,0xbb76,0xbb77,
+ 0xbb78,0xbb79,0xbb7a,0xbb7b,0xbb7c,0xbb7d,0xbb7e,0xbb7f,
+ 0xbb80,0xbb81,0xbb82,0xbb83,0xbb84,0xbb85,0xbb86,0xbb87,
+ 0xbb88,0xbb89,0xbb8a,0xbb8b,0xbb8c,0xbb8d,0xbb8e,0xbb8f,
+ 0xbb90,0xbb91,0xbb92,0xbb93,0xbb94,0xbb95,0xbb96,0xbb97,
+ 0xbb98,0xbb99,0xbb9a,0xbb9b,0xbb9c,0xbb9d,0xbb9e,0xbb9f,
+ 0xbba0,0xbba1,0xbba2,0xbba3,0xbba4,0xbba5,0xbba6,0xbba7,
+ 0xbba8,0xbba9,0xbbaa,0xbbab,0xbbac,0xbbad,0xbbae,0xbbaf,
+ 0xbbb0,0xbbb1,0xbbb2,0xbbb3,0xbbb4,0xbbb5,0xbbb6,0xbbb7,
+ 0xbbb8,0xbbb9,0xbbba,0xbbbb,0xbbbc,0xbbbd,0xbbbe,0xbbbf,
+ 0xbbc0,0xbbc1,0xbbc2,0xbbc3,0xbbc4,0xbbc5,0xbbc6,0xbbc7,
+ 0xbbc8,0xbbc9,0xbbca,0xbbcb,0xbbcc,0xbbcd,0xbbce,0xbbcf,
+ 0xbbd0,0xbbd1,0xbbd2,0xbbd3,0xbbd4,0xbbd5,0xbbd6,0xbbd7,
+ 0xbbd8,0xbbd9,0xbbda,0xbbdb,0xbbdc,0xbbdd,0xbbde,0xbbdf,
+ 0xbbe0,0xbbe1,0xbbe2,0xbbe3,0xbbe4,0xbbe5,0xbbe6,0xbbe7,
+ 0xbbe8,0xbbe9,0xbbea,0xbbeb,0xbbec,0xbbed,0xbbee,0xbbef,
+ 0xbbf0,0xbbf1,0xbbf2,0xbbf3,0xbbf4,0xbbf5,0xbbf6,0xbbf7,
+ 0xbbf8,0xbbf9,0xbbfa,0xbbfb,0xbbfc,0xbbfd,0xbbfe,0xbbff,
+ 0xbc00,0xbc01,0xbc02,0xbc03,0xbc04,0xbc05,0xbc06,0xbc07,
+ 0xbc08,0xbc09,0xbc0a,0xbc0b,0xbc0c,0xbc0d,0xbc0e,0xbc0f,
+ 0xbc10,0xbc11,0xbc12,0xbc13,0xbc14,0xbc15,0xbc16,0xbc17,
+ 0xbc18,0xbc19,0xbc1a,0xbc1b,0xbc1c,0xbc1d,0xbc1e,0xbc1f,
+ 0xbc20,0xbc21,0xbc22,0xbc23,0xbc24,0xbc25,0xbc26,0xbc27,
+ 0xbc28,0xbc29,0xbc2a,0xbc2b,0xbc2c,0xbc2d,0xbc2e,0xbc2f,
+ 0xbc30,0xbc31,0xbc32,0xbc33,0xbc34,0xbc35,0xbc36,0xbc37,
+ 0xbc38,0xbc39,0xbc3a,0xbc3b,0xbc3c,0xbc3d,0xbc3e,0xbc3f,
+ 0xbc40,0xbc41,0xbc42,0xbc43,0xbc44,0xbc45,0xbc46,0xbc47,
+ 0xbc48,0xbc49,0xbc4a,0xbc4b,0xbc4c,0xbc4d,0xbc4e,0xbc4f,
+ 0xbc50,0xbc51,0xbc52,0xbc53,0xbc54,0xbc55,0xbc56,0xbc57,
+ 0xbc58,0xbc59,0xbc5a,0xbc5b,0xbc5c,0xbc5d,0xbc5e,0xbc5f,
+ 0xbc60,0xbc61,0xbc62,0xbc63,0xbc64,0xbc65,0xbc66,0xbc67,
+ 0xbc68,0xbc69,0xbc6a,0xbc6b,0xbc6c,0xbc6d,0xbc6e,0xbc6f,
+ 0xbc70,0xbc71,0xbc72,0xbc73,0xbc74,0xbc75,0xbc76,0xbc77,
+ 0xbc78,0xbc79,0xbc7a,0xbc7b,0xbc7c,0xbc7d,0xbc7e,0xbc7f,
+ 0xbc80,0xbc81,0xbc82,0xbc83,0xbc84,0xbc85,0xbc86,0xbc87,
+ 0xbc88,0xbc89,0xbc8a,0xbc8b,0xbc8c,0xbc8d,0xbc8e,0xbc8f,
+ 0xbc90,0xbc91,0xbc92,0xbc93,0xbc94,0xbc95,0xbc96,0xbc97,
+ 0xbc98,0xbc99,0xbc9a,0xbc9b,0xbc9c,0xbc9d,0xbc9e,0xbc9f,
+ 0xbca0,0xbca1,0xbca2,0xbca3,0xbca4,0xbca5,0xbca6,0xbca7,
+ 0xbca8,0xbca9,0xbcaa,0xbcab,0xbcac,0xbcad,0xbcae,0xbcaf,
+ 0xbcb0,0xbcb1,0xbcb2,0xbcb3,0xbcb4,0xbcb5,0xbcb6,0xbcb7,
+ 0xbcb8,0xbcb9,0xbcba,0xbcbb,0xbcbc,0xbcbd,0xbcbe,0xbcbf,
+ 0xbcc0,0xbcc1,0xbcc2,0xbcc3,0xbcc4,0xbcc5,0xbcc6,0xbcc7,
+ 0xbcc8,0xbcc9,0xbcca,0xbccb,0xbccc,0xbccd,0xbcce,0xbccf,
+ 0xbcd0,0xbcd1,0xbcd2,0xbcd3,0xbcd4,0xbcd5,0xbcd6,0xbcd7,
+ 0xbcd8,0xbcd9,0xbcda,0xbcdb,0xbcdc,0xbcdd,0xbcde,0xbcdf,
+ 0xbce0,0xbce1,0xbce2,0xbce3,0xbce4,0xbce5,0xbce6,0xbce7,
+ 0xbce8,0xbce9,0xbcea,0xbceb,0xbcec,0xbced,0xbcee,0xbcef,
+ 0xbcf0,0xbcf1,0xbcf2,0xbcf3,0xbcf4,0xbcf5,0xbcf6,0xbcf7,
+ 0xbcf8,0xbcf9,0xbcfa,0xbcfb,0xbcfc,0xbcfd,0xbcfe,0xbcff,
+ 0xbd00,0xbd01,0xbd02,0xbd03,0xbd04,0xbd05,0xbd06,0xbd07,
+ 0xbd08,0xbd09,0xbd0a,0xbd0b,0xbd0c,0xbd0d,0xbd0e,0xbd0f,
+ 0xbd10,0xbd11,0xbd12,0xbd13,0xbd14,0xbd15,0xbd16,0xbd17,
+ 0xbd18,0xbd19,0xbd1a,0xbd1b,0xbd1c,0xbd1d,0xbd1e,0xbd1f,
+ 0xbd20,0xbd21,0xbd22,0xbd23,0xbd24,0xbd25,0xbd26,0xbd27,
+ 0xbd28,0xbd29,0xbd2a,0xbd2b,0xbd2c,0xbd2d,0xbd2e,0xbd2f,
+ 0xbd30,0xbd31,0xbd32,0xbd33,0xbd34,0xbd35,0xbd36,0xbd37,
+ 0xbd38,0xbd39,0xbd3a,0xbd3b,0xbd3c,0xbd3d,0xbd3e,0xbd3f,
+ 0xbd40,0xbd41,0xbd42,0xbd43,0xbd44,0xbd45,0xbd46,0xbd47,
+ 0xbd48,0xbd49,0xbd4a,0xbd4b,0xbd4c,0xbd4d,0xbd4e,0xbd4f,
+ 0xbd50,0xbd51,0xbd52,0xbd53,0xbd54,0xbd55,0xbd56,0xbd57,
+ 0xbd58,0xbd59,0xbd5a,0xbd5b,0xbd5c,0xbd5d,0xbd5e,0xbd5f,
+ 0xbd60,0xbd61,0xbd62,0xbd63,0xbd64,0xbd65,0xbd66,0xbd67,
+ 0xbd68,0xbd69,0xbd6a,0xbd6b,0xbd6c,0xbd6d,0xbd6e,0xbd6f,
+ 0xbd70,0xbd71,0xbd72,0xbd73,0xbd74,0xbd75,0xbd76,0xbd77,
+ 0xbd78,0xbd79,0xbd7a,0xbd7b,0xbd7c,0xbd7d,0xbd7e,0xbd7f,
+ 0xbd80,0xbd81,0xbd82,0xbd83,0xbd84,0xbd85,0xbd86,0xbd87,
+ 0xbd88,0xbd89,0xbd8a,0xbd8b,0xbd8c,0xbd8d,0xbd8e,0xbd8f,
+ 0xbd90,0xbd91,0xbd92,0xbd93,0xbd94,0xbd95,0xbd96,0xbd97,
+ 0xbd98,0xbd99,0xbd9a,0xbd9b,0xbd9c,0xbd9d,0xbd9e,0xbd9f,
+ 0xbda0,0xbda1,0xbda2,0xbda3,0xbda4,0xbda5,0xbda6,0xbda7,
+ 0xbda8,0xbda9,0xbdaa,0xbdab,0xbdac,0xbdad,0xbdae,0xbdaf,
+ 0xbdb0,0xbdb1,0xbdb2,0xbdb3,0xbdb4,0xbdb5,0xbdb6,0xbdb7,
+ 0xbdb8,0xbdb9,0xbdba,0xbdbb,0xbdbc,0xbdbd,0xbdbe,0xbdbf,
+ 0xbdc0,0xbdc1,0xbdc2,0xbdc3,0xbdc4,0xbdc5,0xbdc6,0xbdc7,
+ 0xbdc8,0xbdc9,0xbdca,0xbdcb,0xbdcc,0xbdcd,0xbdce,0xbdcf,
+ 0xbdd0,0xbdd1,0xbdd2,0xbdd3,0xbdd4,0xbdd5,0xbdd6,0xbdd7,
+ 0xbdd8,0xbdd9,0xbdda,0xbddb,0xbddc,0xbddd,0xbdde,0xbddf,
+ 0xbde0,0xbde1,0xbde2,0xbde3,0xbde4,0xbde5,0xbde6,0xbde7,
+ 0xbde8,0xbde9,0xbdea,0xbdeb,0xbdec,0xbded,0xbdee,0xbdef,
+ 0xbdf0,0xbdf1,0xbdf2,0xbdf3,0xbdf4,0xbdf5,0xbdf6,0xbdf7,
+ 0xbdf8,0xbdf9,0xbdfa,0xbdfb,0xbdfc,0xbdfd,0xbdfe,0xbdff,
+ 0xbe00,0xbe01,0xbe02,0xbe03,0xbe04,0xbe05,0xbe06,0xbe07,
+ 0xbe08,0xbe09,0xbe0a,0xbe0b,0xbe0c,0xbe0d,0xbe0e,0xbe0f,
+ 0xbe10,0xbe11,0xbe12,0xbe13,0xbe14,0xbe15,0xbe16,0xbe17,
+ 0xbe18,0xbe19,0xbe1a,0xbe1b,0xbe1c,0xbe1d,0xbe1e,0xbe1f,
+ 0xbe20,0xbe21,0xbe22,0xbe23,0xbe24,0xbe25,0xbe26,0xbe27,
+ 0xbe28,0xbe29,0xbe2a,0xbe2b,0xbe2c,0xbe2d,0xbe2e,0xbe2f,
+ 0xbe30,0xbe31,0xbe32,0xbe33,0xbe34,0xbe35,0xbe36,0xbe37,
+ 0xbe38,0xbe39,0xbe3a,0xbe3b,0xbe3c,0xbe3d,0xbe3e,0xbe3f,
+ 0xbe40,0xbe41,0xbe42,0xbe43,0xbe44,0xbe45,0xbe46,0xbe47,
+ 0xbe48,0xbe49,0xbe4a,0xbe4b,0xbe4c,0xbe4d,0xbe4e,0xbe4f,
+ 0xbe50,0xbe51,0xbe52,0xbe53,0xbe54,0xbe55,0xbe56,0xbe57,
+ 0xbe58,0xbe59,0xbe5a,0xbe5b,0xbe5c,0xbe5d,0xbe5e,0xbe5f,
+ 0xbe60,0xbe61,0xbe62,0xbe63,0xbe64,0xbe65,0xbe66,0xbe67,
+ 0xbe68,0xbe69,0xbe6a,0xbe6b,0xbe6c,0xbe6d,0xbe6e,0xbe6f,
+ 0xbe70,0xbe71,0xbe72,0xbe73,0xbe74,0xbe75,0xbe76,0xbe77,
+ 0xbe78,0xbe79,0xbe7a,0xbe7b,0xbe7c,0xbe7d,0xbe7e,0xbe7f,
+ 0xbe80,0xbe81,0xbe82,0xbe83,0xbe84,0xbe85,0xbe86,0xbe87,
+ 0xbe88,0xbe89,0xbe8a,0xbe8b,0xbe8c,0xbe8d,0xbe8e,0xbe8f,
+ 0xbe90,0xbe91,0xbe92,0xbe93,0xbe94,0xbe95,0xbe96,0xbe97,
+ 0xbe98,0xbe99,0xbe9a,0xbe9b,0xbe9c,0xbe9d,0xbe9e,0xbe9f,
+ 0xbea0,0xbea1,0xbea2,0xbea3,0xbea4,0xbea5,0xbea6,0xbea7,
+ 0xbea8,0xbea9,0xbeaa,0xbeab,0xbeac,0xbead,0xbeae,0xbeaf,
+ 0xbeb0,0xbeb1,0xbeb2,0xbeb3,0xbeb4,0xbeb5,0xbeb6,0xbeb7,
+ 0xbeb8,0xbeb9,0xbeba,0xbebb,0xbebc,0xbebd,0xbebe,0xbebf,
+ 0xbec0,0xbec1,0xbec2,0xbec3,0xbec4,0xbec5,0xbec6,0xbec7,
+ 0xbec8,0xbec9,0xbeca,0xbecb,0xbecc,0xbecd,0xbece,0xbecf,
+ 0xbed0,0xbed1,0xbed2,0xbed3,0xbed4,0xbed5,0xbed6,0xbed7,
+ 0xbed8,0xbed9,0xbeda,0xbedb,0xbedc,0xbedd,0xbede,0xbedf,
+ 0xbee0,0xbee1,0xbee2,0xbee3,0xbee4,0xbee5,0xbee6,0xbee7,
+ 0xbee8,0xbee9,0xbeea,0xbeeb,0xbeec,0xbeed,0xbeee,0xbeef,
+ 0xbef0,0xbef1,0xbef2,0xbef3,0xbef4,0xbef5,0xbef6,0xbef7,
+ 0xbef8,0xbef9,0xbefa,0xbefb,0xbefc,0xbefd,0xbefe,0xbeff,
+ 0xbf00,0xbf01,0xbf02,0xbf03,0xbf04,0xbf05,0xbf06,0xbf07,
+ 0xbf08,0xbf09,0xbf0a,0xbf0b,0xbf0c,0xbf0d,0xbf0e,0xbf0f,
+ 0xbf10,0xbf11,0xbf12,0xbf13,0xbf14,0xbf15,0xbf16,0xbf17,
+ 0xbf18,0xbf19,0xbf1a,0xbf1b,0xbf1c,0xbf1d,0xbf1e,0xbf1f,
+ 0xbf20,0xbf21,0xbf22,0xbf23,0xbf24,0xbf25,0xbf26,0xbf27,
+ 0xbf28,0xbf29,0xbf2a,0xbf2b,0xbf2c,0xbf2d,0xbf2e,0xbf2f,
+ 0xbf30,0xbf31,0xbf32,0xbf33,0xbf34,0xbf35,0xbf36,0xbf37,
+ 0xbf38,0xbf39,0xbf3a,0xbf3b,0xbf3c,0xbf3d,0xbf3e,0xbf3f,
+ 0xbf40,0xbf41,0xbf42,0xbf43,0xbf44,0xbf45,0xbf46,0xbf47,
+ 0xbf48,0xbf49,0xbf4a,0xbf4b,0xbf4c,0xbf4d,0xbf4e,0xbf4f,
+ 0xbf50,0xbf51,0xbf52,0xbf53,0xbf54,0xbf55,0xbf56,0xbf57,
+ 0xbf58,0xbf59,0xbf5a,0xbf5b,0xbf5c,0xbf5d,0xbf5e,0xbf5f,
+ 0xbf60,0xbf61,0xbf62,0xbf63,0xbf64,0xbf65,0xbf66,0xbf67,
+ 0xbf68,0xbf69,0xbf6a,0xbf6b,0xbf6c,0xbf6d,0xbf6e,0xbf6f,
+ 0xbf70,0xbf71,0xbf72,0xbf73,0xbf74,0xbf75,0xbf76,0xbf77,
+ 0xbf78,0xbf79,0xbf7a,0xbf7b,0xbf7c,0xbf7d,0xbf7e,0xbf7f,
+ 0xbf80,0xbf81,0xbf82,0xbf83,0xbf84,0xbf85,0xbf86,0xbf87,
+ 0xbf88,0xbf89,0xbf8a,0xbf8b,0xbf8c,0xbf8d,0xbf8e,0xbf8f,
+ 0xbf90,0xbf91,0xbf92,0xbf93,0xbf94,0xbf95,0xbf96,0xbf97,
+ 0xbf98,0xbf99,0xbf9a,0xbf9b,0xbf9c,0xbf9d,0xbf9e,0xbf9f,
+ 0xbfa0,0xbfa1,0xbfa2,0xbfa3,0xbfa4,0xbfa5,0xbfa6,0xbfa7,
+ 0xbfa8,0xbfa9,0xbfaa,0xbfab,0xbfac,0xbfad,0xbfae,0xbfaf,
+ 0xbfb0,0xbfb1,0xbfb2,0xbfb3,0xbfb4,0xbfb5,0xbfb6,0xbfb7,
+ 0xbfb8,0xbfb9,0xbfba,0xbfbb,0xbfbc,0xbfbd,0xbfbe,0xbfbf,
+ 0xbfc0,0xbfc1,0xbfc2,0xbfc3,0xbfc4,0xbfc5,0xbfc6,0xbfc7,
+ 0xbfc8,0xbfc9,0xbfca,0xbfcb,0xbfcc,0xbfcd,0xbfce,0xbfcf,
+ 0xbfd0,0xbfd1,0xbfd2,0xbfd3,0xbfd4,0xbfd5,0xbfd6,0xbfd7,
+ 0xbfd8,0xbfd9,0xbfda,0xbfdb,0xbfdc,0xbfdd,0xbfde,0xbfdf,
+ 0xbfe0,0xbfe1,0xbfe2,0xbfe3,0xbfe4,0xbfe5,0xbfe6,0xbfe7,
+ 0xbfe8,0xbfe9,0xbfea,0xbfeb,0xbfec,0xbfed,0xbfee,0xbfef,
+ 0xbff0,0xbff1,0xbff2,0xbff3,0xbff4,0xbff5,0xbff6,0xbff7,
+ 0xbff8,0xbff9,0xbffa,0xbffb,0xbffc,0xbffd,0xbffe,0xbfff,
+ 0xc000,0xc001,0xc002,0xc003,0xc004,0xc005,0xc006,0xc007,
+ 0xc008,0xc009,0xc00a,0xc00b,0xc00c,0xc00d,0xc00e,0xc00f,
+ 0xc010,0xc011,0xc012,0xc013,0xc014,0xc015,0xc016,0xc017,
+ 0xc018,0xc019,0xc01a,0xc01b,0xc01c,0xc01d,0xc01e,0xc01f,
+ 0xc020,0xc021,0xc022,0xc023,0xc024,0xc025,0xc026,0xc027,
+ 0xc028,0xc029,0xc02a,0xc02b,0xc02c,0xc02d,0xc02e,0xc02f,
+ 0xc030,0xc031,0xc032,0xc033,0xc034,0xc035,0xc036,0xc037,
+ 0xc038,0xc039,0xc03a,0xc03b,0xc03c,0xc03d,0xc03e,0xc03f,
+ 0xc040,0xc041,0xc042,0xc043,0xc044,0xc045,0xc046,0xc047,
+ 0xc048,0xc049,0xc04a,0xc04b,0xc04c,0xc04d,0xc04e,0xc04f,
+ 0xc050,0xc051,0xc052,0xc053,0xc054,0xc055,0xc056,0xc057,
+ 0xc058,0xc059,0xc05a,0xc05b,0xc05c,0xc05d,0xc05e,0xc05f,
+ 0xc060,0xc061,0xc062,0xc063,0xc064,0xc065,0xc066,0xc067,
+ 0xc068,0xc069,0xc06a,0xc06b,0xc06c,0xc06d,0xc06e,0xc06f,
+ 0xc070,0xc071,0xc072,0xc073,0xc074,0xc075,0xc076,0xc077,
+ 0xc078,0xc079,0xc07a,0xc07b,0xc07c,0xc07d,0xc07e,0xc07f,
+ 0xc080,0xc081,0xc082,0xc083,0xc084,0xc085,0xc086,0xc087,
+ 0xc088,0xc089,0xc08a,0xc08b,0xc08c,0xc08d,0xc08e,0xc08f,
+ 0xc090,0xc091,0xc092,0xc093,0xc094,0xc095,0xc096,0xc097,
+ 0xc098,0xc099,0xc09a,0xc09b,0xc09c,0xc09d,0xc09e,0xc09f,
+ 0xc0a0,0xc0a1,0xc0a2,0xc0a3,0xc0a4,0xc0a5,0xc0a6,0xc0a7,
+ 0xc0a8,0xc0a9,0xc0aa,0xc0ab,0xc0ac,0xc0ad,0xc0ae,0xc0af,
+ 0xc0b0,0xc0b1,0xc0b2,0xc0b3,0xc0b4,0xc0b5,0xc0b6,0xc0b7,
+ 0xc0b8,0xc0b9,0xc0ba,0xc0bb,0xc0bc,0xc0bd,0xc0be,0xc0bf,
+ 0xc0c0,0xc0c1,0xc0c2,0xc0c3,0xc0c4,0xc0c5,0xc0c6,0xc0c7,
+ 0xc0c8,0xc0c9,0xc0ca,0xc0cb,0xc0cc,0xc0cd,0xc0ce,0xc0cf,
+ 0xc0d0,0xc0d1,0xc0d2,0xc0d3,0xc0d4,0xc0d5,0xc0d6,0xc0d7,
+ 0xc0d8,0xc0d9,0xc0da,0xc0db,0xc0dc,0xc0dd,0xc0de,0xc0df,
+ 0xc0e0,0xc0e1,0xc0e2,0xc0e3,0xc0e4,0xc0e5,0xc0e6,0xc0e7,
+ 0xc0e8,0xc0e9,0xc0ea,0xc0eb,0xc0ec,0xc0ed,0xc0ee,0xc0ef,
+ 0xc0f0,0xc0f1,0xc0f2,0xc0f3,0xc0f4,0xc0f5,0xc0f6,0xc0f7,
+ 0xc0f8,0xc0f9,0xc0fa,0xc0fb,0xc0fc,0xc0fd,0xc0fe,0xc0ff,
+ 0xc100,0xc101,0xc102,0xc103,0xc104,0xc105,0xc106,0xc107,
+ 0xc108,0xc109,0xc10a,0xc10b,0xc10c,0xc10d,0xc10e,0xc10f,
+ 0xc110,0xc111,0xc112,0xc113,0xc114,0xc115,0xc116,0xc117,
+ 0xc118,0xc119,0xc11a,0xc11b,0xc11c,0xc11d,0xc11e,0xc11f,
+ 0xc120,0xc121,0xc122,0xc123,0xc124,0xc125,0xc126,0xc127,
+ 0xc128,0xc129,0xc12a,0xc12b,0xc12c,0xc12d,0xc12e,0xc12f,
+ 0xc130,0xc131,0xc132,0xc133,0xc134,0xc135,0xc136,0xc137,
+ 0xc138,0xc139,0xc13a,0xc13b,0xc13c,0xc13d,0xc13e,0xc13f,
+ 0xc140,0xc141,0xc142,0xc143,0xc144,0xc145,0xc146,0xc147,
+ 0xc148,0xc149,0xc14a,0xc14b,0xc14c,0xc14d,0xc14e,0xc14f,
+ 0xc150,0xc151,0xc152,0xc153,0xc154,0xc155,0xc156,0xc157,
+ 0xc158,0xc159,0xc15a,0xc15b,0xc15c,0xc15d,0xc15e,0xc15f,
+ 0xc160,0xc161,0xc162,0xc163,0xc164,0xc165,0xc166,0xc167,
+ 0xc168,0xc169,0xc16a,0xc16b,0xc16c,0xc16d,0xc16e,0xc16f,
+ 0xc170,0xc171,0xc172,0xc173,0xc174,0xc175,0xc176,0xc177,
+ 0xc178,0xc179,0xc17a,0xc17b,0xc17c,0xc17d,0xc17e,0xc17f,
+ 0xc180,0xc181,0xc182,0xc183,0xc184,0xc185,0xc186,0xc187,
+ 0xc188,0xc189,0xc18a,0xc18b,0xc18c,0xc18d,0xc18e,0xc18f,
+ 0xc190,0xc191,0xc192,0xc193,0xc194,0xc195,0xc196,0xc197,
+ 0xc198,0xc199,0xc19a,0xc19b,0xc19c,0xc19d,0xc19e,0xc19f,
+ 0xc1a0,0xc1a1,0xc1a2,0xc1a3,0xc1a4,0xc1a5,0xc1a6,0xc1a7,
+ 0xc1a8,0xc1a9,0xc1aa,0xc1ab,0xc1ac,0xc1ad,0xc1ae,0xc1af,
+ 0xc1b0,0xc1b1,0xc1b2,0xc1b3,0xc1b4,0xc1b5,0xc1b6,0xc1b7,
+ 0xc1b8,0xc1b9,0xc1ba,0xc1bb,0xc1bc,0xc1bd,0xc1be,0xc1bf,
+ 0xc1c0,0xc1c1,0xc1c2,0xc1c3,0xc1c4,0xc1c5,0xc1c6,0xc1c7,
+ 0xc1c8,0xc1c9,0xc1ca,0xc1cb,0xc1cc,0xc1cd,0xc1ce,0xc1cf,
+ 0xc1d0,0xc1d1,0xc1d2,0xc1d3,0xc1d4,0xc1d5,0xc1d6,0xc1d7,
+ 0xc1d8,0xc1d9,0xc1da,0xc1db,0xc1dc,0xc1dd,0xc1de,0xc1df,
+ 0xc1e0,0xc1e1,0xc1e2,0xc1e3,0xc1e4,0xc1e5,0xc1e6,0xc1e7,
+ 0xc1e8,0xc1e9,0xc1ea,0xc1eb,0xc1ec,0xc1ed,0xc1ee,0xc1ef,
+ 0xc1f0,0xc1f1,0xc1f2,0xc1f3,0xc1f4,0xc1f5,0xc1f6,0xc1f7,
+ 0xc1f8,0xc1f9,0xc1fa,0xc1fb,0xc1fc,0xc1fd,0xc1fe,0xc1ff,
+ 0xc200,0xc201,0xc202,0xc203,0xc204,0xc205,0xc206,0xc207,
+ 0xc208,0xc209,0xc20a,0xc20b,0xc20c,0xc20d,0xc20e,0xc20f,
+ 0xc210,0xc211,0xc212,0xc213,0xc214,0xc215,0xc216,0xc217,
+ 0xc218,0xc219,0xc21a,0xc21b,0xc21c,0xc21d,0xc21e,0xc21f,
+ 0xc220,0xc221,0xc222,0xc223,0xc224,0xc225,0xc226,0xc227,
+ 0xc228,0xc229,0xc22a,0xc22b,0xc22c,0xc22d,0xc22e,0xc22f,
+ 0xc230,0xc231,0xc232,0xc233,0xc234,0xc235,0xc236,0xc237,
+ 0xc238,0xc239,0xc23a,0xc23b,0xc23c,0xc23d,0xc23e,0xc23f,
+ 0xc240,0xc241,0xc242,0xc243,0xc244,0xc245,0xc246,0xc247,
+ 0xc248,0xc249,0xc24a,0xc24b,0xc24c,0xc24d,0xc24e,0xc24f,
+ 0xc250,0xc251,0xc252,0xc253,0xc254,0xc255,0xc256,0xc257,
+ 0xc258,0xc259,0xc25a,0xc25b,0xc25c,0xc25d,0xc25e,0xc25f,
+ 0xc260,0xc261,0xc262,0xc263,0xc264,0xc265,0xc266,0xc267,
+ 0xc268,0xc269,0xc26a,0xc26b,0xc26c,0xc26d,0xc26e,0xc26f,
+ 0xc270,0xc271,0xc272,0xc273,0xc274,0xc275,0xc276,0xc277,
+ 0xc278,0xc279,0xc27a,0xc27b,0xc27c,0xc27d,0xc27e,0xc27f,
+ 0xc280,0xc281,0xc282,0xc283,0xc284,0xc285,0xc286,0xc287,
+ 0xc288,0xc289,0xc28a,0xc28b,0xc28c,0xc28d,0xc28e,0xc28f,
+ 0xc290,0xc291,0xc292,0xc293,0xc294,0xc295,0xc296,0xc297,
+ 0xc298,0xc299,0xc29a,0xc29b,0xc29c,0xc29d,0xc29e,0xc29f,
+ 0xc2a0,0xc2a1,0xc2a2,0xc2a3,0xc2a4,0xc2a5,0xc2a6,0xc2a7,
+ 0xc2a8,0xc2a9,0xc2aa,0xc2ab,0xc2ac,0xc2ad,0xc2ae,0xc2af,
+ 0xc2b0,0xc2b1,0xc2b2,0xc2b3,0xc2b4,0xc2b5,0xc2b6,0xc2b7,
+ 0xc2b8,0xc2b9,0xc2ba,0xc2bb,0xc2bc,0xc2bd,0xc2be,0xc2bf,
+ 0xc2c0,0xc2c1,0xc2c2,0xc2c3,0xc2c4,0xc2c5,0xc2c6,0xc2c7,
+ 0xc2c8,0xc2c9,0xc2ca,0xc2cb,0xc2cc,0xc2cd,0xc2ce,0xc2cf,
+ 0xc2d0,0xc2d1,0xc2d2,0xc2d3,0xc2d4,0xc2d5,0xc2d6,0xc2d7,
+ 0xc2d8,0xc2d9,0xc2da,0xc2db,0xc2dc,0xc2dd,0xc2de,0xc2df,
+ 0xc2e0,0xc2e1,0xc2e2,0xc2e3,0xc2e4,0xc2e5,0xc2e6,0xc2e7,
+ 0xc2e8,0xc2e9,0xc2ea,0xc2eb,0xc2ec,0xc2ed,0xc2ee,0xc2ef,
+ 0xc2f0,0xc2f1,0xc2f2,0xc2f3,0xc2f4,0xc2f5,0xc2f6,0xc2f7,
+ 0xc2f8,0xc2f9,0xc2fa,0xc2fb,0xc2fc,0xc2fd,0xc2fe,0xc2ff,
+ 0xc300,0xc301,0xc302,0xc303,0xc304,0xc305,0xc306,0xc307,
+ 0xc308,0xc309,0xc30a,0xc30b,0xc30c,0xc30d,0xc30e,0xc30f,
+ 0xc310,0xc311,0xc312,0xc313,0xc314,0xc315,0xc316,0xc317,
+ 0xc318,0xc319,0xc31a,0xc31b,0xc31c,0xc31d,0xc31e,0xc31f,
+ 0xc320,0xc321,0xc322,0xc323,0xc324,0xc325,0xc326,0xc327,
+ 0xc328,0xc329,0xc32a,0xc32b,0xc32c,0xc32d,0xc32e,0xc32f,
+ 0xc330,0xc331,0xc332,0xc333,0xc334,0xc335,0xc336,0xc337,
+ 0xc338,0xc339,0xc33a,0xc33b,0xc33c,0xc33d,0xc33e,0xc33f,
+ 0xc340,0xc341,0xc342,0xc343,0xc344,0xc345,0xc346,0xc347,
+ 0xc348,0xc349,0xc34a,0xc34b,0xc34c,0xc34d,0xc34e,0xc34f,
+ 0xc350,0xc351,0xc352,0xc353,0xc354,0xc355,0xc356,0xc357,
+ 0xc358,0xc359,0xc35a,0xc35b,0xc35c,0xc35d,0xc35e,0xc35f,
+ 0xc360,0xc361,0xc362,0xc363,0xc364,0xc365,0xc366,0xc367,
+ 0xc368,0xc369,0xc36a,0xc36b,0xc36c,0xc36d,0xc36e,0xc36f,
+ 0xc370,0xc371,0xc372,0xc373,0xc374,0xc375,0xc376,0xc377,
+ 0xc378,0xc379,0xc37a,0xc37b,0xc37c,0xc37d,0xc37e,0xc37f,
+ 0xc380,0xc381,0xc382,0xc383,0xc384,0xc385,0xc386,0xc387,
+ 0xc388,0xc389,0xc38a,0xc38b,0xc38c,0xc38d,0xc38e,0xc38f,
+ 0xc390,0xc391,0xc392,0xc393,0xc394,0xc395,0xc396,0xc397,
+ 0xc398,0xc399,0xc39a,0xc39b,0xc39c,0xc39d,0xc39e,0xc39f,
+ 0xc3a0,0xc3a1,0xc3a2,0xc3a3,0xc3a4,0xc3a5,0xc3a6,0xc3a7,
+ 0xc3a8,0xc3a9,0xc3aa,0xc3ab,0xc3ac,0xc3ad,0xc3ae,0xc3af,
+ 0xc3b0,0xc3b1,0xc3b2,0xc3b3,0xc3b4,0xc3b5,0xc3b6,0xc3b7,
+ 0xc3b8,0xc3b9,0xc3ba,0xc3bb,0xc3bc,0xc3bd,0xc3be,0xc3bf,
+ 0xc3c0,0xc3c1,0xc3c2,0xc3c3,0xc3c4,0xc3c5,0xc3c6,0xc3c7,
+ 0xc3c8,0xc3c9,0xc3ca,0xc3cb,0xc3cc,0xc3cd,0xc3ce,0xc3cf,
+ 0xc3d0,0xc3d1,0xc3d2,0xc3d3,0xc3d4,0xc3d5,0xc3d6,0xc3d7,
+ 0xc3d8,0xc3d9,0xc3da,0xc3db,0xc3dc,0xc3dd,0xc3de,0xc3df,
+ 0xc3e0,0xc3e1,0xc3e2,0xc3e3,0xc3e4,0xc3e5,0xc3e6,0xc3e7,
+ 0xc3e8,0xc3e9,0xc3ea,0xc3eb,0xc3ec,0xc3ed,0xc3ee,0xc3ef,
+ 0xc3f0,0xc3f1,0xc3f2,0xc3f3,0xc3f4,0xc3f5,0xc3f6,0xc3f7,
+ 0xc3f8,0xc3f9,0xc3fa,0xc3fb,0xc3fc,0xc3fd,0xc3fe,0xc3ff,
+ 0xc400,0xc401,0xc402,0xc403,0xc404,0xc405,0xc406,0xc407,
+ 0xc408,0xc409,0xc40a,0xc40b,0xc40c,0xc40d,0xc40e,0xc40f,
+ 0xc410,0xc411,0xc412,0xc413,0xc414,0xc415,0xc416,0xc417,
+ 0xc418,0xc419,0xc41a,0xc41b,0xc41c,0xc41d,0xc41e,0xc41f,
+ 0xc420,0xc421,0xc422,0xc423,0xc424,0xc425,0xc426,0xc427,
+ 0xc428,0xc429,0xc42a,0xc42b,0xc42c,0xc42d,0xc42e,0xc42f,
+ 0xc430,0xc431,0xc432,0xc433,0xc434,0xc435,0xc436,0xc437,
+ 0xc438,0xc439,0xc43a,0xc43b,0xc43c,0xc43d,0xc43e,0xc43f,
+ 0xc440,0xc441,0xc442,0xc443,0xc444,0xc445,0xc446,0xc447,
+ 0xc448,0xc449,0xc44a,0xc44b,0xc44c,0xc44d,0xc44e,0xc44f,
+ 0xc450,0xc451,0xc452,0xc453,0xc454,0xc455,0xc456,0xc457,
+ 0xc458,0xc459,0xc45a,0xc45b,0xc45c,0xc45d,0xc45e,0xc45f,
+ 0xc460,0xc461,0xc462,0xc463,0xc464,0xc465,0xc466,0xc467,
+ 0xc468,0xc469,0xc46a,0xc46b,0xc46c,0xc46d,0xc46e,0xc46f,
+ 0xc470,0xc471,0xc472,0xc473,0xc474,0xc475,0xc476,0xc477,
+ 0xc478,0xc479,0xc47a,0xc47b,0xc47c,0xc47d,0xc47e,0xc47f,
+ 0xc480,0xc481,0xc482,0xc483,0xc484,0xc485,0xc486,0xc487,
+ 0xc488,0xc489,0xc48a,0xc48b,0xc48c,0xc48d,0xc48e,0xc48f,
+ 0xc490,0xc491,0xc492,0xc493,0xc494,0xc495,0xc496,0xc497,
+ 0xc498,0xc499,0xc49a,0xc49b,0xc49c,0xc49d,0xc49e,0xc49f,
+ 0xc4a0,0xc4a1,0xc4a2,0xc4a3,0xc4a4,0xc4a5,0xc4a6,0xc4a7,
+ 0xc4a8,0xc4a9,0xc4aa,0xc4ab,0xc4ac,0xc4ad,0xc4ae,0xc4af,
+ 0xc4b0,0xc4b1,0xc4b2,0xc4b3,0xc4b4,0xc4b5,0xc4b6,0xc4b7,
+ 0xc4b8,0xc4b9,0xc4ba,0xc4bb,0xc4bc,0xc4bd,0xc4be,0xc4bf,
+ 0xc4c0,0xc4c1,0xc4c2,0xc4c3,0xc4c4,0xc4c5,0xc4c6,0xc4c7,
+ 0xc4c8,0xc4c9,0xc4ca,0xc4cb,0xc4cc,0xc4cd,0xc4ce,0xc4cf,
+ 0xc4d0,0xc4d1,0xc4d2,0xc4d3,0xc4d4,0xc4d5,0xc4d6,0xc4d7,
+ 0xc4d8,0xc4d9,0xc4da,0xc4db,0xc4dc,0xc4dd,0xc4de,0xc4df,
+ 0xc4e0,0xc4e1,0xc4e2,0xc4e3,0xc4e4,0xc4e5,0xc4e6,0xc4e7,
+ 0xc4e8,0xc4e9,0xc4ea,0xc4eb,0xc4ec,0xc4ed,0xc4ee,0xc4ef,
+ 0xc4f0,0xc4f1,0xc4f2,0xc4f3,0xc4f4,0xc4f5,0xc4f6,0xc4f7,
+ 0xc4f8,0xc4f9,0xc4fa,0xc4fb,0xc4fc,0xc4fd,0xc4fe,0xc4ff,
+ 0xc500,0xc501,0xc502,0xc503,0xc504,0xc505,0xc506,0xc507,
+ 0xc508,0xc509,0xc50a,0xc50b,0xc50c,0xc50d,0xc50e,0xc50f,
+ 0xc510,0xc511,0xc512,0xc513,0xc514,0xc515,0xc516,0xc517,
+ 0xc518,0xc519,0xc51a,0xc51b,0xc51c,0xc51d,0xc51e,0xc51f,
+ 0xc520,0xc521,0xc522,0xc523,0xc524,0xc525,0xc526,0xc527,
+ 0xc528,0xc529,0xc52a,0xc52b,0xc52c,0xc52d,0xc52e,0xc52f,
+ 0xc530,0xc531,0xc532,0xc533,0xc534,0xc535,0xc536,0xc537,
+ 0xc538,0xc539,0xc53a,0xc53b,0xc53c,0xc53d,0xc53e,0xc53f,
+ 0xc540,0xc541,0xc542,0xc543,0xc544,0xc545,0xc546,0xc547,
+ 0xc548,0xc549,0xc54a,0xc54b,0xc54c,0xc54d,0xc54e,0xc54f,
+ 0xc550,0xc551,0xc552,0xc553,0xc554,0xc555,0xc556,0xc557,
+ 0xc558,0xc559,0xc55a,0xc55b,0xc55c,0xc55d,0xc55e,0xc55f,
+ 0xc560,0xc561,0xc562,0xc563,0xc564,0xc565,0xc566,0xc567,
+ 0xc568,0xc569,0xc56a,0xc56b,0xc56c,0xc56d,0xc56e,0xc56f,
+ 0xc570,0xc571,0xc572,0xc573,0xc574,0xc575,0xc576,0xc577,
+ 0xc578,0xc579,0xc57a,0xc57b,0xc57c,0xc57d,0xc57e,0xc57f,
+ 0xc580,0xc581,0xc582,0xc583,0xc584,0xc585,0xc586,0xc587,
+ 0xc588,0xc589,0xc58a,0xc58b,0xc58c,0xc58d,0xc58e,0xc58f,
+ 0xc590,0xc591,0xc592,0xc593,0xc594,0xc595,0xc596,0xc597,
+ 0xc598,0xc599,0xc59a,0xc59b,0xc59c,0xc59d,0xc59e,0xc59f,
+ 0xc5a0,0xc5a1,0xc5a2,0xc5a3,0xc5a4,0xc5a5,0xc5a6,0xc5a7,
+ 0xc5a8,0xc5a9,0xc5aa,0xc5ab,0xc5ac,0xc5ad,0xc5ae,0xc5af,
+ 0xc5b0,0xc5b1,0xc5b2,0xc5b3,0xc5b4,0xc5b5,0xc5b6,0xc5b7,
+ 0xc5b8,0xc5b9,0xc5ba,0xc5bb,0xc5bc,0xc5bd,0xc5be,0xc5bf,
+ 0xc5c0,0xc5c1,0xc5c2,0xc5c3,0xc5c4,0xc5c5,0xc5c6,0xc5c7,
+ 0xc5c8,0xc5c9,0xc5ca,0xc5cb,0xc5cc,0xc5cd,0xc5ce,0xc5cf,
+ 0xc5d0,0xc5d1,0xc5d2,0xc5d3,0xc5d4,0xc5d5,0xc5d6,0xc5d7,
+ 0xc5d8,0xc5d9,0xc5da,0xc5db,0xc5dc,0xc5dd,0xc5de,0xc5df,
+ 0xc5e0,0xc5e1,0xc5e2,0xc5e3,0xc5e4,0xc5e5,0xc5e6,0xc5e7,
+ 0xc5e8,0xc5e9,0xc5ea,0xc5eb,0xc5ec,0xc5ed,0xc5ee,0xc5ef,
+ 0xc5f0,0xc5f1,0xc5f2,0xc5f3,0xc5f4,0xc5f5,0xc5f6,0xc5f7,
+ 0xc5f8,0xc5f9,0xc5fa,0xc5fb,0xc5fc,0xc5fd,0xc5fe,0xc5ff,
+ 0xc600,0xc601,0xc602,0xc603,0xc604,0xc605,0xc606,0xc607,
+ 0xc608,0xc609,0xc60a,0xc60b,0xc60c,0xc60d,0xc60e,0xc60f,
+ 0xc610,0xc611,0xc612,0xc613,0xc614,0xc615,0xc616,0xc617,
+ 0xc618,0xc619,0xc61a,0xc61b,0xc61c,0xc61d,0xc61e,0xc61f,
+ 0xc620,0xc621,0xc622,0xc623,0xc624,0xc625,0xc626,0xc627,
+ 0xc628,0xc629,0xc62a,0xc62b,0xc62c,0xc62d,0xc62e,0xc62f,
+ 0xc630,0xc631,0xc632,0xc633,0xc634,0xc635,0xc636,0xc637,
+ 0xc638,0xc639,0xc63a,0xc63b,0xc63c,0xc63d,0xc63e,0xc63f,
+ 0xc640,0xc641,0xc642,0xc643,0xc644,0xc645,0xc646,0xc647,
+ 0xc648,0xc649,0xc64a,0xc64b,0xc64c,0xc64d,0xc64e,0xc64f,
+ 0xc650,0xc651,0xc652,0xc653,0xc654,0xc655,0xc656,0xc657,
+ 0xc658,0xc659,0xc65a,0xc65b,0xc65c,0xc65d,0xc65e,0xc65f,
+ 0xc660,0xc661,0xc662,0xc663,0xc664,0xc665,0xc666,0xc667,
+ 0xc668,0xc669,0xc66a,0xc66b,0xc66c,0xc66d,0xc66e,0xc66f,
+ 0xc670,0xc671,0xc672,0xc673,0xc674,0xc675,0xc676,0xc677,
+ 0xc678,0xc679,0xc67a,0xc67b,0xc67c,0xc67d,0xc67e,0xc67f,
+ 0xc680,0xc681,0xc682,0xc683,0xc684,0xc685,0xc686,0xc687,
+ 0xc688,0xc689,0xc68a,0xc68b,0xc68c,0xc68d,0xc68e,0xc68f,
+ 0xc690,0xc691,0xc692,0xc693,0xc694,0xc695,0xc696,0xc697,
+ 0xc698,0xc699,0xc69a,0xc69b,0xc69c,0xc69d,0xc69e,0xc69f,
+ 0xc6a0,0xc6a1,0xc6a2,0xc6a3,0xc6a4,0xc6a5,0xc6a6,0xc6a7,
+ 0xc6a8,0xc6a9,0xc6aa,0xc6ab,0xc6ac,0xc6ad,0xc6ae,0xc6af,
+ 0xc6b0,0xc6b1,0xc6b2,0xc6b3,0xc6b4,0xc6b5,0xc6b6,0xc6b7,
+ 0xc6b8,0xc6b9,0xc6ba,0xc6bb,0xc6bc,0xc6bd,0xc6be,0xc6bf,
+ 0xc6c0,0xc6c1,0xc6c2,0xc6c3,0xc6c4,0xc6c5,0xc6c6,0xc6c7,
+ 0xc6c8,0xc6c9,0xc6ca,0xc6cb,0xc6cc,0xc6cd,0xc6ce,0xc6cf,
+ 0xc6d0,0xc6d1,0xc6d2,0xc6d3,0xc6d4,0xc6d5,0xc6d6,0xc6d7,
+ 0xc6d8,0xc6d9,0xc6da,0xc6db,0xc6dc,0xc6dd,0xc6de,0xc6df,
+ 0xc6e0,0xc6e1,0xc6e2,0xc6e3,0xc6e4,0xc6e5,0xc6e6,0xc6e7,
+ 0xc6e8,0xc6e9,0xc6ea,0xc6eb,0xc6ec,0xc6ed,0xc6ee,0xc6ef,
+ 0xc6f0,0xc6f1,0xc6f2,0xc6f3,0xc6f4,0xc6f5,0xc6f6,0xc6f7,
+ 0xc6f8,0xc6f9,0xc6fa,0xc6fb,0xc6fc,0xc6fd,0xc6fe,0xc6ff,
+ 0xc700,0xc701,0xc702,0xc703,0xc704,0xc705,0xc706,0xc707,
+ 0xc708,0xc709,0xc70a,0xc70b,0xc70c,0xc70d,0xc70e,0xc70f,
+ 0xc710,0xc711,0xc712,0xc713,0xc714,0xc715,0xc716,0xc717,
+ 0xc718,0xc719,0xc71a,0xc71b,0xc71c,0xc71d,0xc71e,0xc71f,
+ 0xc720,0xc721,0xc722,0xc723,0xc724,0xc725,0xc726,0xc727,
+ 0xc728,0xc729,0xc72a,0xc72b,0xc72c,0xc72d,0xc72e,0xc72f,
+ 0xc730,0xc731,0xc732,0xc733,0xc734,0xc735,0xc736,0xc737,
+ 0xc738,0xc739,0xc73a,0xc73b,0xc73c,0xc73d,0xc73e,0xc73f,
+ 0xc740,0xc741,0xc742,0xc743,0xc744,0xc745,0xc746,0xc747,
+ 0xc748,0xc749,0xc74a,0xc74b,0xc74c,0xc74d,0xc74e,0xc74f,
+ 0xc750,0xc751,0xc752,0xc753,0xc754,0xc755,0xc756,0xc757,
+ 0xc758,0xc759,0xc75a,0xc75b,0xc75c,0xc75d,0xc75e,0xc75f,
+ 0xc760,0xc761,0xc762,0xc763,0xc764,0xc765,0xc766,0xc767,
+ 0xc768,0xc769,0xc76a,0xc76b,0xc76c,0xc76d,0xc76e,0xc76f,
+ 0xc770,0xc771,0xc772,0xc773,0xc774,0xc775,0xc776,0xc777,
+ 0xc778,0xc779,0xc77a,0xc77b,0xc77c,0xc77d,0xc77e,0xc77f,
+ 0xc780,0xc781,0xc782,0xc783,0xc784,0xc785,0xc786,0xc787,
+ 0xc788,0xc789,0xc78a,0xc78b,0xc78c,0xc78d,0xc78e,0xc78f,
+ 0xc790,0xc791,0xc792,0xc793,0xc794,0xc795,0xc796,0xc797,
+ 0xc798,0xc799,0xc79a,0xc79b,0xc79c,0xc79d,0xc79e,0xc79f,
+ 0xc7a0,0xc7a1,0xc7a2,0xc7a3,0xc7a4,0xc7a5,0xc7a6,0xc7a7,
+ 0xc7a8,0xc7a9,0xc7aa,0xc7ab,0xc7ac,0xc7ad,0xc7ae,0xc7af,
+ 0xc7b0,0xc7b1,0xc7b2,0xc7b3,0xc7b4,0xc7b5,0xc7b6,0xc7b7,
+ 0xc7b8,0xc7b9,0xc7ba,0xc7bb,0xc7bc,0xc7bd,0xc7be,0xc7bf,
+ 0xc7c0,0xc7c1,0xc7c2,0xc7c3,0xc7c4,0xc7c5,0xc7c6,0xc7c7,
+ 0xc7c8,0xc7c9,0xc7ca,0xc7cb,0xc7cc,0xc7cd,0xc7ce,0xc7cf,
+ 0xc7d0,0xc7d1,0xc7d2,0xc7d3,0xc7d4,0xc7d5,0xc7d6,0xc7d7,
+ 0xc7d8,0xc7d9,0xc7da,0xc7db,0xc7dc,0xc7dd,0xc7de,0xc7df,
+ 0xc7e0,0xc7e1,0xc7e2,0xc7e3,0xc7e4,0xc7e5,0xc7e6,0xc7e7,
+ 0xc7e8,0xc7e9,0xc7ea,0xc7eb,0xc7ec,0xc7ed,0xc7ee,0xc7ef,
+ 0xc7f0,0xc7f1,0xc7f2,0xc7f3,0xc7f4,0xc7f5,0xc7f6,0xc7f7,
+ 0xc7f8,0xc7f9,0xc7fa,0xc7fb,0xc7fc,0xc7fd,0xc7fe,0xc7ff,
+ 0xc800,0xc801,0xc802,0xc803,0xc804,0xc805,0xc806,0xc807,
+ 0xc808,0xc809,0xc80a,0xc80b,0xc80c,0xc80d,0xc80e,0xc80f,
+ 0xc810,0xc811,0xc812,0xc813,0xc814,0xc815,0xc816,0xc817,
+ 0xc818,0xc819,0xc81a,0xc81b,0xc81c,0xc81d,0xc81e,0xc81f,
+ 0xc820,0xc821,0xc822,0xc823,0xc824,0xc825,0xc826,0xc827,
+ 0xc828,0xc829,0xc82a,0xc82b,0xc82c,0xc82d,0xc82e,0xc82f,
+ 0xc830,0xc831,0xc832,0xc833,0xc834,0xc835,0xc836,0xc837,
+ 0xc838,0xc839,0xc83a,0xc83b,0xc83c,0xc83d,0xc83e,0xc83f,
+ 0xc840,0xc841,0xc842,0xc843,0xc844,0xc845,0xc846,0xc847,
+ 0xc848,0xc849,0xc84a,0xc84b,0xc84c,0xc84d,0xc84e,0xc84f,
+ 0xc850,0xc851,0xc852,0xc853,0xc854,0xc855,0xc856,0xc857,
+ 0xc858,0xc859,0xc85a,0xc85b,0xc85c,0xc85d,0xc85e,0xc85f,
+ 0xc860,0xc861,0xc862,0xc863,0xc864,0xc865,0xc866,0xc867,
+ 0xc868,0xc869,0xc86a,0xc86b,0xc86c,0xc86d,0xc86e,0xc86f,
+ 0xc870,0xc871,0xc872,0xc873,0xc874,0xc875,0xc876,0xc877,
+ 0xc878,0xc879,0xc87a,0xc87b,0xc87c,0xc87d,0xc87e,0xc87f,
+ 0xc880,0xc881,0xc882,0xc883,0xc884,0xc885,0xc886,0xc887,
+ 0xc888,0xc889,0xc88a,0xc88b,0xc88c,0xc88d,0xc88e,0xc88f,
+ 0xc890,0xc891,0xc892,0xc893,0xc894,0xc895,0xc896,0xc897,
+ 0xc898,0xc899,0xc89a,0xc89b,0xc89c,0xc89d,0xc89e,0xc89f,
+ 0xc8a0,0xc8a1,0xc8a2,0xc8a3,0xc8a4,0xc8a5,0xc8a6,0xc8a7,
+ 0xc8a8,0xc8a9,0xc8aa,0xc8ab,0xc8ac,0xc8ad,0xc8ae,0xc8af,
+ 0xc8b0,0xc8b1,0xc8b2,0xc8b3,0xc8b4,0xc8b5,0xc8b6,0xc8b7,
+ 0xc8b8,0xc8b9,0xc8ba,0xc8bb,0xc8bc,0xc8bd,0xc8be,0xc8bf,
+ 0xc8c0,0xc8c1,0xc8c2,0xc8c3,0xc8c4,0xc8c5,0xc8c6,0xc8c7,
+ 0xc8c8,0xc8c9,0xc8ca,0xc8cb,0xc8cc,0xc8cd,0xc8ce,0xc8cf,
+ 0xc8d0,0xc8d1,0xc8d2,0xc8d3,0xc8d4,0xc8d5,0xc8d6,0xc8d7,
+ 0xc8d8,0xc8d9,0xc8da,0xc8db,0xc8dc,0xc8dd,0xc8de,0xc8df,
+ 0xc8e0,0xc8e1,0xc8e2,0xc8e3,0xc8e4,0xc8e5,0xc8e6,0xc8e7,
+ 0xc8e8,0xc8e9,0xc8ea,0xc8eb,0xc8ec,0xc8ed,0xc8ee,0xc8ef,
+ 0xc8f0,0xc8f1,0xc8f2,0xc8f3,0xc8f4,0xc8f5,0xc8f6,0xc8f7,
+ 0xc8f8,0xc8f9,0xc8fa,0xc8fb,0xc8fc,0xc8fd,0xc8fe,0xc8ff,
+ 0xc900,0xc901,0xc902,0xc903,0xc904,0xc905,0xc906,0xc907,
+ 0xc908,0xc909,0xc90a,0xc90b,0xc90c,0xc90d,0xc90e,0xc90f,
+ 0xc910,0xc911,0xc912,0xc913,0xc914,0xc915,0xc916,0xc917,
+ 0xc918,0xc919,0xc91a,0xc91b,0xc91c,0xc91d,0xc91e,0xc91f,
+ 0xc920,0xc921,0xc922,0xc923,0xc924,0xc925,0xc926,0xc927,
+ 0xc928,0xc929,0xc92a,0xc92b,0xc92c,0xc92d,0xc92e,0xc92f,
+ 0xc930,0xc931,0xc932,0xc933,0xc934,0xc935,0xc936,0xc937,
+ 0xc938,0xc939,0xc93a,0xc93b,0xc93c,0xc93d,0xc93e,0xc93f,
+ 0xc940,0xc941,0xc942,0xc943,0xc944,0xc945,0xc946,0xc947,
+ 0xc948,0xc949,0xc94a,0xc94b,0xc94c,0xc94d,0xc94e,0xc94f,
+ 0xc950,0xc951,0xc952,0xc953,0xc954,0xc955,0xc956,0xc957,
+ 0xc958,0xc959,0xc95a,0xc95b,0xc95c,0xc95d,0xc95e,0xc95f,
+ 0xc960,0xc961,0xc962,0xc963,0xc964,0xc965,0xc966,0xc967,
+ 0xc968,0xc969,0xc96a,0xc96b,0xc96c,0xc96d,0xc96e,0xc96f,
+ 0xc970,0xc971,0xc972,0xc973,0xc974,0xc975,0xc976,0xc977,
+ 0xc978,0xc979,0xc97a,0xc97b,0xc97c,0xc97d,0xc97e,0xc97f,
+ 0xc980,0xc981,0xc982,0xc983,0xc984,0xc985,0xc986,0xc987,
+ 0xc988,0xc989,0xc98a,0xc98b,0xc98c,0xc98d,0xc98e,0xc98f,
+ 0xc990,0xc991,0xc992,0xc993,0xc994,0xc995,0xc996,0xc997,
+ 0xc998,0xc999,0xc99a,0xc99b,0xc99c,0xc99d,0xc99e,0xc99f,
+ 0xc9a0,0xc9a1,0xc9a2,0xc9a3,0xc9a4,0xc9a5,0xc9a6,0xc9a7,
+ 0xc9a8,0xc9a9,0xc9aa,0xc9ab,0xc9ac,0xc9ad,0xc9ae,0xc9af,
+ 0xc9b0,0xc9b1,0xc9b2,0xc9b3,0xc9b4,0xc9b5,0xc9b6,0xc9b7,
+ 0xc9b8,0xc9b9,0xc9ba,0xc9bb,0xc9bc,0xc9bd,0xc9be,0xc9bf,
+ 0xc9c0,0xc9c1,0xc9c2,0xc9c3,0xc9c4,0xc9c5,0xc9c6,0xc9c7,
+ 0xc9c8,0xc9c9,0xc9ca,0xc9cb,0xc9cc,0xc9cd,0xc9ce,0xc9cf,
+ 0xc9d0,0xc9d1,0xc9d2,0xc9d3,0xc9d4,0xc9d5,0xc9d6,0xc9d7,
+ 0xc9d8,0xc9d9,0xc9da,0xc9db,0xc9dc,0xc9dd,0xc9de,0xc9df,
+ 0xc9e0,0xc9e1,0xc9e2,0xc9e3,0xc9e4,0xc9e5,0xc9e6,0xc9e7,
+ 0xc9e8,0xc9e9,0xc9ea,0xc9eb,0xc9ec,0xc9ed,0xc9ee,0xc9ef,
+ 0xc9f0,0xc9f1,0xc9f2,0xc9f3,0xc9f4,0xc9f5,0xc9f6,0xc9f7,
+ 0xc9f8,0xc9f9,0xc9fa,0xc9fb,0xc9fc,0xc9fd,0xc9fe,0xc9ff,
+ 0xca00,0xca01,0xca02,0xca03,0xca04,0xca05,0xca06,0xca07,
+ 0xca08,0xca09,0xca0a,0xca0b,0xca0c,0xca0d,0xca0e,0xca0f,
+ 0xca10,0xca11,0xca12,0xca13,0xca14,0xca15,0xca16,0xca17,
+ 0xca18,0xca19,0xca1a,0xca1b,0xca1c,0xca1d,0xca1e,0xca1f,
+ 0xca20,0xca21,0xca22,0xca23,0xca24,0xca25,0xca26,0xca27,
+ 0xca28,0xca29,0xca2a,0xca2b,0xca2c,0xca2d,0xca2e,0xca2f,
+ 0xca30,0xca31,0xca32,0xca33,0xca34,0xca35,0xca36,0xca37,
+ 0xca38,0xca39,0xca3a,0xca3b,0xca3c,0xca3d,0xca3e,0xca3f,
+ 0xca40,0xca41,0xca42,0xca43,0xca44,0xca45,0xca46,0xca47,
+ 0xca48,0xca49,0xca4a,0xca4b,0xca4c,0xca4d,0xca4e,0xca4f,
+ 0xca50,0xca51,0xca52,0xca53,0xca54,0xca55,0xca56,0xca57,
+ 0xca58,0xca59,0xca5a,0xca5b,0xca5c,0xca5d,0xca5e,0xca5f,
+ 0xca60,0xca61,0xca62,0xca63,0xca64,0xca65,0xca66,0xca67,
+ 0xca68,0xca69,0xca6a,0xca6b,0xca6c,0xca6d,0xca6e,0xca6f,
+ 0xca70,0xca71,0xca72,0xca73,0xca74,0xca75,0xca76,0xca77,
+ 0xca78,0xca79,0xca7a,0xca7b,0xca7c,0xca7d,0xca7e,0xca7f,
+ 0xca80,0xca81,0xca82,0xca83,0xca84,0xca85,0xca86,0xca87,
+ 0xca88,0xca89,0xca8a,0xca8b,0xca8c,0xca8d,0xca8e,0xca8f,
+ 0xca90,0xca91,0xca92,0xca93,0xca94,0xca95,0xca96,0xca97,
+ 0xca98,0xca99,0xca9a,0xca9b,0xca9c,0xca9d,0xca9e,0xca9f,
+ 0xcaa0,0xcaa1,0xcaa2,0xcaa3,0xcaa4,0xcaa5,0xcaa6,0xcaa7,
+ 0xcaa8,0xcaa9,0xcaaa,0xcaab,0xcaac,0xcaad,0xcaae,0xcaaf,
+ 0xcab0,0xcab1,0xcab2,0xcab3,0xcab4,0xcab5,0xcab6,0xcab7,
+ 0xcab8,0xcab9,0xcaba,0xcabb,0xcabc,0xcabd,0xcabe,0xcabf,
+ 0xcac0,0xcac1,0xcac2,0xcac3,0xcac4,0xcac5,0xcac6,0xcac7,
+ 0xcac8,0xcac9,0xcaca,0xcacb,0xcacc,0xcacd,0xcace,0xcacf,
+ 0xcad0,0xcad1,0xcad2,0xcad3,0xcad4,0xcad5,0xcad6,0xcad7,
+ 0xcad8,0xcad9,0xcada,0xcadb,0xcadc,0xcadd,0xcade,0xcadf,
+ 0xcae0,0xcae1,0xcae2,0xcae3,0xcae4,0xcae5,0xcae6,0xcae7,
+ 0xcae8,0xcae9,0xcaea,0xcaeb,0xcaec,0xcaed,0xcaee,0xcaef,
+ 0xcaf0,0xcaf1,0xcaf2,0xcaf3,0xcaf4,0xcaf5,0xcaf6,0xcaf7,
+ 0xcaf8,0xcaf9,0xcafa,0xcafb,0xcafc,0xcafd,0xcafe,0xcaff,
+ 0xcb00,0xcb01,0xcb02,0xcb03,0xcb04,0xcb05,0xcb06,0xcb07,
+ 0xcb08,0xcb09,0xcb0a,0xcb0b,0xcb0c,0xcb0d,0xcb0e,0xcb0f,
+ 0xcb10,0xcb11,0xcb12,0xcb13,0xcb14,0xcb15,0xcb16,0xcb17,
+ 0xcb18,0xcb19,0xcb1a,0xcb1b,0xcb1c,0xcb1d,0xcb1e,0xcb1f,
+ 0xcb20,0xcb21,0xcb22,0xcb23,0xcb24,0xcb25,0xcb26,0xcb27,
+ 0xcb28,0xcb29,0xcb2a,0xcb2b,0xcb2c,0xcb2d,0xcb2e,0xcb2f,
+ 0xcb30,0xcb31,0xcb32,0xcb33,0xcb34,0xcb35,0xcb36,0xcb37,
+ 0xcb38,0xcb39,0xcb3a,0xcb3b,0xcb3c,0xcb3d,0xcb3e,0xcb3f,
+ 0xcb40,0xcb41,0xcb42,0xcb43,0xcb44,0xcb45,0xcb46,0xcb47,
+ 0xcb48,0xcb49,0xcb4a,0xcb4b,0xcb4c,0xcb4d,0xcb4e,0xcb4f,
+ 0xcb50,0xcb51,0xcb52,0xcb53,0xcb54,0xcb55,0xcb56,0xcb57,
+ 0xcb58,0xcb59,0xcb5a,0xcb5b,0xcb5c,0xcb5d,0xcb5e,0xcb5f,
+ 0xcb60,0xcb61,0xcb62,0xcb63,0xcb64,0xcb65,0xcb66,0xcb67,
+ 0xcb68,0xcb69,0xcb6a,0xcb6b,0xcb6c,0xcb6d,0xcb6e,0xcb6f,
+ 0xcb70,0xcb71,0xcb72,0xcb73,0xcb74,0xcb75,0xcb76,0xcb77,
+ 0xcb78,0xcb79,0xcb7a,0xcb7b,0xcb7c,0xcb7d,0xcb7e,0xcb7f,
+ 0xcb80,0xcb81,0xcb82,0xcb83,0xcb84,0xcb85,0xcb86,0xcb87,
+ 0xcb88,0xcb89,0xcb8a,0xcb8b,0xcb8c,0xcb8d,0xcb8e,0xcb8f,
+ 0xcb90,0xcb91,0xcb92,0xcb93,0xcb94,0xcb95,0xcb96,0xcb97,
+ 0xcb98,0xcb99,0xcb9a,0xcb9b,0xcb9c,0xcb9d,0xcb9e,0xcb9f,
+ 0xcba0,0xcba1,0xcba2,0xcba3,0xcba4,0xcba5,0xcba6,0xcba7,
+ 0xcba8,0xcba9,0xcbaa,0xcbab,0xcbac,0xcbad,0xcbae,0xcbaf,
+ 0xcbb0,0xcbb1,0xcbb2,0xcbb3,0xcbb4,0xcbb5,0xcbb6,0xcbb7,
+ 0xcbb8,0xcbb9,0xcbba,0xcbbb,0xcbbc,0xcbbd,0xcbbe,0xcbbf,
+ 0xcbc0,0xcbc1,0xcbc2,0xcbc3,0xcbc4,0xcbc5,0xcbc6,0xcbc7,
+ 0xcbc8,0xcbc9,0xcbca,0xcbcb,0xcbcc,0xcbcd,0xcbce,0xcbcf,
+ 0xcbd0,0xcbd1,0xcbd2,0xcbd3,0xcbd4,0xcbd5,0xcbd6,0xcbd7,
+ 0xcbd8,0xcbd9,0xcbda,0xcbdb,0xcbdc,0xcbdd,0xcbde,0xcbdf,
+ 0xcbe0,0xcbe1,0xcbe2,0xcbe3,0xcbe4,0xcbe5,0xcbe6,0xcbe7,
+ 0xcbe8,0xcbe9,0xcbea,0xcbeb,0xcbec,0xcbed,0xcbee,0xcbef,
+ 0xcbf0,0xcbf1,0xcbf2,0xcbf3,0xcbf4,0xcbf5,0xcbf6,0xcbf7,
+ 0xcbf8,0xcbf9,0xcbfa,0xcbfb,0xcbfc,0xcbfd,0xcbfe,0xcbff,
+ 0xcc00,0xcc01,0xcc02,0xcc03,0xcc04,0xcc05,0xcc06,0xcc07,
+ 0xcc08,0xcc09,0xcc0a,0xcc0b,0xcc0c,0xcc0d,0xcc0e,0xcc0f,
+ 0xcc10,0xcc11,0xcc12,0xcc13,0xcc14,0xcc15,0xcc16,0xcc17,
+ 0xcc18,0xcc19,0xcc1a,0xcc1b,0xcc1c,0xcc1d,0xcc1e,0xcc1f,
+ 0xcc20,0xcc21,0xcc22,0xcc23,0xcc24,0xcc25,0xcc26,0xcc27,
+ 0xcc28,0xcc29,0xcc2a,0xcc2b,0xcc2c,0xcc2d,0xcc2e,0xcc2f,
+ 0xcc30,0xcc31,0xcc32,0xcc33,0xcc34,0xcc35,0xcc36,0xcc37,
+ 0xcc38,0xcc39,0xcc3a,0xcc3b,0xcc3c,0xcc3d,0xcc3e,0xcc3f,
+ 0xcc40,0xcc41,0xcc42,0xcc43,0xcc44,0xcc45,0xcc46,0xcc47,
+ 0xcc48,0xcc49,0xcc4a,0xcc4b,0xcc4c,0xcc4d,0xcc4e,0xcc4f,
+ 0xcc50,0xcc51,0xcc52,0xcc53,0xcc54,0xcc55,0xcc56,0xcc57,
+ 0xcc58,0xcc59,0xcc5a,0xcc5b,0xcc5c,0xcc5d,0xcc5e,0xcc5f,
+ 0xcc60,0xcc61,0xcc62,0xcc63,0xcc64,0xcc65,0xcc66,0xcc67,
+ 0xcc68,0xcc69,0xcc6a,0xcc6b,0xcc6c,0xcc6d,0xcc6e,0xcc6f,
+ 0xcc70,0xcc71,0xcc72,0xcc73,0xcc74,0xcc75,0xcc76,0xcc77,
+ 0xcc78,0xcc79,0xcc7a,0xcc7b,0xcc7c,0xcc7d,0xcc7e,0xcc7f,
+ 0xcc80,0xcc81,0xcc82,0xcc83,0xcc84,0xcc85,0xcc86,0xcc87,
+ 0xcc88,0xcc89,0xcc8a,0xcc8b,0xcc8c,0xcc8d,0xcc8e,0xcc8f,
+ 0xcc90,0xcc91,0xcc92,0xcc93,0xcc94,0xcc95,0xcc96,0xcc97,
+ 0xcc98,0xcc99,0xcc9a,0xcc9b,0xcc9c,0xcc9d,0xcc9e,0xcc9f,
+ 0xcca0,0xcca1,0xcca2,0xcca3,0xcca4,0xcca5,0xcca6,0xcca7,
+ 0xcca8,0xcca9,0xccaa,0xccab,0xccac,0xccad,0xccae,0xccaf,
+ 0xccb0,0xccb1,0xccb2,0xccb3,0xccb4,0xccb5,0xccb6,0xccb7,
+ 0xccb8,0xccb9,0xccba,0xccbb,0xccbc,0xccbd,0xccbe,0xccbf,
+ 0xccc0,0xccc1,0xccc2,0xccc3,0xccc4,0xccc5,0xccc6,0xccc7,
+ 0xccc8,0xccc9,0xccca,0xcccb,0xcccc,0xcccd,0xccce,0xcccf,
+ 0xccd0,0xccd1,0xccd2,0xccd3,0xccd4,0xccd5,0xccd6,0xccd7,
+ 0xccd8,0xccd9,0xccda,0xccdb,0xccdc,0xccdd,0xccde,0xccdf,
+ 0xcce0,0xcce1,0xcce2,0xcce3,0xcce4,0xcce5,0xcce6,0xcce7,
+ 0xcce8,0xcce9,0xccea,0xcceb,0xccec,0xcced,0xccee,0xccef,
+ 0xccf0,0xccf1,0xccf2,0xccf3,0xccf4,0xccf5,0xccf6,0xccf7,
+ 0xccf8,0xccf9,0xccfa,0xccfb,0xccfc,0xccfd,0xccfe,0xccff,
+ 0xcd00,0xcd01,0xcd02,0xcd03,0xcd04,0xcd05,0xcd06,0xcd07,
+ 0xcd08,0xcd09,0xcd0a,0xcd0b,0xcd0c,0xcd0d,0xcd0e,0xcd0f,
+ 0xcd10,0xcd11,0xcd12,0xcd13,0xcd14,0xcd15,0xcd16,0xcd17,
+ 0xcd18,0xcd19,0xcd1a,0xcd1b,0xcd1c,0xcd1d,0xcd1e,0xcd1f,
+ 0xcd20,0xcd21,0xcd22,0xcd23,0xcd24,0xcd25,0xcd26,0xcd27,
+ 0xcd28,0xcd29,0xcd2a,0xcd2b,0xcd2c,0xcd2d,0xcd2e,0xcd2f,
+ 0xcd30,0xcd31,0xcd32,0xcd33,0xcd34,0xcd35,0xcd36,0xcd37,
+ 0xcd38,0xcd39,0xcd3a,0xcd3b,0xcd3c,0xcd3d,0xcd3e,0xcd3f,
+ 0xcd40,0xcd41,0xcd42,0xcd43,0xcd44,0xcd45,0xcd46,0xcd47,
+ 0xcd48,0xcd49,0xcd4a,0xcd4b,0xcd4c,0xcd4d,0xcd4e,0xcd4f,
+ 0xcd50,0xcd51,0xcd52,0xcd53,0xcd54,0xcd55,0xcd56,0xcd57,
+ 0xcd58,0xcd59,0xcd5a,0xcd5b,0xcd5c,0xcd5d,0xcd5e,0xcd5f,
+ 0xcd60,0xcd61,0xcd62,0xcd63,0xcd64,0xcd65,0xcd66,0xcd67,
+ 0xcd68,0xcd69,0xcd6a,0xcd6b,0xcd6c,0xcd6d,0xcd6e,0xcd6f,
+ 0xcd70,0xcd71,0xcd72,0xcd73,0xcd74,0xcd75,0xcd76,0xcd77,
+ 0xcd78,0xcd79,0xcd7a,0xcd7b,0xcd7c,0xcd7d,0xcd7e,0xcd7f,
+ 0xcd80,0xcd81,0xcd82,0xcd83,0xcd84,0xcd85,0xcd86,0xcd87,
+ 0xcd88,0xcd89,0xcd8a,0xcd8b,0xcd8c,0xcd8d,0xcd8e,0xcd8f,
+ 0xcd90,0xcd91,0xcd92,0xcd93,0xcd94,0xcd95,0xcd96,0xcd97,
+ 0xcd98,0xcd99,0xcd9a,0xcd9b,0xcd9c,0xcd9d,0xcd9e,0xcd9f,
+ 0xcda0,0xcda1,0xcda2,0xcda3,0xcda4,0xcda5,0xcda6,0xcda7,
+ 0xcda8,0xcda9,0xcdaa,0xcdab,0xcdac,0xcdad,0xcdae,0xcdaf,
+ 0xcdb0,0xcdb1,0xcdb2,0xcdb3,0xcdb4,0xcdb5,0xcdb6,0xcdb7,
+ 0xcdb8,0xcdb9,0xcdba,0xcdbb,0xcdbc,0xcdbd,0xcdbe,0xcdbf,
+ 0xcdc0,0xcdc1,0xcdc2,0xcdc3,0xcdc4,0xcdc5,0xcdc6,0xcdc7,
+ 0xcdc8,0xcdc9,0xcdca,0xcdcb,0xcdcc,0xcdcd,0xcdce,0xcdcf,
+ 0xcdd0,0xcdd1,0xcdd2,0xcdd3,0xcdd4,0xcdd5,0xcdd6,0xcdd7,
+ 0xcdd8,0xcdd9,0xcdda,0xcddb,0xcddc,0xcddd,0xcdde,0xcddf,
+ 0xcde0,0xcde1,0xcde2,0xcde3,0xcde4,0xcde5,0xcde6,0xcde7,
+ 0xcde8,0xcde9,0xcdea,0xcdeb,0xcdec,0xcded,0xcdee,0xcdef,
+ 0xcdf0,0xcdf1,0xcdf2,0xcdf3,0xcdf4,0xcdf5,0xcdf6,0xcdf7,
+ 0xcdf8,0xcdf9,0xcdfa,0xcdfb,0xcdfc,0xcdfd,0xcdfe,0xcdff,
+ 0xce00,0xce01,0xce02,0xce03,0xce04,0xce05,0xce06,0xce07,
+ 0xce08,0xce09,0xce0a,0xce0b,0xce0c,0xce0d,0xce0e,0xce0f,
+ 0xce10,0xce11,0xce12,0xce13,0xce14,0xce15,0xce16,0xce17,
+ 0xce18,0xce19,0xce1a,0xce1b,0xce1c,0xce1d,0xce1e,0xce1f,
+ 0xce20,0xce21,0xce22,0xce23,0xce24,0xce25,0xce26,0xce27,
+ 0xce28,0xce29,0xce2a,0xce2b,0xce2c,0xce2d,0xce2e,0xce2f,
+ 0xce30,0xce31,0xce32,0xce33,0xce34,0xce35,0xce36,0xce37,
+ 0xce38,0xce39,0xce3a,0xce3b,0xce3c,0xce3d,0xce3e,0xce3f,
+ 0xce40,0xce41,0xce42,0xce43,0xce44,0xce45,0xce46,0xce47,
+ 0xce48,0xce49,0xce4a,0xce4b,0xce4c,0xce4d,0xce4e,0xce4f,
+ 0xce50,0xce51,0xce52,0xce53,0xce54,0xce55,0xce56,0xce57,
+ 0xce58,0xce59,0xce5a,0xce5b,0xce5c,0xce5d,0xce5e,0xce5f,
+ 0xce60,0xce61,0xce62,0xce63,0xce64,0xce65,0xce66,0xce67,
+ 0xce68,0xce69,0xce6a,0xce6b,0xce6c,0xce6d,0xce6e,0xce6f,
+ 0xce70,0xce71,0xce72,0xce73,0xce74,0xce75,0xce76,0xce77,
+ 0xce78,0xce79,0xce7a,0xce7b,0xce7c,0xce7d,0xce7e,0xce7f,
+ 0xce80,0xce81,0xce82,0xce83,0xce84,0xce85,0xce86,0xce87,
+ 0xce88,0xce89,0xce8a,0xce8b,0xce8c,0xce8d,0xce8e,0xce8f,
+ 0xce90,0xce91,0xce92,0xce93,0xce94,0xce95,0xce96,0xce97,
+ 0xce98,0xce99,0xce9a,0xce9b,0xce9c,0xce9d,0xce9e,0xce9f,
+ 0xcea0,0xcea1,0xcea2,0xcea3,0xcea4,0xcea5,0xcea6,0xcea7,
+ 0xcea8,0xcea9,0xceaa,0xceab,0xceac,0xcead,0xceae,0xceaf,
+ 0xceb0,0xceb1,0xceb2,0xceb3,0xceb4,0xceb5,0xceb6,0xceb7,
+ 0xceb8,0xceb9,0xceba,0xcebb,0xcebc,0xcebd,0xcebe,0xcebf,
+ 0xcec0,0xcec1,0xcec2,0xcec3,0xcec4,0xcec5,0xcec6,0xcec7,
+ 0xcec8,0xcec9,0xceca,0xcecb,0xcecc,0xcecd,0xcece,0xcecf,
+ 0xced0,0xced1,0xced2,0xced3,0xced4,0xced5,0xced6,0xced7,
+ 0xced8,0xced9,0xceda,0xcedb,0xcedc,0xcedd,0xcede,0xcedf,
+ 0xcee0,0xcee1,0xcee2,0xcee3,0xcee4,0xcee5,0xcee6,0xcee7,
+ 0xcee8,0xcee9,0xceea,0xceeb,0xceec,0xceed,0xceee,0xceef,
+ 0xcef0,0xcef1,0xcef2,0xcef3,0xcef4,0xcef5,0xcef6,0xcef7,
+ 0xcef8,0xcef9,0xcefa,0xcefb,0xcefc,0xcefd,0xcefe,0xceff,
+ 0xcf00,0xcf01,0xcf02,0xcf03,0xcf04,0xcf05,0xcf06,0xcf07,
+ 0xcf08,0xcf09,0xcf0a,0xcf0b,0xcf0c,0xcf0d,0xcf0e,0xcf0f,
+ 0xcf10,0xcf11,0xcf12,0xcf13,0xcf14,0xcf15,0xcf16,0xcf17,
+ 0xcf18,0xcf19,0xcf1a,0xcf1b,0xcf1c,0xcf1d,0xcf1e,0xcf1f,
+ 0xcf20,0xcf21,0xcf22,0xcf23,0xcf24,0xcf25,0xcf26,0xcf27,
+ 0xcf28,0xcf29,0xcf2a,0xcf2b,0xcf2c,0xcf2d,0xcf2e,0xcf2f,
+ 0xcf30,0xcf31,0xcf32,0xcf33,0xcf34,0xcf35,0xcf36,0xcf37,
+ 0xcf38,0xcf39,0xcf3a,0xcf3b,0xcf3c,0xcf3d,0xcf3e,0xcf3f,
+ 0xcf40,0xcf41,0xcf42,0xcf43,0xcf44,0xcf45,0xcf46,0xcf47,
+ 0xcf48,0xcf49,0xcf4a,0xcf4b,0xcf4c,0xcf4d,0xcf4e,0xcf4f,
+ 0xcf50,0xcf51,0xcf52,0xcf53,0xcf54,0xcf55,0xcf56,0xcf57,
+ 0xcf58,0xcf59,0xcf5a,0xcf5b,0xcf5c,0xcf5d,0xcf5e,0xcf5f,
+ 0xcf60,0xcf61,0xcf62,0xcf63,0xcf64,0xcf65,0xcf66,0xcf67,
+ 0xcf68,0xcf69,0xcf6a,0xcf6b,0xcf6c,0xcf6d,0xcf6e,0xcf6f,
+ 0xcf70,0xcf71,0xcf72,0xcf73,0xcf74,0xcf75,0xcf76,0xcf77,
+ 0xcf78,0xcf79,0xcf7a,0xcf7b,0xcf7c,0xcf7d,0xcf7e,0xcf7f,
+ 0xcf80,0xcf81,0xcf82,0xcf83,0xcf84,0xcf85,0xcf86,0xcf87,
+ 0xcf88,0xcf89,0xcf8a,0xcf8b,0xcf8c,0xcf8d,0xcf8e,0xcf8f,
+ 0xcf90,0xcf91,0xcf92,0xcf93,0xcf94,0xcf95,0xcf96,0xcf97,
+ 0xcf98,0xcf99,0xcf9a,0xcf9b,0xcf9c,0xcf9d,0xcf9e,0xcf9f,
+ 0xcfa0,0xcfa1,0xcfa2,0xcfa3,0xcfa4,0xcfa5,0xcfa6,0xcfa7,
+ 0xcfa8,0xcfa9,0xcfaa,0xcfab,0xcfac,0xcfad,0xcfae,0xcfaf,
+ 0xcfb0,0xcfb1,0xcfb2,0xcfb3,0xcfb4,0xcfb5,0xcfb6,0xcfb7,
+ 0xcfb8,0xcfb9,0xcfba,0xcfbb,0xcfbc,0xcfbd,0xcfbe,0xcfbf,
+ 0xcfc0,0xcfc1,0xcfc2,0xcfc3,0xcfc4,0xcfc5,0xcfc6,0xcfc7,
+ 0xcfc8,0xcfc9,0xcfca,0xcfcb,0xcfcc,0xcfcd,0xcfce,0xcfcf,
+ 0xcfd0,0xcfd1,0xcfd2,0xcfd3,0xcfd4,0xcfd5,0xcfd6,0xcfd7,
+ 0xcfd8,0xcfd9,0xcfda,0xcfdb,0xcfdc,0xcfdd,0xcfde,0xcfdf,
+ 0xcfe0,0xcfe1,0xcfe2,0xcfe3,0xcfe4,0xcfe5,0xcfe6,0xcfe7,
+ 0xcfe8,0xcfe9,0xcfea,0xcfeb,0xcfec,0xcfed,0xcfee,0xcfef,
+ 0xcff0,0xcff1,0xcff2,0xcff3,0xcff4,0xcff5,0xcff6,0xcff7,
+ 0xcff8,0xcff9,0xcffa,0xcffb,0xcffc,0xcffd,0xcffe,0xcfff,
+ 0xd000,0xd001,0xd002,0xd003,0xd004,0xd005,0xd006,0xd007,
+ 0xd008,0xd009,0xd00a,0xd00b,0xd00c,0xd00d,0xd00e,0xd00f,
+ 0xd010,0xd011,0xd012,0xd013,0xd014,0xd015,0xd016,0xd017,
+ 0xd018,0xd019,0xd01a,0xd01b,0xd01c,0xd01d,0xd01e,0xd01f,
+ 0xd020,0xd021,0xd022,0xd023,0xd024,0xd025,0xd026,0xd027,
+ 0xd028,0xd029,0xd02a,0xd02b,0xd02c,0xd02d,0xd02e,0xd02f,
+ 0xd030,0xd031,0xd032,0xd033,0xd034,0xd035,0xd036,0xd037,
+ 0xd038,0xd039,0xd03a,0xd03b,0xd03c,0xd03d,0xd03e,0xd03f,
+ 0xd040,0xd041,0xd042,0xd043,0xd044,0xd045,0xd046,0xd047,
+ 0xd048,0xd049,0xd04a,0xd04b,0xd04c,0xd04d,0xd04e,0xd04f,
+ 0xd050,0xd051,0xd052,0xd053,0xd054,0xd055,0xd056,0xd057,
+ 0xd058,0xd059,0xd05a,0xd05b,0xd05c,0xd05d,0xd05e,0xd05f,
+ 0xd060,0xd061,0xd062,0xd063,0xd064,0xd065,0xd066,0xd067,
+ 0xd068,0xd069,0xd06a,0xd06b,0xd06c,0xd06d,0xd06e,0xd06f,
+ 0xd070,0xd071,0xd072,0xd073,0xd074,0xd075,0xd076,0xd077,
+ 0xd078,0xd079,0xd07a,0xd07b,0xd07c,0xd07d,0xd07e,0xd07f,
+ 0xd080,0xd081,0xd082,0xd083,0xd084,0xd085,0xd086,0xd087,
+ 0xd088,0xd089,0xd08a,0xd08b,0xd08c,0xd08d,0xd08e,0xd08f,
+ 0xd090,0xd091,0xd092,0xd093,0xd094,0xd095,0xd096,0xd097,
+ 0xd098,0xd099,0xd09a,0xd09b,0xd09c,0xd09d,0xd09e,0xd09f,
+ 0xd0a0,0xd0a1,0xd0a2,0xd0a3,0xd0a4,0xd0a5,0xd0a6,0xd0a7,
+ 0xd0a8,0xd0a9,0xd0aa,0xd0ab,0xd0ac,0xd0ad,0xd0ae,0xd0af,
+ 0xd0b0,0xd0b1,0xd0b2,0xd0b3,0xd0b4,0xd0b5,0xd0b6,0xd0b7,
+ 0xd0b8,0xd0b9,0xd0ba,0xd0bb,0xd0bc,0xd0bd,0xd0be,0xd0bf,
+ 0xd0c0,0xd0c1,0xd0c2,0xd0c3,0xd0c4,0xd0c5,0xd0c6,0xd0c7,
+ 0xd0c8,0xd0c9,0xd0ca,0xd0cb,0xd0cc,0xd0cd,0xd0ce,0xd0cf,
+ 0xd0d0,0xd0d1,0xd0d2,0xd0d3,0xd0d4,0xd0d5,0xd0d6,0xd0d7,
+ 0xd0d8,0xd0d9,0xd0da,0xd0db,0xd0dc,0xd0dd,0xd0de,0xd0df,
+ 0xd0e0,0xd0e1,0xd0e2,0xd0e3,0xd0e4,0xd0e5,0xd0e6,0xd0e7,
+ 0xd0e8,0xd0e9,0xd0ea,0xd0eb,0xd0ec,0xd0ed,0xd0ee,0xd0ef,
+ 0xd0f0,0xd0f1,0xd0f2,0xd0f3,0xd0f4,0xd0f5,0xd0f6,0xd0f7,
+ 0xd0f8,0xd0f9,0xd0fa,0xd0fb,0xd0fc,0xd0fd,0xd0fe,0xd0ff,
+ 0xd100,0xd101,0xd102,0xd103,0xd104,0xd105,0xd106,0xd107,
+ 0xd108,0xd109,0xd10a,0xd10b,0xd10c,0xd10d,0xd10e,0xd10f,
+ 0xd110,0xd111,0xd112,0xd113,0xd114,0xd115,0xd116,0xd117,
+ 0xd118,0xd119,0xd11a,0xd11b,0xd11c,0xd11d,0xd11e,0xd11f,
+ 0xd120,0xd121,0xd122,0xd123,0xd124,0xd125,0xd126,0xd127,
+ 0xd128,0xd129,0xd12a,0xd12b,0xd12c,0xd12d,0xd12e,0xd12f,
+ 0xd130,0xd131,0xd132,0xd133,0xd134,0xd135,0xd136,0xd137,
+ 0xd138,0xd139,0xd13a,0xd13b,0xd13c,0xd13d,0xd13e,0xd13f,
+ 0xd140,0xd141,0xd142,0xd143,0xd144,0xd145,0xd146,0xd147,
+ 0xd148,0xd149,0xd14a,0xd14b,0xd14c,0xd14d,0xd14e,0xd14f,
+ 0xd150,0xd151,0xd152,0xd153,0xd154,0xd155,0xd156,0xd157,
+ 0xd158,0xd159,0xd15a,0xd15b,0xd15c,0xd15d,0xd15e,0xd15f,
+ 0xd160,0xd161,0xd162,0xd163,0xd164,0xd165,0xd166,0xd167,
+ 0xd168,0xd169,0xd16a,0xd16b,0xd16c,0xd16d,0xd16e,0xd16f,
+ 0xd170,0xd171,0xd172,0xd173,0xd174,0xd175,0xd176,0xd177,
+ 0xd178,0xd179,0xd17a,0xd17b,0xd17c,0xd17d,0xd17e,0xd17f,
+ 0xd180,0xd181,0xd182,0xd183,0xd184,0xd185,0xd186,0xd187,
+ 0xd188,0xd189,0xd18a,0xd18b,0xd18c,0xd18d,0xd18e,0xd18f,
+ 0xd190,0xd191,0xd192,0xd193,0xd194,0xd195,0xd196,0xd197,
+ 0xd198,0xd199,0xd19a,0xd19b,0xd19c,0xd19d,0xd19e,0xd19f,
+ 0xd1a0,0xd1a1,0xd1a2,0xd1a3,0xd1a4,0xd1a5,0xd1a6,0xd1a7,
+ 0xd1a8,0xd1a9,0xd1aa,0xd1ab,0xd1ac,0xd1ad,0xd1ae,0xd1af,
+ 0xd1b0,0xd1b1,0xd1b2,0xd1b3,0xd1b4,0xd1b5,0xd1b6,0xd1b7,
+ 0xd1b8,0xd1b9,0xd1ba,0xd1bb,0xd1bc,0xd1bd,0xd1be,0xd1bf,
+ 0xd1c0,0xd1c1,0xd1c2,0xd1c3,0xd1c4,0xd1c5,0xd1c6,0xd1c7,
+ 0xd1c8,0xd1c9,0xd1ca,0xd1cb,0xd1cc,0xd1cd,0xd1ce,0xd1cf,
+ 0xd1d0,0xd1d1,0xd1d2,0xd1d3,0xd1d4,0xd1d5,0xd1d6,0xd1d7,
+ 0xd1d8,0xd1d9,0xd1da,0xd1db,0xd1dc,0xd1dd,0xd1de,0xd1df,
+ 0xd1e0,0xd1e1,0xd1e2,0xd1e3,0xd1e4,0xd1e5,0xd1e6,0xd1e7,
+ 0xd1e8,0xd1e9,0xd1ea,0xd1eb,0xd1ec,0xd1ed,0xd1ee,0xd1ef,
+ 0xd1f0,0xd1f1,0xd1f2,0xd1f3,0xd1f4,0xd1f5,0xd1f6,0xd1f7,
+ 0xd1f8,0xd1f9,0xd1fa,0xd1fb,0xd1fc,0xd1fd,0xd1fe,0xd1ff,
+ 0xd200,0xd201,0xd202,0xd203,0xd204,0xd205,0xd206,0xd207,
+ 0xd208,0xd209,0xd20a,0xd20b,0xd20c,0xd20d,0xd20e,0xd20f,
+ 0xd210,0xd211,0xd212,0xd213,0xd214,0xd215,0xd216,0xd217,
+ 0xd218,0xd219,0xd21a,0xd21b,0xd21c,0xd21d,0xd21e,0xd21f,
+ 0xd220,0xd221,0xd222,0xd223,0xd224,0xd225,0xd226,0xd227,
+ 0xd228,0xd229,0xd22a,0xd22b,0xd22c,0xd22d,0xd22e,0xd22f,
+ 0xd230,0xd231,0xd232,0xd233,0xd234,0xd235,0xd236,0xd237,
+ 0xd238,0xd239,0xd23a,0xd23b,0xd23c,0xd23d,0xd23e,0xd23f,
+ 0xd240,0xd241,0xd242,0xd243,0xd244,0xd245,0xd246,0xd247,
+ 0xd248,0xd249,0xd24a,0xd24b,0xd24c,0xd24d,0xd24e,0xd24f,
+ 0xd250,0xd251,0xd252,0xd253,0xd254,0xd255,0xd256,0xd257,
+ 0xd258,0xd259,0xd25a,0xd25b,0xd25c,0xd25d,0xd25e,0xd25f,
+ 0xd260,0xd261,0xd262,0xd263,0xd264,0xd265,0xd266,0xd267,
+ 0xd268,0xd269,0xd26a,0xd26b,0xd26c,0xd26d,0xd26e,0xd26f,
+ 0xd270,0xd271,0xd272,0xd273,0xd274,0xd275,0xd276,0xd277,
+ 0xd278,0xd279,0xd27a,0xd27b,0xd27c,0xd27d,0xd27e,0xd27f,
+ 0xd280,0xd281,0xd282,0xd283,0xd284,0xd285,0xd286,0xd287,
+ 0xd288,0xd289,0xd28a,0xd28b,0xd28c,0xd28d,0xd28e,0xd28f,
+ 0xd290,0xd291,0xd292,0xd293,0xd294,0xd295,0xd296,0xd297,
+ 0xd298,0xd299,0xd29a,0xd29b,0xd29c,0xd29d,0xd29e,0xd29f,
+ 0xd2a0,0xd2a1,0xd2a2,0xd2a3,0xd2a4,0xd2a5,0xd2a6,0xd2a7,
+ 0xd2a8,0xd2a9,0xd2aa,0xd2ab,0xd2ac,0xd2ad,0xd2ae,0xd2af,
+ 0xd2b0,0xd2b1,0xd2b2,0xd2b3,0xd2b4,0xd2b5,0xd2b6,0xd2b7,
+ 0xd2b8,0xd2b9,0xd2ba,0xd2bb,0xd2bc,0xd2bd,0xd2be,0xd2bf,
+ 0xd2c0,0xd2c1,0xd2c2,0xd2c3,0xd2c4,0xd2c5,0xd2c6,0xd2c7,
+ 0xd2c8,0xd2c9,0xd2ca,0xd2cb,0xd2cc,0xd2cd,0xd2ce,0xd2cf,
+ 0xd2d0,0xd2d1,0xd2d2,0xd2d3,0xd2d4,0xd2d5,0xd2d6,0xd2d7,
+ 0xd2d8,0xd2d9,0xd2da,0xd2db,0xd2dc,0xd2dd,0xd2de,0xd2df,
+ 0xd2e0,0xd2e1,0xd2e2,0xd2e3,0xd2e4,0xd2e5,0xd2e6,0xd2e7,
+ 0xd2e8,0xd2e9,0xd2ea,0xd2eb,0xd2ec,0xd2ed,0xd2ee,0xd2ef,
+ 0xd2f0,0xd2f1,0xd2f2,0xd2f3,0xd2f4,0xd2f5,0xd2f6,0xd2f7,
+ 0xd2f8,0xd2f9,0xd2fa,0xd2fb,0xd2fc,0xd2fd,0xd2fe,0xd2ff,
+ 0xd300,0xd301,0xd302,0xd303,0xd304,0xd305,0xd306,0xd307,
+ 0xd308,0xd309,0xd30a,0xd30b,0xd30c,0xd30d,0xd30e,0xd30f,
+ 0xd310,0xd311,0xd312,0xd313,0xd314,0xd315,0xd316,0xd317,
+ 0xd318,0xd319,0xd31a,0xd31b,0xd31c,0xd31d,0xd31e,0xd31f,
+ 0xd320,0xd321,0xd322,0xd323,0xd324,0xd325,0xd326,0xd327,
+ 0xd328,0xd329,0xd32a,0xd32b,0xd32c,0xd32d,0xd32e,0xd32f,
+ 0xd330,0xd331,0xd332,0xd333,0xd334,0xd335,0xd336,0xd337,
+ 0xd338,0xd339,0xd33a,0xd33b,0xd33c,0xd33d,0xd33e,0xd33f,
+ 0xd340,0xd341,0xd342,0xd343,0xd344,0xd345,0xd346,0xd347,
+ 0xd348,0xd349,0xd34a,0xd34b,0xd34c,0xd34d,0xd34e,0xd34f,
+ 0xd350,0xd351,0xd352,0xd353,0xd354,0xd355,0xd356,0xd357,
+ 0xd358,0xd359,0xd35a,0xd35b,0xd35c,0xd35d,0xd35e,0xd35f,
+ 0xd360,0xd361,0xd362,0xd363,0xd364,0xd365,0xd366,0xd367,
+ 0xd368,0xd369,0xd36a,0xd36b,0xd36c,0xd36d,0xd36e,0xd36f,
+ 0xd370,0xd371,0xd372,0xd373,0xd374,0xd375,0xd376,0xd377,
+ 0xd378,0xd379,0xd37a,0xd37b,0xd37c,0xd37d,0xd37e,0xd37f,
+ 0xd380,0xd381,0xd382,0xd383,0xd384,0xd385,0xd386,0xd387,
+ 0xd388,0xd389,0xd38a,0xd38b,0xd38c,0xd38d,0xd38e,0xd38f,
+ 0xd390,0xd391,0xd392,0xd393,0xd394,0xd395,0xd396,0xd397,
+ 0xd398,0xd399,0xd39a,0xd39b,0xd39c,0xd39d,0xd39e,0xd39f,
+ 0xd3a0,0xd3a1,0xd3a2,0xd3a3,0xd3a4,0xd3a5,0xd3a6,0xd3a7,
+ 0xd3a8,0xd3a9,0xd3aa,0xd3ab,0xd3ac,0xd3ad,0xd3ae,0xd3af,
+ 0xd3b0,0xd3b1,0xd3b2,0xd3b3,0xd3b4,0xd3b5,0xd3b6,0xd3b7,
+ 0xd3b8,0xd3b9,0xd3ba,0xd3bb,0xd3bc,0xd3bd,0xd3be,0xd3bf,
+ 0xd3c0,0xd3c1,0xd3c2,0xd3c3,0xd3c4,0xd3c5,0xd3c6,0xd3c7,
+ 0xd3c8,0xd3c9,0xd3ca,0xd3cb,0xd3cc,0xd3cd,0xd3ce,0xd3cf,
+ 0xd3d0,0xd3d1,0xd3d2,0xd3d3,0xd3d4,0xd3d5,0xd3d6,0xd3d7,
+ 0xd3d8,0xd3d9,0xd3da,0xd3db,0xd3dc,0xd3dd,0xd3de,0xd3df,
+ 0xd3e0,0xd3e1,0xd3e2,0xd3e3,0xd3e4,0xd3e5,0xd3e6,0xd3e7,
+ 0xd3e8,0xd3e9,0xd3ea,0xd3eb,0xd3ec,0xd3ed,0xd3ee,0xd3ef,
+ 0xd3f0,0xd3f1,0xd3f2,0xd3f3,0xd3f4,0xd3f5,0xd3f6,0xd3f7,
+ 0xd3f8,0xd3f9,0xd3fa,0xd3fb,0xd3fc,0xd3fd,0xd3fe,0xd3ff,
+ 0xd400,0xd401,0xd402,0xd403,0xd404,0xd405,0xd406,0xd407,
+ 0xd408,0xd409,0xd40a,0xd40b,0xd40c,0xd40d,0xd40e,0xd40f,
+ 0xd410,0xd411,0xd412,0xd413,0xd414,0xd415,0xd416,0xd417,
+ 0xd418,0xd419,0xd41a,0xd41b,0xd41c,0xd41d,0xd41e,0xd41f,
+ 0xd420,0xd421,0xd422,0xd423,0xd424,0xd425,0xd426,0xd427,
+ 0xd428,0xd429,0xd42a,0xd42b,0xd42c,0xd42d,0xd42e,0xd42f,
+ 0xd430,0xd431,0xd432,0xd433,0xd434,0xd435,0xd436,0xd437,
+ 0xd438,0xd439,0xd43a,0xd43b,0xd43c,0xd43d,0xd43e,0xd43f,
+ 0xd440,0xd441,0xd442,0xd443,0xd444,0xd445,0xd446,0xd447,
+ 0xd448,0xd449,0xd44a,0xd44b,0xd44c,0xd44d,0xd44e,0xd44f,
+ 0xd450,0xd451,0xd452,0xd453,0xd454,0xd455,0xd456,0xd457,
+ 0xd458,0xd459,0xd45a,0xd45b,0xd45c,0xd45d,0xd45e,0xd45f,
+ 0xd460,0xd461,0xd462,0xd463,0xd464,0xd465,0xd466,0xd467,
+ 0xd468,0xd469,0xd46a,0xd46b,0xd46c,0xd46d,0xd46e,0xd46f,
+ 0xd470,0xd471,0xd472,0xd473,0xd474,0xd475,0xd476,0xd477,
+ 0xd478,0xd479,0xd47a,0xd47b,0xd47c,0xd47d,0xd47e,0xd47f,
+ 0xd480,0xd481,0xd482,0xd483,0xd484,0xd485,0xd486,0xd487,
+ 0xd488,0xd489,0xd48a,0xd48b,0xd48c,0xd48d,0xd48e,0xd48f,
+ 0xd490,0xd491,0xd492,0xd493,0xd494,0xd495,0xd496,0xd497,
+ 0xd498,0xd499,0xd49a,0xd49b,0xd49c,0xd49d,0xd49e,0xd49f,
+ 0xd4a0,0xd4a1,0xd4a2,0xd4a3,0xd4a4,0xd4a5,0xd4a6,0xd4a7,
+ 0xd4a8,0xd4a9,0xd4aa,0xd4ab,0xd4ac,0xd4ad,0xd4ae,0xd4af,
+ 0xd4b0,0xd4b1,0xd4b2,0xd4b3,0xd4b4,0xd4b5,0xd4b6,0xd4b7,
+ 0xd4b8,0xd4b9,0xd4ba,0xd4bb,0xd4bc,0xd4bd,0xd4be,0xd4bf,
+ 0xd4c0,0xd4c1,0xd4c2,0xd4c3,0xd4c4,0xd4c5,0xd4c6,0xd4c7,
+ 0xd4c8,0xd4c9,0xd4ca,0xd4cb,0xd4cc,0xd4cd,0xd4ce,0xd4cf,
+ 0xd4d0,0xd4d1,0xd4d2,0xd4d3,0xd4d4,0xd4d5,0xd4d6,0xd4d7,
+ 0xd4d8,0xd4d9,0xd4da,0xd4db,0xd4dc,0xd4dd,0xd4de,0xd4df,
+ 0xd4e0,0xd4e1,0xd4e2,0xd4e3,0xd4e4,0xd4e5,0xd4e6,0xd4e7,
+ 0xd4e8,0xd4e9,0xd4ea,0xd4eb,0xd4ec,0xd4ed,0xd4ee,0xd4ef,
+ 0xd4f0,0xd4f1,0xd4f2,0xd4f3,0xd4f4,0xd4f5,0xd4f6,0xd4f7,
+ 0xd4f8,0xd4f9,0xd4fa,0xd4fb,0xd4fc,0xd4fd,0xd4fe,0xd4ff,
+ 0xd500,0xd501,0xd502,0xd503,0xd504,0xd505,0xd506,0xd507,
+ 0xd508,0xd509,0xd50a,0xd50b,0xd50c,0xd50d,0xd50e,0xd50f,
+ 0xd510,0xd511,0xd512,0xd513,0xd514,0xd515,0xd516,0xd517,
+ 0xd518,0xd519,0xd51a,0xd51b,0xd51c,0xd51d,0xd51e,0xd51f,
+ 0xd520,0xd521,0xd522,0xd523,0xd524,0xd525,0xd526,0xd527,
+ 0xd528,0xd529,0xd52a,0xd52b,0xd52c,0xd52d,0xd52e,0xd52f,
+ 0xd530,0xd531,0xd532,0xd533,0xd534,0xd535,0xd536,0xd537,
+ 0xd538,0xd539,0xd53a,0xd53b,0xd53c,0xd53d,0xd53e,0xd53f,
+ 0xd540,0xd541,0xd542,0xd543,0xd544,0xd545,0xd546,0xd547,
+ 0xd548,0xd549,0xd54a,0xd54b,0xd54c,0xd54d,0xd54e,0xd54f,
+ 0xd550,0xd551,0xd552,0xd553,0xd554,0xd555,0xd556,0xd557,
+ 0xd558,0xd559,0xd55a,0xd55b,0xd55c,0xd55d,0xd55e,0xd55f,
+ 0xd560,0xd561,0xd562,0xd563,0xd564,0xd565,0xd566,0xd567,
+ 0xd568,0xd569,0xd56a,0xd56b,0xd56c,0xd56d,0xd56e,0xd56f,
+ 0xd570,0xd571,0xd572,0xd573,0xd574,0xd575,0xd576,0xd577,
+ 0xd578,0xd579,0xd57a,0xd57b,0xd57c,0xd57d,0xd57e,0xd57f,
+ 0xd580,0xd581,0xd582,0xd583,0xd584,0xd585,0xd586,0xd587,
+ 0xd588,0xd589,0xd58a,0xd58b,0xd58c,0xd58d,0xd58e,0xd58f,
+ 0xd590,0xd591,0xd592,0xd593,0xd594,0xd595,0xd596,0xd597,
+ 0xd598,0xd599,0xd59a,0xd59b,0xd59c,0xd59d,0xd59e,0xd59f,
+ 0xd5a0,0xd5a1,0xd5a2,0xd5a3,0xd5a4,0xd5a5,0xd5a6,0xd5a7,
+ 0xd5a8,0xd5a9,0xd5aa,0xd5ab,0xd5ac,0xd5ad,0xd5ae,0xd5af,
+ 0xd5b0,0xd5b1,0xd5b2,0xd5b3,0xd5b4,0xd5b5,0xd5b6,0xd5b7,
+ 0xd5b8,0xd5b9,0xd5ba,0xd5bb,0xd5bc,0xd5bd,0xd5be,0xd5bf,
+ 0xd5c0,0xd5c1,0xd5c2,0xd5c3,0xd5c4,0xd5c5,0xd5c6,0xd5c7,
+ 0xd5c8,0xd5c9,0xd5ca,0xd5cb,0xd5cc,0xd5cd,0xd5ce,0xd5cf,
+ 0xd5d0,0xd5d1,0xd5d2,0xd5d3,0xd5d4,0xd5d5,0xd5d6,0xd5d7,
+ 0xd5d8,0xd5d9,0xd5da,0xd5db,0xd5dc,0xd5dd,0xd5de,0xd5df,
+ 0xd5e0,0xd5e1,0xd5e2,0xd5e3,0xd5e4,0xd5e5,0xd5e6,0xd5e7,
+ 0xd5e8,0xd5e9,0xd5ea,0xd5eb,0xd5ec,0xd5ed,0xd5ee,0xd5ef,
+ 0xd5f0,0xd5f1,0xd5f2,0xd5f3,0xd5f4,0xd5f5,0xd5f6,0xd5f7,
+ 0xd5f8,0xd5f9,0xd5fa,0xd5fb,0xd5fc,0xd5fd,0xd5fe,0xd5ff,
+ 0xd600,0xd601,0xd602,0xd603,0xd604,0xd605,0xd606,0xd607,
+ 0xd608,0xd609,0xd60a,0xd60b,0xd60c,0xd60d,0xd60e,0xd60f,
+ 0xd610,0xd611,0xd612,0xd613,0xd614,0xd615,0xd616,0xd617,
+ 0xd618,0xd619,0xd61a,0xd61b,0xd61c,0xd61d,0xd61e,0xd61f,
+ 0xd620,0xd621,0xd622,0xd623,0xd624,0xd625,0xd626,0xd627,
+ 0xd628,0xd629,0xd62a,0xd62b,0xd62c,0xd62d,0xd62e,0xd62f,
+ 0xd630,0xd631,0xd632,0xd633,0xd634,0xd635,0xd636,0xd637,
+ 0xd638,0xd639,0xd63a,0xd63b,0xd63c,0xd63d,0xd63e,0xd63f,
+ 0xd640,0xd641,0xd642,0xd643,0xd644,0xd645,0xd646,0xd647,
+ 0xd648,0xd649,0xd64a,0xd64b,0xd64c,0xd64d,0xd64e,0xd64f,
+ 0xd650,0xd651,0xd652,0xd653,0xd654,0xd655,0xd656,0xd657,
+ 0xd658,0xd659,0xd65a,0xd65b,0xd65c,0xd65d,0xd65e,0xd65f,
+ 0xd660,0xd661,0xd662,0xd663,0xd664,0xd665,0xd666,0xd667,
+ 0xd668,0xd669,0xd66a,0xd66b,0xd66c,0xd66d,0xd66e,0xd66f,
+ 0xd670,0xd671,0xd672,0xd673,0xd674,0xd675,0xd676,0xd677,
+ 0xd678,0xd679,0xd67a,0xd67b,0xd67c,0xd67d,0xd67e,0xd67f,
+ 0xd680,0xd681,0xd682,0xd683,0xd684,0xd685,0xd686,0xd687,
+ 0xd688,0xd689,0xd68a,0xd68b,0xd68c,0xd68d,0xd68e,0xd68f,
+ 0xd690,0xd691,0xd692,0xd693,0xd694,0xd695,0xd696,0xd697,
+ 0xd698,0xd699,0xd69a,0xd69b,0xd69c,0xd69d,0xd69e,0xd69f,
+ 0xd6a0,0xd6a1,0xd6a2,0xd6a3,0xd6a4,0xd6a5,0xd6a6,0xd6a7,
+ 0xd6a8,0xd6a9,0xd6aa,0xd6ab,0xd6ac,0xd6ad,0xd6ae,0xd6af,
+ 0xd6b0,0xd6b1,0xd6b2,0xd6b3,0xd6b4,0xd6b5,0xd6b6,0xd6b7,
+ 0xd6b8,0xd6b9,0xd6ba,0xd6bb,0xd6bc,0xd6bd,0xd6be,0xd6bf,
+ 0xd6c0,0xd6c1,0xd6c2,0xd6c3,0xd6c4,0xd6c5,0xd6c6,0xd6c7,
+ 0xd6c8,0xd6c9,0xd6ca,0xd6cb,0xd6cc,0xd6cd,0xd6ce,0xd6cf,
+ 0xd6d0,0xd6d1,0xd6d2,0xd6d3,0xd6d4,0xd6d5,0xd6d6,0xd6d7,
+ 0xd6d8,0xd6d9,0xd6da,0xd6db,0xd6dc,0xd6dd,0xd6de,0xd6df,
+ 0xd6e0,0xd6e1,0xd6e2,0xd6e3,0xd6e4,0xd6e5,0xd6e6,0xd6e7,
+ 0xd6e8,0xd6e9,0xd6ea,0xd6eb,0xd6ec,0xd6ed,0xd6ee,0xd6ef,
+ 0xd6f0,0xd6f1,0xd6f2,0xd6f3,0xd6f4,0xd6f5,0xd6f6,0xd6f7,
+ 0xd6f8,0xd6f9,0xd6fa,0xd6fb,0xd6fc,0xd6fd,0xd6fe,0xd6ff,
+ 0xd700,0xd701,0xd702,0xd703,0xd704,0xd705,0xd706,0xd707,
+ 0xd708,0xd709,0xd70a,0xd70b,0xd70c,0xd70d,0xd70e,0xd70f,
+ 0xd710,0xd711,0xd712,0xd713,0xd714,0xd715,0xd716,0xd717,
+ 0xd718,0xd719,0xd71a,0xd71b,0xd71c,0xd71d,0xd71e,0xd71f,
+ 0xd720,0xd721,0xd722,0xd723,0xd724,0xd725,0xd726,0xd727,
+ 0xd728,0xd729,0xd72a,0xd72b,0xd72c,0xd72d,0xd72e,0xd72f,
+ 0xd730,0xd731,0xd732,0xd733,0xd734,0xd735,0xd736,0xd737,
+ 0xd738,0xd739,0xd73a,0xd73b,0xd73c,0xd73d,0xd73e,0xd73f,
+ 0xd740,0xd741,0xd742,0xd743,0xd744,0xd745,0xd746,0xd747,
+ 0xd748,0xd749,0xd74a,0xd74b,0xd74c,0xd74d,0xd74e,0xd74f,
+ 0xd750,0xd751,0xd752,0xd753,0xd754,0xd755,0xd756,0xd757,
+ 0xd758,0xd759,0xd75a,0xd75b,0xd75c,0xd75d,0xd75e,0xd75f,
+ 0xd760,0xd761,0xd762,0xd763,0xd764,0xd765,0xd766,0xd767,
+ 0xd768,0xd769,0xd76a,0xd76b,0xd76c,0xd76d,0xd76e,0xd76f,
+ 0xd770,0xd771,0xd772,0xd773,0xd774,0xd775,0xd776,0xd777,
+ 0xd778,0xd779,0xd77a,0xd77b,0xd77c,0xd77d,0xd77e,0xd77f,
+ 0xd780,0xd781,0xd782,0xd783,0xd784,0xd785,0xd786,0xd787,
+ 0xd788,0xd789,0xd78a,0xd78b,0xd78c,0xd78d,0xd78e,0xd78f,
+ 0xd790,0xd791,0xd792,0xd793,0xd794,0xd795,0xd796,0xd797,
+ 0xd798,0xd799,0xd79a,0xd79b,0xd79c,0xd79d,0xd79e,0xd79f,
+ 0xd7a0,0xd7a1,0xd7a2,0xd7a3,0xd7a4,0xd7a5,0xd7a6,0xd7a7,
+ 0xd7a8,0xd7a9,0xd7aa,0xd7ab,0xd7ac,0xd7ad,0xd7ae,0xd7af,
+ 0xd7b0,0xd7b1,0xd7b2,0xd7b3,0xd7b4,0xd7b5,0xd7b6,0xd7b7,
+ 0xd7b8,0xd7b9,0xd7ba,0xd7bb,0xd7bc,0xd7bd,0xd7be,0xd7bf,
+ 0xd7c0,0xd7c1,0xd7c2,0xd7c3,0xd7c4,0xd7c5,0xd7c6,0xd7c7,
+ 0xd7c8,0xd7c9,0xd7ca,0xd7cb,0xd7cc,0xd7cd,0xd7ce,0xd7cf,
+ 0xd7d0,0xd7d1,0xd7d2,0xd7d3,0xd7d4,0xd7d5,0xd7d6,0xd7d7,
+ 0xd7d8,0xd7d9,0xd7da,0xd7db,0xd7dc,0xd7dd,0xd7de,0xd7df,
+ 0xd7e0,0xd7e1,0xd7e2,0xd7e3,0xd7e4,0xd7e5,0xd7e6,0xd7e7,
+ 0xd7e8,0xd7e9,0xd7ea,0xd7eb,0xd7ec,0xd7ed,0xd7ee,0xd7ef,
+ 0xd7f0,0xd7f1,0xd7f2,0xd7f3,0xd7f4,0xd7f5,0xd7f6,0xd7f7,
+ 0xd7f8,0xd7f9,0xd7fa,0xd7fb,0xd7fc,0xd7fd,0xd7fe,0xd7ff,
+ 0xd800,0xd801,0xd802,0xd803,0xd804,0xd805,0xd806,0xd807,
+ 0xd808,0xd809,0xd80a,0xd80b,0xd80c,0xd80d,0xd80e,0xd80f,
+ 0xd810,0xd811,0xd812,0xd813,0xd814,0xd815,0xd816,0xd817,
+ 0xd818,0xd819,0xd81a,0xd81b,0xd81c,0xd81d,0xd81e,0xd81f,
+ 0xd820,0xd821,0xd822,0xd823,0xd824,0xd825,0xd826,0xd827,
+ 0xd828,0xd829,0xd82a,0xd82b,0xd82c,0xd82d,0xd82e,0xd82f,
+ 0xd830,0xd831,0xd832,0xd833,0xd834,0xd835,0xd836,0xd837,
+ 0xd838,0xd839,0xd83a,0xd83b,0xd83c,0xd83d,0xd83e,0xd83f,
+ 0xd840,0xd841,0xd842,0xd843,0xd844,0xd845,0xd846,0xd847,
+ 0xd848,0xd849,0xd84a,0xd84b,0xd84c,0xd84d,0xd84e,0xd84f,
+ 0xd850,0xd851,0xd852,0xd853,0xd854,0xd855,0xd856,0xd857,
+ 0xd858,0xd859,0xd85a,0xd85b,0xd85c,0xd85d,0xd85e,0xd85f,
+ 0xd860,0xd861,0xd862,0xd863,0xd864,0xd865,0xd866,0xd867,
+ 0xd868,0xd869,0xd86a,0xd86b,0xd86c,0xd86d,0xd86e,0xd86f,
+ 0xd870,0xd871,0xd872,0xd873,0xd874,0xd875,0xd876,0xd877,
+ 0xd878,0xd879,0xd87a,0xd87b,0xd87c,0xd87d,0xd87e,0xd87f,
+ 0xd880,0xd881,0xd882,0xd883,0xd884,0xd885,0xd886,0xd887,
+ 0xd888,0xd889,0xd88a,0xd88b,0xd88c,0xd88d,0xd88e,0xd88f,
+ 0xd890,0xd891,0xd892,0xd893,0xd894,0xd895,0xd896,0xd897,
+ 0xd898,0xd899,0xd89a,0xd89b,0xd89c,0xd89d,0xd89e,0xd89f,
+ 0xd8a0,0xd8a1,0xd8a2,0xd8a3,0xd8a4,0xd8a5,0xd8a6,0xd8a7,
+ 0xd8a8,0xd8a9,0xd8aa,0xd8ab,0xd8ac,0xd8ad,0xd8ae,0xd8af,
+ 0xd8b0,0xd8b1,0xd8b2,0xd8b3,0xd8b4,0xd8b5,0xd8b6,0xd8b7,
+ 0xd8b8,0xd8b9,0xd8ba,0xd8bb,0xd8bc,0xd8bd,0xd8be,0xd8bf,
+ 0xd8c0,0xd8c1,0xd8c2,0xd8c3,0xd8c4,0xd8c5,0xd8c6,0xd8c7,
+ 0xd8c8,0xd8c9,0xd8ca,0xd8cb,0xd8cc,0xd8cd,0xd8ce,0xd8cf,
+ 0xd8d0,0xd8d1,0xd8d2,0xd8d3,0xd8d4,0xd8d5,0xd8d6,0xd8d7,
+ 0xd8d8,0xd8d9,0xd8da,0xd8db,0xd8dc,0xd8dd,0xd8de,0xd8df,
+ 0xd8e0,0xd8e1,0xd8e2,0xd8e3,0xd8e4,0xd8e5,0xd8e6,0xd8e7,
+ 0xd8e8,0xd8e9,0xd8ea,0xd8eb,0xd8ec,0xd8ed,0xd8ee,0xd8ef,
+ 0xd8f0,0xd8f1,0xd8f2,0xd8f3,0xd8f4,0xd8f5,0xd8f6,0xd8f7,
+ 0xd8f8,0xd8f9,0xd8fa,0xd8fb,0xd8fc,0xd8fd,0xd8fe,0xd8ff,
+ 0xd900,0xd901,0xd902,0xd903,0xd904,0xd905,0xd906,0xd907,
+ 0xd908,0xd909,0xd90a,0xd90b,0xd90c,0xd90d,0xd90e,0xd90f,
+ 0xd910,0xd911,0xd912,0xd913,0xd914,0xd915,0xd916,0xd917,
+ 0xd918,0xd919,0xd91a,0xd91b,0xd91c,0xd91d,0xd91e,0xd91f,
+ 0xd920,0xd921,0xd922,0xd923,0xd924,0xd925,0xd926,0xd927,
+ 0xd928,0xd929,0xd92a,0xd92b,0xd92c,0xd92d,0xd92e,0xd92f,
+ 0xd930,0xd931,0xd932,0xd933,0xd934,0xd935,0xd936,0xd937,
+ 0xd938,0xd939,0xd93a,0xd93b,0xd93c,0xd93d,0xd93e,0xd93f,
+ 0xd940,0xd941,0xd942,0xd943,0xd944,0xd945,0xd946,0xd947,
+ 0xd948,0xd949,0xd94a,0xd94b,0xd94c,0xd94d,0xd94e,0xd94f,
+ 0xd950,0xd951,0xd952,0xd953,0xd954,0xd955,0xd956,0xd957,
+ 0xd958,0xd959,0xd95a,0xd95b,0xd95c,0xd95d,0xd95e,0xd95f,
+ 0xd960,0xd961,0xd962,0xd963,0xd964,0xd965,0xd966,0xd967,
+ 0xd968,0xd969,0xd96a,0xd96b,0xd96c,0xd96d,0xd96e,0xd96f,
+ 0xd970,0xd971,0xd972,0xd973,0xd974,0xd975,0xd976,0xd977,
+ 0xd978,0xd979,0xd97a,0xd97b,0xd97c,0xd97d,0xd97e,0xd97f,
+ 0xd980,0xd981,0xd982,0xd983,0xd984,0xd985,0xd986,0xd987,
+ 0xd988,0xd989,0xd98a,0xd98b,0xd98c,0xd98d,0xd98e,0xd98f,
+ 0xd990,0xd991,0xd992,0xd993,0xd994,0xd995,0xd996,0xd997,
+ 0xd998,0xd999,0xd99a,0xd99b,0xd99c,0xd99d,0xd99e,0xd99f,
+ 0xd9a0,0xd9a1,0xd9a2,0xd9a3,0xd9a4,0xd9a5,0xd9a6,0xd9a7,
+ 0xd9a8,0xd9a9,0xd9aa,0xd9ab,0xd9ac,0xd9ad,0xd9ae,0xd9af,
+ 0xd9b0,0xd9b1,0xd9b2,0xd9b3,0xd9b4,0xd9b5,0xd9b6,0xd9b7,
+ 0xd9b8,0xd9b9,0xd9ba,0xd9bb,0xd9bc,0xd9bd,0xd9be,0xd9bf,
+ 0xd9c0,0xd9c1,0xd9c2,0xd9c3,0xd9c4,0xd9c5,0xd9c6,0xd9c7,
+ 0xd9c8,0xd9c9,0xd9ca,0xd9cb,0xd9cc,0xd9cd,0xd9ce,0xd9cf,
+ 0xd9d0,0xd9d1,0xd9d2,0xd9d3,0xd9d4,0xd9d5,0xd9d6,0xd9d7,
+ 0xd9d8,0xd9d9,0xd9da,0xd9db,0xd9dc,0xd9dd,0xd9de,0xd9df,
+ 0xd9e0,0xd9e1,0xd9e2,0xd9e3,0xd9e4,0xd9e5,0xd9e6,0xd9e7,
+ 0xd9e8,0xd9e9,0xd9ea,0xd9eb,0xd9ec,0xd9ed,0xd9ee,0xd9ef,
+ 0xd9f0,0xd9f1,0xd9f2,0xd9f3,0xd9f4,0xd9f5,0xd9f6,0xd9f7,
+ 0xd9f8,0xd9f9,0xd9fa,0xd9fb,0xd9fc,0xd9fd,0xd9fe,0xd9ff,
+ 0xda00,0xda01,0xda02,0xda03,0xda04,0xda05,0xda06,0xda07,
+ 0xda08,0xda09,0xda0a,0xda0b,0xda0c,0xda0d,0xda0e,0xda0f,
+ 0xda10,0xda11,0xda12,0xda13,0xda14,0xda15,0xda16,0xda17,
+ 0xda18,0xda19,0xda1a,0xda1b,0xda1c,0xda1d,0xda1e,0xda1f,
+ 0xda20,0xda21,0xda22,0xda23,0xda24,0xda25,0xda26,0xda27,
+ 0xda28,0xda29,0xda2a,0xda2b,0xda2c,0xda2d,0xda2e,0xda2f,
+ 0xda30,0xda31,0xda32,0xda33,0xda34,0xda35,0xda36,0xda37,
+ 0xda38,0xda39,0xda3a,0xda3b,0xda3c,0xda3d,0xda3e,0xda3f,
+ 0xda40,0xda41,0xda42,0xda43,0xda44,0xda45,0xda46,0xda47,
+ 0xda48,0xda49,0xda4a,0xda4b,0xda4c,0xda4d,0xda4e,0xda4f,
+ 0xda50,0xda51,0xda52,0xda53,0xda54,0xda55,0xda56,0xda57,
+ 0xda58,0xda59,0xda5a,0xda5b,0xda5c,0xda5d,0xda5e,0xda5f,
+ 0xda60,0xda61,0xda62,0xda63,0xda64,0xda65,0xda66,0xda67,
+ 0xda68,0xda69,0xda6a,0xda6b,0xda6c,0xda6d,0xda6e,0xda6f,
+ 0xda70,0xda71,0xda72,0xda73,0xda74,0xda75,0xda76,0xda77,
+ 0xda78,0xda79,0xda7a,0xda7b,0xda7c,0xda7d,0xda7e,0xda7f,
+ 0xda80,0xda81,0xda82,0xda83,0xda84,0xda85,0xda86,0xda87,
+ 0xda88,0xda89,0xda8a,0xda8b,0xda8c,0xda8d,0xda8e,0xda8f,
+ 0xda90,0xda91,0xda92,0xda93,0xda94,0xda95,0xda96,0xda97,
+ 0xda98,0xda99,0xda9a,0xda9b,0xda9c,0xda9d,0xda9e,0xda9f,
+ 0xdaa0,0xdaa1,0xdaa2,0xdaa3,0xdaa4,0xdaa5,0xdaa6,0xdaa7,
+ 0xdaa8,0xdaa9,0xdaaa,0xdaab,0xdaac,0xdaad,0xdaae,0xdaaf,
+ 0xdab0,0xdab1,0xdab2,0xdab3,0xdab4,0xdab5,0xdab6,0xdab7,
+ 0xdab8,0xdab9,0xdaba,0xdabb,0xdabc,0xdabd,0xdabe,0xdabf,
+ 0xdac0,0xdac1,0xdac2,0xdac3,0xdac4,0xdac5,0xdac6,0xdac7,
+ 0xdac8,0xdac9,0xdaca,0xdacb,0xdacc,0xdacd,0xdace,0xdacf,
+ 0xdad0,0xdad1,0xdad2,0xdad3,0xdad4,0xdad5,0xdad6,0xdad7,
+ 0xdad8,0xdad9,0xdada,0xdadb,0xdadc,0xdadd,0xdade,0xdadf,
+ 0xdae0,0xdae1,0xdae2,0xdae3,0xdae4,0xdae5,0xdae6,0xdae7,
+ 0xdae8,0xdae9,0xdaea,0xdaeb,0xdaec,0xdaed,0xdaee,0xdaef,
+ 0xdaf0,0xdaf1,0xdaf2,0xdaf3,0xdaf4,0xdaf5,0xdaf6,0xdaf7,
+ 0xdaf8,0xdaf9,0xdafa,0xdafb,0xdafc,0xdafd,0xdafe,0xdaff,
+ 0xdb00,0xdb01,0xdb02,0xdb03,0xdb04,0xdb05,0xdb06,0xdb07,
+ 0xdb08,0xdb09,0xdb0a,0xdb0b,0xdb0c,0xdb0d,0xdb0e,0xdb0f,
+ 0xdb10,0xdb11,0xdb12,0xdb13,0xdb14,0xdb15,0xdb16,0xdb17,
+ 0xdb18,0xdb19,0xdb1a,0xdb1b,0xdb1c,0xdb1d,0xdb1e,0xdb1f,
+ 0xdb20,0xdb21,0xdb22,0xdb23,0xdb24,0xdb25,0xdb26,0xdb27,
+ 0xdb28,0xdb29,0xdb2a,0xdb2b,0xdb2c,0xdb2d,0xdb2e,0xdb2f,
+ 0xdb30,0xdb31,0xdb32,0xdb33,0xdb34,0xdb35,0xdb36,0xdb37,
+ 0xdb38,0xdb39,0xdb3a,0xdb3b,0xdb3c,0xdb3d,0xdb3e,0xdb3f,
+ 0xdb40,0xdb41,0xdb42,0xdb43,0xdb44,0xdb45,0xdb46,0xdb47,
+ 0xdb48,0xdb49,0xdb4a,0xdb4b,0xdb4c,0xdb4d,0xdb4e,0xdb4f,
+ 0xdb50,0xdb51,0xdb52,0xdb53,0xdb54,0xdb55,0xdb56,0xdb57,
+ 0xdb58,0xdb59,0xdb5a,0xdb5b,0xdb5c,0xdb5d,0xdb5e,0xdb5f,
+ 0xdb60,0xdb61,0xdb62,0xdb63,0xdb64,0xdb65,0xdb66,0xdb67,
+ 0xdb68,0xdb69,0xdb6a,0xdb6b,0xdb6c,0xdb6d,0xdb6e,0xdb6f,
+ 0xdb70,0xdb71,0xdb72,0xdb73,0xdb74,0xdb75,0xdb76,0xdb77,
+ 0xdb78,0xdb79,0xdb7a,0xdb7b,0xdb7c,0xdb7d,0xdb7e,0xdb7f,
+ 0xdb80,0xdb81,0xdb82,0xdb83,0xdb84,0xdb85,0xdb86,0xdb87,
+ 0xdb88,0xdb89,0xdb8a,0xdb8b,0xdb8c,0xdb8d,0xdb8e,0xdb8f,
+ 0xdb90,0xdb91,0xdb92,0xdb93,0xdb94,0xdb95,0xdb96,0xdb97,
+ 0xdb98,0xdb99,0xdb9a,0xdb9b,0xdb9c,0xdb9d,0xdb9e,0xdb9f,
+ 0xdba0,0xdba1,0xdba2,0xdba3,0xdba4,0xdba5,0xdba6,0xdba7,
+ 0xdba8,0xdba9,0xdbaa,0xdbab,0xdbac,0xdbad,0xdbae,0xdbaf,
+ 0xdbb0,0xdbb1,0xdbb2,0xdbb3,0xdbb4,0xdbb5,0xdbb6,0xdbb7,
+ 0xdbb8,0xdbb9,0xdbba,0xdbbb,0xdbbc,0xdbbd,0xdbbe,0xdbbf,
+ 0xdbc0,0xdbc1,0xdbc2,0xdbc3,0xdbc4,0xdbc5,0xdbc6,0xdbc7,
+ 0xdbc8,0xdbc9,0xdbca,0xdbcb,0xdbcc,0xdbcd,0xdbce,0xdbcf,
+ 0xdbd0,0xdbd1,0xdbd2,0xdbd3,0xdbd4,0xdbd5,0xdbd6,0xdbd7,
+ 0xdbd8,0xdbd9,0xdbda,0xdbdb,0xdbdc,0xdbdd,0xdbde,0xdbdf,
+ 0xdbe0,0xdbe1,0xdbe2,0xdbe3,0xdbe4,0xdbe5,0xdbe6,0xdbe7,
+ 0xdbe8,0xdbe9,0xdbea,0xdbeb,0xdbec,0xdbed,0xdbee,0xdbef,
+ 0xdbf0,0xdbf1,0xdbf2,0xdbf3,0xdbf4,0xdbf5,0xdbf6,0xdbf7,
+ 0xdbf8,0xdbf9,0xdbfa,0xdbfb,0xdbfc,0xdbfd,0xdbfe,0xdbff,
+ 0xdc00,0xdc01,0xdc02,0xdc03,0xdc04,0xdc05,0xdc06,0xdc07,
+ 0xdc08,0xdc09,0xdc0a,0xdc0b,0xdc0c,0xdc0d,0xdc0e,0xdc0f,
+ 0xdc10,0xdc11,0xdc12,0xdc13,0xdc14,0xdc15,0xdc16,0xdc17,
+ 0xdc18,0xdc19,0xdc1a,0xdc1b,0xdc1c,0xdc1d,0xdc1e,0xdc1f,
+ 0xdc20,0xdc21,0xdc22,0xdc23,0xdc24,0xdc25,0xdc26,0xdc27,
+ 0xdc28,0xdc29,0xdc2a,0xdc2b,0xdc2c,0xdc2d,0xdc2e,0xdc2f,
+ 0xdc30,0xdc31,0xdc32,0xdc33,0xdc34,0xdc35,0xdc36,0xdc37,
+ 0xdc38,0xdc39,0xdc3a,0xdc3b,0xdc3c,0xdc3d,0xdc3e,0xdc3f,
+ 0xdc40,0xdc41,0xdc42,0xdc43,0xdc44,0xdc45,0xdc46,0xdc47,
+ 0xdc48,0xdc49,0xdc4a,0xdc4b,0xdc4c,0xdc4d,0xdc4e,0xdc4f,
+ 0xdc50,0xdc51,0xdc52,0xdc53,0xdc54,0xdc55,0xdc56,0xdc57,
+ 0xdc58,0xdc59,0xdc5a,0xdc5b,0xdc5c,0xdc5d,0xdc5e,0xdc5f,
+ 0xdc60,0xdc61,0xdc62,0xdc63,0xdc64,0xdc65,0xdc66,0xdc67,
+ 0xdc68,0xdc69,0xdc6a,0xdc6b,0xdc6c,0xdc6d,0xdc6e,0xdc6f,
+ 0xdc70,0xdc71,0xdc72,0xdc73,0xdc74,0xdc75,0xdc76,0xdc77,
+ 0xdc78,0xdc79,0xdc7a,0xdc7b,0xdc7c,0xdc7d,0xdc7e,0xdc7f,
+ 0xdc80,0xdc81,0xdc82,0xdc83,0xdc84,0xdc85,0xdc86,0xdc87,
+ 0xdc88,0xdc89,0xdc8a,0xdc8b,0xdc8c,0xdc8d,0xdc8e,0xdc8f,
+ 0xdc90,0xdc91,0xdc92,0xdc93,0xdc94,0xdc95,0xdc96,0xdc97,
+ 0xdc98,0xdc99,0xdc9a,0xdc9b,0xdc9c,0xdc9d,0xdc9e,0xdc9f,
+ 0xdca0,0xdca1,0xdca2,0xdca3,0xdca4,0xdca5,0xdca6,0xdca7,
+ 0xdca8,0xdca9,0xdcaa,0xdcab,0xdcac,0xdcad,0xdcae,0xdcaf,
+ 0xdcb0,0xdcb1,0xdcb2,0xdcb3,0xdcb4,0xdcb5,0xdcb6,0xdcb7,
+ 0xdcb8,0xdcb9,0xdcba,0xdcbb,0xdcbc,0xdcbd,0xdcbe,0xdcbf,
+ 0xdcc0,0xdcc1,0xdcc2,0xdcc3,0xdcc4,0xdcc5,0xdcc6,0xdcc7,
+ 0xdcc8,0xdcc9,0xdcca,0xdccb,0xdccc,0xdccd,0xdcce,0xdccf,
+ 0xdcd0,0xdcd1,0xdcd2,0xdcd3,0xdcd4,0xdcd5,0xdcd6,0xdcd7,
+ 0xdcd8,0xdcd9,0xdcda,0xdcdb,0xdcdc,0xdcdd,0xdcde,0xdcdf,
+ 0xdce0,0xdce1,0xdce2,0xdce3,0xdce4,0xdce5,0xdce6,0xdce7,
+ 0xdce8,0xdce9,0xdcea,0xdceb,0xdcec,0xdced,0xdcee,0xdcef,
+ 0xdcf0,0xdcf1,0xdcf2,0xdcf3,0xdcf4,0xdcf5,0xdcf6,0xdcf7,
+ 0xdcf8,0xdcf9,0xdcfa,0xdcfb,0xdcfc,0xdcfd,0xdcfe,0xdcff,
+ 0xdd00,0xdd01,0xdd02,0xdd03,0xdd04,0xdd05,0xdd06,0xdd07,
+ 0xdd08,0xdd09,0xdd0a,0xdd0b,0xdd0c,0xdd0d,0xdd0e,0xdd0f,
+ 0xdd10,0xdd11,0xdd12,0xdd13,0xdd14,0xdd15,0xdd16,0xdd17,
+ 0xdd18,0xdd19,0xdd1a,0xdd1b,0xdd1c,0xdd1d,0xdd1e,0xdd1f,
+ 0xdd20,0xdd21,0xdd22,0xdd23,0xdd24,0xdd25,0xdd26,0xdd27,
+ 0xdd28,0xdd29,0xdd2a,0xdd2b,0xdd2c,0xdd2d,0xdd2e,0xdd2f,
+ 0xdd30,0xdd31,0xdd32,0xdd33,0xdd34,0xdd35,0xdd36,0xdd37,
+ 0xdd38,0xdd39,0xdd3a,0xdd3b,0xdd3c,0xdd3d,0xdd3e,0xdd3f,
+ 0xdd40,0xdd41,0xdd42,0xdd43,0xdd44,0xdd45,0xdd46,0xdd47,
+ 0xdd48,0xdd49,0xdd4a,0xdd4b,0xdd4c,0xdd4d,0xdd4e,0xdd4f,
+ 0xdd50,0xdd51,0xdd52,0xdd53,0xdd54,0xdd55,0xdd56,0xdd57,
+ 0xdd58,0xdd59,0xdd5a,0xdd5b,0xdd5c,0xdd5d,0xdd5e,0xdd5f,
+ 0xdd60,0xdd61,0xdd62,0xdd63,0xdd64,0xdd65,0xdd66,0xdd67,
+ 0xdd68,0xdd69,0xdd6a,0xdd6b,0xdd6c,0xdd6d,0xdd6e,0xdd6f,
+ 0xdd70,0xdd71,0xdd72,0xdd73,0xdd74,0xdd75,0xdd76,0xdd77,
+ 0xdd78,0xdd79,0xdd7a,0xdd7b,0xdd7c,0xdd7d,0xdd7e,0xdd7f,
+ 0xdd80,0xdd81,0xdd82,0xdd83,0xdd84,0xdd85,0xdd86,0xdd87,
+ 0xdd88,0xdd89,0xdd8a,0xdd8b,0xdd8c,0xdd8d,0xdd8e,0xdd8f,
+ 0xdd90,0xdd91,0xdd92,0xdd93,0xdd94,0xdd95,0xdd96,0xdd97,
+ 0xdd98,0xdd99,0xdd9a,0xdd9b,0xdd9c,0xdd9d,0xdd9e,0xdd9f,
+ 0xdda0,0xdda1,0xdda2,0xdda3,0xdda4,0xdda5,0xdda6,0xdda7,
+ 0xdda8,0xdda9,0xddaa,0xddab,0xddac,0xddad,0xddae,0xddaf,
+ 0xddb0,0xddb1,0xddb2,0xddb3,0xddb4,0xddb5,0xddb6,0xddb7,
+ 0xddb8,0xddb9,0xddba,0xddbb,0xddbc,0xddbd,0xddbe,0xddbf,
+ 0xddc0,0xddc1,0xddc2,0xddc3,0xddc4,0xddc5,0xddc6,0xddc7,
+ 0xddc8,0xddc9,0xddca,0xddcb,0xddcc,0xddcd,0xddce,0xddcf,
+ 0xddd0,0xddd1,0xddd2,0xddd3,0xddd4,0xddd5,0xddd6,0xddd7,
+ 0xddd8,0xddd9,0xddda,0xdddb,0xdddc,0xdddd,0xddde,0xdddf,
+ 0xdde0,0xdde1,0xdde2,0xdde3,0xdde4,0xdde5,0xdde6,0xdde7,
+ 0xdde8,0xdde9,0xddea,0xddeb,0xddec,0xdded,0xddee,0xddef,
+ 0xddf0,0xddf1,0xddf2,0xddf3,0xddf4,0xddf5,0xddf6,0xddf7,
+ 0xddf8,0xddf9,0xddfa,0xddfb,0xddfc,0xddfd,0xddfe,0xddff,
+ 0xde00,0xde01,0xde02,0xde03,0xde04,0xde05,0xde06,0xde07,
+ 0xde08,0xde09,0xde0a,0xde0b,0xde0c,0xde0d,0xde0e,0xde0f,
+ 0xde10,0xde11,0xde12,0xde13,0xde14,0xde15,0xde16,0xde17,
+ 0xde18,0xde19,0xde1a,0xde1b,0xde1c,0xde1d,0xde1e,0xde1f,
+ 0xde20,0xde21,0xde22,0xde23,0xde24,0xde25,0xde26,0xde27,
+ 0xde28,0xde29,0xde2a,0xde2b,0xde2c,0xde2d,0xde2e,0xde2f,
+ 0xde30,0xde31,0xde32,0xde33,0xde34,0xde35,0xde36,0xde37,
+ 0xde38,0xde39,0xde3a,0xde3b,0xde3c,0xde3d,0xde3e,0xde3f,
+ 0xde40,0xde41,0xde42,0xde43,0xde44,0xde45,0xde46,0xde47,
+ 0xde48,0xde49,0xde4a,0xde4b,0xde4c,0xde4d,0xde4e,0xde4f,
+ 0xde50,0xde51,0xde52,0xde53,0xde54,0xde55,0xde56,0xde57,
+ 0xde58,0xde59,0xde5a,0xde5b,0xde5c,0xde5d,0xde5e,0xde5f,
+ 0xde60,0xde61,0xde62,0xde63,0xde64,0xde65,0xde66,0xde67,
+ 0xde68,0xde69,0xde6a,0xde6b,0xde6c,0xde6d,0xde6e,0xde6f,
+ 0xde70,0xde71,0xde72,0xde73,0xde74,0xde75,0xde76,0xde77,
+ 0xde78,0xde79,0xde7a,0xde7b,0xde7c,0xde7d,0xde7e,0xde7f,
+ 0xde80,0xde81,0xde82,0xde83,0xde84,0xde85,0xde86,0xde87,
+ 0xde88,0xde89,0xde8a,0xde8b,0xde8c,0xde8d,0xde8e,0xde8f,
+ 0xde90,0xde91,0xde92,0xde93,0xde94,0xde95,0xde96,0xde97,
+ 0xde98,0xde99,0xde9a,0xde9b,0xde9c,0xde9d,0xde9e,0xde9f,
+ 0xdea0,0xdea1,0xdea2,0xdea3,0xdea4,0xdea5,0xdea6,0xdea7,
+ 0xdea8,0xdea9,0xdeaa,0xdeab,0xdeac,0xdead,0xdeae,0xdeaf,
+ 0xdeb0,0xdeb1,0xdeb2,0xdeb3,0xdeb4,0xdeb5,0xdeb6,0xdeb7,
+ 0xdeb8,0xdeb9,0xdeba,0xdebb,0xdebc,0xdebd,0xdebe,0xdebf,
+ 0xdec0,0xdec1,0xdec2,0xdec3,0xdec4,0xdec5,0xdec6,0xdec7,
+ 0xdec8,0xdec9,0xdeca,0xdecb,0xdecc,0xdecd,0xdece,0xdecf,
+ 0xded0,0xded1,0xded2,0xded3,0xded4,0xded5,0xded6,0xded7,
+ 0xded8,0xded9,0xdeda,0xdedb,0xdedc,0xdedd,0xdede,0xdedf,
+ 0xdee0,0xdee1,0xdee2,0xdee3,0xdee4,0xdee5,0xdee6,0xdee7,
+ 0xdee8,0xdee9,0xdeea,0xdeeb,0xdeec,0xdeed,0xdeee,0xdeef,
+ 0xdef0,0xdef1,0xdef2,0xdef3,0xdef4,0xdef5,0xdef6,0xdef7,
+ 0xdef8,0xdef9,0xdefa,0xdefb,0xdefc,0xdefd,0xdefe,0xdeff,
+ 0xdf00,0xdf01,0xdf02,0xdf03,0xdf04,0xdf05,0xdf06,0xdf07,
+ 0xdf08,0xdf09,0xdf0a,0xdf0b,0xdf0c,0xdf0d,0xdf0e,0xdf0f,
+ 0xdf10,0xdf11,0xdf12,0xdf13,0xdf14,0xdf15,0xdf16,0xdf17,
+ 0xdf18,0xdf19,0xdf1a,0xdf1b,0xdf1c,0xdf1d,0xdf1e,0xdf1f,
+ 0xdf20,0xdf21,0xdf22,0xdf23,0xdf24,0xdf25,0xdf26,0xdf27,
+ 0xdf28,0xdf29,0xdf2a,0xdf2b,0xdf2c,0xdf2d,0xdf2e,0xdf2f,
+ 0xdf30,0xdf31,0xdf32,0xdf33,0xdf34,0xdf35,0xdf36,0xdf37,
+ 0xdf38,0xdf39,0xdf3a,0xdf3b,0xdf3c,0xdf3d,0xdf3e,0xdf3f,
+ 0xdf40,0xdf41,0xdf42,0xdf43,0xdf44,0xdf45,0xdf46,0xdf47,
+ 0xdf48,0xdf49,0xdf4a,0xdf4b,0xdf4c,0xdf4d,0xdf4e,0xdf4f,
+ 0xdf50,0xdf51,0xdf52,0xdf53,0xdf54,0xdf55,0xdf56,0xdf57,
+ 0xdf58,0xdf59,0xdf5a,0xdf5b,0xdf5c,0xdf5d,0xdf5e,0xdf5f,
+ 0xdf60,0xdf61,0xdf62,0xdf63,0xdf64,0xdf65,0xdf66,0xdf67,
+ 0xdf68,0xdf69,0xdf6a,0xdf6b,0xdf6c,0xdf6d,0xdf6e,0xdf6f,
+ 0xdf70,0xdf71,0xdf72,0xdf73,0xdf74,0xdf75,0xdf76,0xdf77,
+ 0xdf78,0xdf79,0xdf7a,0xdf7b,0xdf7c,0xdf7d,0xdf7e,0xdf7f,
+ 0xdf80,0xdf81,0xdf82,0xdf83,0xdf84,0xdf85,0xdf86,0xdf87,
+ 0xdf88,0xdf89,0xdf8a,0xdf8b,0xdf8c,0xdf8d,0xdf8e,0xdf8f,
+ 0xdf90,0xdf91,0xdf92,0xdf93,0xdf94,0xdf95,0xdf96,0xdf97,
+ 0xdf98,0xdf99,0xdf9a,0xdf9b,0xdf9c,0xdf9d,0xdf9e,0xdf9f,
+ 0xdfa0,0xdfa1,0xdfa2,0xdfa3,0xdfa4,0xdfa5,0xdfa6,0xdfa7,
+ 0xdfa8,0xdfa9,0xdfaa,0xdfab,0xdfac,0xdfad,0xdfae,0xdfaf,
+ 0xdfb0,0xdfb1,0xdfb2,0xdfb3,0xdfb4,0xdfb5,0xdfb6,0xdfb7,
+ 0xdfb8,0xdfb9,0xdfba,0xdfbb,0xdfbc,0xdfbd,0xdfbe,0xdfbf,
+ 0xdfc0,0xdfc1,0xdfc2,0xdfc3,0xdfc4,0xdfc5,0xdfc6,0xdfc7,
+ 0xdfc8,0xdfc9,0xdfca,0xdfcb,0xdfcc,0xdfcd,0xdfce,0xdfcf,
+ 0xdfd0,0xdfd1,0xdfd2,0xdfd3,0xdfd4,0xdfd5,0xdfd6,0xdfd7,
+ 0xdfd8,0xdfd9,0xdfda,0xdfdb,0xdfdc,0xdfdd,0xdfde,0xdfdf,
+ 0xdfe0,0xdfe1,0xdfe2,0xdfe3,0xdfe4,0xdfe5,0xdfe6,0xdfe7,
+ 0xdfe8,0xdfe9,0xdfea,0xdfeb,0xdfec,0xdfed,0xdfee,0xdfef,
+ 0xdff0,0xdff1,0xdff2,0xdff3,0xdff4,0xdff5,0xdff6,0xdff7,
+ 0xdff8,0xdff9,0xdffa,0xdffb,0xdffc,0xdffd,0xdffe,0xdfff,
+ 0xe000,0xe001,0xe002,0xe003,0xe004,0xe005,0xe006,0xe007,
+ 0xe008,0xe009,0xe00a,0xe00b,0xe00c,0xe00d,0xe00e,0xe00f,
+ 0xe010,0xe011,0xe012,0xe013,0xe014,0xe015,0xe016,0xe017,
+ 0xe018,0xe019,0xe01a,0xe01b,0xe01c,0xe01d,0xe01e,0xe01f,
+ 0xe020,0xe021,0xe022,0xe023,0xe024,0xe025,0xe026,0xe027,
+ 0xe028,0xe029,0xe02a,0xe02b,0xe02c,0xe02d,0xe02e,0xe02f,
+ 0xe030,0xe031,0xe032,0xe033,0xe034,0xe035,0xe036,0xe037,
+ 0xe038,0xe039,0xe03a,0xe03b,0xe03c,0xe03d,0xe03e,0xe03f,
+ 0xe040,0xe041,0xe042,0xe043,0xe044,0xe045,0xe046,0xe047,
+ 0xe048,0xe049,0xe04a,0xe04b,0xe04c,0xe04d,0xe04e,0xe04f,
+ 0xe050,0xe051,0xe052,0xe053,0xe054,0xe055,0xe056,0xe057,
+ 0xe058,0xe059,0xe05a,0xe05b,0xe05c,0xe05d,0xe05e,0xe05f,
+ 0xe060,0xe061,0xe062,0xe063,0xe064,0xe065,0xe066,0xe067,
+ 0xe068,0xe069,0xe06a,0xe06b,0xe06c,0xe06d,0xe06e,0xe06f,
+ 0xe070,0xe071,0xe072,0xe073,0xe074,0xe075,0xe076,0xe077,
+ 0xe078,0xe079,0xe07a,0xe07b,0xe07c,0xe07d,0xe07e,0xe07f,
+ 0xe080,0xe081,0xe082,0xe083,0xe084,0xe085,0xe086,0xe087,
+ 0xe088,0xe089,0xe08a,0xe08b,0xe08c,0xe08d,0xe08e,0xe08f,
+ 0xe090,0xe091,0xe092,0xe093,0xe094,0xe095,0xe096,0xe097,
+ 0xe098,0xe099,0xe09a,0xe09b,0xe09c,0xe09d,0xe09e,0xe09f,
+ 0xe0a0,0xe0a1,0xe0a2,0xe0a3,0xe0a4,0xe0a5,0xe0a6,0xe0a7,
+ 0xe0a8,0xe0a9,0xe0aa,0xe0ab,0xe0ac,0xe0ad,0xe0ae,0xe0af,
+ 0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xe0b4,0xe0b5,0xe0b6,0xe0b7,
+ 0xe0b8,0xe0b9,0xe0ba,0xe0bb,0xe0bc,0xe0bd,0xe0be,0xe0bf,
+ 0xe0c0,0xe0c1,0xe0c2,0xe0c3,0xe0c4,0xe0c5,0xe0c6,0xe0c7,
+ 0xe0c8,0xe0c9,0xe0ca,0xe0cb,0xe0cc,0xe0cd,0xe0ce,0xe0cf,
+ 0xe0d0,0xe0d1,0xe0d2,0xe0d3,0xe0d4,0xe0d5,0xe0d6,0xe0d7,
+ 0xe0d8,0xe0d9,0xe0da,0xe0db,0xe0dc,0xe0dd,0xe0de,0xe0df,
+ 0xe0e0,0xe0e1,0xe0e2,0xe0e3,0xe0e4,0xe0e5,0xe0e6,0xe0e7,
+ 0xe0e8,0xe0e9,0xe0ea,0xe0eb,0xe0ec,0xe0ed,0xe0ee,0xe0ef,
+ 0xe0f0,0xe0f1,0xe0f2,0xe0f3,0xe0f4,0xe0f5,0xe0f6,0xe0f7,
+ 0xe0f8,0xe0f9,0xe0fa,0xe0fb,0xe0fc,0xe0fd,0xe0fe,0xe0ff,
+ 0xe100,0xe101,0xe102,0xe103,0xe104,0xe105,0xe106,0xe107,
+ 0xe108,0xe109,0xe10a,0xe10b,0xe10c,0xe10d,0xe10e,0xe10f,
+ 0xe110,0xe111,0xe112,0xe113,0xe114,0xe115,0xe116,0xe117,
+ 0xe118,0xe119,0xe11a,0xe11b,0xe11c,0xe11d,0xe11e,0xe11f,
+ 0xe120,0xe121,0xe122,0xe123,0xe124,0xe125,0xe126,0xe127,
+ 0xe128,0xe129,0xe12a,0xe12b,0xe12c,0xe12d,0xe12e,0xe12f,
+ 0xe130,0xe131,0xe132,0xe133,0xe134,0xe135,0xe136,0xe137,
+ 0xe138,0xe139,0xe13a,0xe13b,0xe13c,0xe13d,0xe13e,0xe13f,
+ 0xe140,0xe141,0xe142,0xe143,0xe144,0xe145,0xe146,0xe147,
+ 0xe148,0xe149,0xe14a,0xe14b,0xe14c,0xe14d,0xe14e,0xe14f,
+ 0xe150,0xe151,0xe152,0xe153,0xe154,0xe155,0xe156,0xe157,
+ 0xe158,0xe159,0xe15a,0xe15b,0xe15c,0xe15d,0xe15e,0xe15f,
+ 0xe160,0xe161,0xe162,0xe163,0xe164,0xe165,0xe166,0xe167,
+ 0xe168,0xe169,0xe16a,0xe16b,0xe16c,0xe16d,0xe16e,0xe16f,
+ 0xe170,0xe171,0xe172,0xe173,0xe174,0xe175,0xe176,0xe177,
+ 0xe178,0xe179,0xe17a,0xe17b,0xe17c,0xe17d,0xe17e,0xe17f,
+ 0xe180,0xe181,0xe182,0xe183,0xe184,0xe185,0xe186,0xe187,
+ 0xe188,0xe189,0xe18a,0xe18b,0xe18c,0xe18d,0xe18e,0xe18f,
+ 0xe190,0xe191,0xe192,0xe193,0xe194,0xe195,0xe196,0xe197,
+ 0xe198,0xe199,0xe19a,0xe19b,0xe19c,0xe19d,0xe19e,0xe19f,
+ 0xe1a0,0xe1a1,0xe1a2,0xe1a3,0xe1a4,0xe1a5,0xe1a6,0xe1a7,
+ 0xe1a8,0xe1a9,0xe1aa,0xe1ab,0xe1ac,0xe1ad,0xe1ae,0xe1af,
+ 0xe1b0,0xe1b1,0xe1b2,0xe1b3,0xe1b4,0xe1b5,0xe1b6,0xe1b7,
+ 0xe1b8,0xe1b9,0xe1ba,0xe1bb,0xe1bc,0xe1bd,0xe1be,0xe1bf,
+ 0xe1c0,0xe1c1,0xe1c2,0xe1c3,0xe1c4,0xe1c5,0xe1c6,0xe1c7,
+ 0xe1c8,0xe1c9,0xe1ca,0xe1cb,0xe1cc,0xe1cd,0xe1ce,0xe1cf,
+ 0xe1d0,0xe1d1,0xe1d2,0xe1d3,0xe1d4,0xe1d5,0xe1d6,0xe1d7,
+ 0xe1d8,0xe1d9,0xe1da,0xe1db,0xe1dc,0xe1dd,0xe1de,0xe1df,
+ 0xe1e0,0xe1e1,0xe1e2,0xe1e3,0xe1e4,0xe1e5,0xe1e6,0xe1e7,
+ 0xe1e8,0xe1e9,0xe1ea,0xe1eb,0xe1ec,0xe1ed,0xe1ee,0xe1ef,
+ 0xe1f0,0xe1f1,0xe1f2,0xe1f3,0xe1f4,0xe1f5,0xe1f6,0xe1f7,
+ 0xe1f8,0xe1f9,0xe1fa,0xe1fb,0xe1fc,0xe1fd,0xe1fe,0xe1ff,
+ 0xe200,0xe201,0xe202,0xe203,0xe204,0xe205,0xe206,0xe207,
+ 0xe208,0xe209,0xe20a,0xe20b,0xe20c,0xe20d,0xe20e,0xe20f,
+ 0xe210,0xe211,0xe212,0xe213,0xe214,0xe215,0xe216,0xe217,
+ 0xe218,0xe219,0xe21a,0xe21b,0xe21c,0xe21d,0xe21e,0xe21f,
+ 0xe220,0xe221,0xe222,0xe223,0xe224,0xe225,0xe226,0xe227,
+ 0xe228,0xe229,0xe22a,0xe22b,0xe22c,0xe22d,0xe22e,0xe22f,
+ 0xe230,0xe231,0xe232,0xe233,0xe234,0xe235,0xe236,0xe237,
+ 0xe238,0xe239,0xe23a,0xe23b,0xe23c,0xe23d,0xe23e,0xe23f,
+ 0xe240,0xe241,0xe242,0xe243,0xe244,0xe245,0xe246,0xe247,
+ 0xe248,0xe249,0xe24a,0xe24b,0xe24c,0xe24d,0xe24e,0xe24f,
+ 0xe250,0xe251,0xe252,0xe253,0xe254,0xe255,0xe256,0xe257,
+ 0xe258,0xe259,0xe25a,0xe25b,0xe25c,0xe25d,0xe25e,0xe25f,
+ 0xe260,0xe261,0xe262,0xe263,0xe264,0xe265,0xe266,0xe267,
+ 0xe268,0xe269,0xe26a,0xe26b,0xe26c,0xe26d,0xe26e,0xe26f,
+ 0xe270,0xe271,0xe272,0xe273,0xe274,0xe275,0xe276,0xe277,
+ 0xe278,0xe279,0xe27a,0xe27b,0xe27c,0xe27d,0xe27e,0xe27f,
+ 0xe280,0xe281,0xe282,0xe283,0xe284,0xe285,0xe286,0xe287,
+ 0xe288,0xe289,0xe28a,0xe28b,0xe28c,0xe28d,0xe28e,0xe28f,
+ 0xe290,0xe291,0xe292,0xe293,0xe294,0xe295,0xe296,0xe297,
+ 0xe298,0xe299,0xe29a,0xe29b,0xe29c,0xe29d,0xe29e,0xe29f,
+ 0xe2a0,0xe2a1,0xe2a2,0xe2a3,0xe2a4,0xe2a5,0xe2a6,0xe2a7,
+ 0xe2a8,0xe2a9,0xe2aa,0xe2ab,0xe2ac,0xe2ad,0xe2ae,0xe2af,
+ 0xe2b0,0xe2b1,0xe2b2,0xe2b3,0xe2b4,0xe2b5,0xe2b6,0xe2b7,
+ 0xe2b8,0xe2b9,0xe2ba,0xe2bb,0xe2bc,0xe2bd,0xe2be,0xe2bf,
+ 0xe2c0,0xe2c1,0xe2c2,0xe2c3,0xe2c4,0xe2c5,0xe2c6,0xe2c7,
+ 0xe2c8,0xe2c9,0xe2ca,0xe2cb,0xe2cc,0xe2cd,0xe2ce,0xe2cf,
+ 0xe2d0,0xe2d1,0xe2d2,0xe2d3,0xe2d4,0xe2d5,0xe2d6,0xe2d7,
+ 0xe2d8,0xe2d9,0xe2da,0xe2db,0xe2dc,0xe2dd,0xe2de,0xe2df,
+ 0xe2e0,0xe2e1,0xe2e2,0xe2e3,0xe2e4,0xe2e5,0xe2e6,0xe2e7,
+ 0xe2e8,0xe2e9,0xe2ea,0xe2eb,0xe2ec,0xe2ed,0xe2ee,0xe2ef,
+ 0xe2f0,0xe2f1,0xe2f2,0xe2f3,0xe2f4,0xe2f5,0xe2f6,0xe2f7,
+ 0xe2f8,0xe2f9,0xe2fa,0xe2fb,0xe2fc,0xe2fd,0xe2fe,0xe2ff,
+ 0xe300,0xe301,0xe302,0xe303,0xe304,0xe305,0xe306,0xe307,
+ 0xe308,0xe309,0xe30a,0xe30b,0xe30c,0xe30d,0xe30e,0xe30f,
+ 0xe310,0xe311,0xe312,0xe313,0xe314,0xe315,0xe316,0xe317,
+ 0xe318,0xe319,0xe31a,0xe31b,0xe31c,0xe31d,0xe31e,0xe31f,
+ 0xe320,0xe321,0xe322,0xe323,0xe324,0xe325,0xe326,0xe327,
+ 0xe328,0xe329,0xe32a,0xe32b,0xe32c,0xe32d,0xe32e,0xe32f,
+ 0xe330,0xe331,0xe332,0xe333,0xe334,0xe335,0xe336,0xe337,
+ 0xe338,0xe339,0xe33a,0xe33b,0xe33c,0xe33d,0xe33e,0xe33f,
+ 0xe340,0xe341,0xe342,0xe343,0xe344,0xe345,0xe346,0xe347,
+ 0xe348,0xe349,0xe34a,0xe34b,0xe34c,0xe34d,0xe34e,0xe34f,
+ 0xe350,0xe351,0xe352,0xe353,0xe354,0xe355,0xe356,0xe357,
+ 0xe358,0xe359,0xe35a,0xe35b,0xe35c,0xe35d,0xe35e,0xe35f,
+ 0xe360,0xe361,0xe362,0xe363,0xe364,0xe365,0xe366,0xe367,
+ 0xe368,0xe369,0xe36a,0xe36b,0xe36c,0xe36d,0xe36e,0xe36f,
+ 0xe370,0xe371,0xe372,0xe373,0xe374,0xe375,0xe376,0xe377,
+ 0xe378,0xe379,0xe37a,0xe37b,0xe37c,0xe37d,0xe37e,0xe37f,
+ 0xe380,0xe381,0xe382,0xe383,0xe384,0xe385,0xe386,0xe387,
+ 0xe388,0xe389,0xe38a,0xe38b,0xe38c,0xe38d,0xe38e,0xe38f,
+ 0xe390,0xe391,0xe392,0xe393,0xe394,0xe395,0xe396,0xe397,
+ 0xe398,0xe399,0xe39a,0xe39b,0xe39c,0xe39d,0xe39e,0xe39f,
+ 0xe3a0,0xe3a1,0xe3a2,0xe3a3,0xe3a4,0xe3a5,0xe3a6,0xe3a7,
+ 0xe3a8,0xe3a9,0xe3aa,0xe3ab,0xe3ac,0xe3ad,0xe3ae,0xe3af,
+ 0xe3b0,0xe3b1,0xe3b2,0xe3b3,0xe3b4,0xe3b5,0xe3b6,0xe3b7,
+ 0xe3b8,0xe3b9,0xe3ba,0xe3bb,0xe3bc,0xe3bd,0xe3be,0xe3bf,
+ 0xe3c0,0xe3c1,0xe3c2,0xe3c3,0xe3c4,0xe3c5,0xe3c6,0xe3c7,
+ 0xe3c8,0xe3c9,0xe3ca,0xe3cb,0xe3cc,0xe3cd,0xe3ce,0xe3cf,
+ 0xe3d0,0xe3d1,0xe3d2,0xe3d3,0xe3d4,0xe3d5,0xe3d6,0xe3d7,
+ 0xe3d8,0xe3d9,0xe3da,0xe3db,0xe3dc,0xe3dd,0xe3de,0xe3df,
+ 0xe3e0,0xe3e1,0xe3e2,0xe3e3,0xe3e4,0xe3e5,0xe3e6,0xe3e7,
+ 0xe3e8,0xe3e9,0xe3ea,0xe3eb,0xe3ec,0xe3ed,0xe3ee,0xe3ef,
+ 0xe3f0,0xe3f1,0xe3f2,0xe3f3,0xe3f4,0xe3f5,0xe3f6,0xe3f7,
+ 0xe3f8,0xe3f9,0xe3fa,0xe3fb,0xe3fc,0xe3fd,0xe3fe,0xe3ff,
+ 0xe400,0xe401,0xe402,0xe403,0xe404,0xe405,0xe406,0xe407,
+ 0xe408,0xe409,0xe40a,0xe40b,0xe40c,0xe40d,0xe40e,0xe40f,
+ 0xe410,0xe411,0xe412,0xe413,0xe414,0xe415,0xe416,0xe417,
+ 0xe418,0xe419,0xe41a,0xe41b,0xe41c,0xe41d,0xe41e,0xe41f,
+ 0xe420,0xe421,0xe422,0xe423,0xe424,0xe425,0xe426,0xe427,
+ 0xe428,0xe429,0xe42a,0xe42b,0xe42c,0xe42d,0xe42e,0xe42f,
+ 0xe430,0xe431,0xe432,0xe433,0xe434,0xe435,0xe436,0xe437,
+ 0xe438,0xe439,0xe43a,0xe43b,0xe43c,0xe43d,0xe43e,0xe43f,
+ 0xe440,0xe441,0xe442,0xe443,0xe444,0xe445,0xe446,0xe447,
+ 0xe448,0xe449,0xe44a,0xe44b,0xe44c,0xe44d,0xe44e,0xe44f,
+ 0xe450,0xe451,0xe452,0xe453,0xe454,0xe455,0xe456,0xe457,
+ 0xe458,0xe459,0xe45a,0xe45b,0xe45c,0xe45d,0xe45e,0xe45f,
+ 0xe460,0xe461,0xe462,0xe463,0xe464,0xe465,0xe466,0xe467,
+ 0xe468,0xe469,0xe46a,0xe46b,0xe46c,0xe46d,0xe46e,0xe46f,
+ 0xe470,0xe471,0xe472,0xe473,0xe474,0xe475,0xe476,0xe477,
+ 0xe478,0xe479,0xe47a,0xe47b,0xe47c,0xe47d,0xe47e,0xe47f,
+ 0xe480,0xe481,0xe482,0xe483,0xe484,0xe485,0xe486,0xe487,
+ 0xe488,0xe489,0xe48a,0xe48b,0xe48c,0xe48d,0xe48e,0xe48f,
+ 0xe490,0xe491,0xe492,0xe493,0xe494,0xe495,0xe496,0xe497,
+ 0xe498,0xe499,0xe49a,0xe49b,0xe49c,0xe49d,0xe49e,0xe49f,
+ 0xe4a0,0xe4a1,0xe4a2,0xe4a3,0xe4a4,0xe4a5,0xe4a6,0xe4a7,
+ 0xe4a8,0xe4a9,0xe4aa,0xe4ab,0xe4ac,0xe4ad,0xe4ae,0xe4af,
+ 0xe4b0,0xe4b1,0xe4b2,0xe4b3,0xe4b4,0xe4b5,0xe4b6,0xe4b7,
+ 0xe4b8,0xe4b9,0xe4ba,0xe4bb,0xe4bc,0xe4bd,0xe4be,0xe4bf,
+ 0xe4c0,0xe4c1,0xe4c2,0xe4c3,0xe4c4,0xe4c5,0xe4c6,0xe4c7,
+ 0xe4c8,0xe4c9,0xe4ca,0xe4cb,0xe4cc,0xe4cd,0xe4ce,0xe4cf,
+ 0xe4d0,0xe4d1,0xe4d2,0xe4d3,0xe4d4,0xe4d5,0xe4d6,0xe4d7,
+ 0xe4d8,0xe4d9,0xe4da,0xe4db,0xe4dc,0xe4dd,0xe4de,0xe4df,
+ 0xe4e0,0xe4e1,0xe4e2,0xe4e3,0xe4e4,0xe4e5,0xe4e6,0xe4e7,
+ 0xe4e8,0xe4e9,0xe4ea,0xe4eb,0xe4ec,0xe4ed,0xe4ee,0xe4ef,
+ 0xe4f0,0xe4f1,0xe4f2,0xe4f3,0xe4f4,0xe4f5,0xe4f6,0xe4f7,
+ 0xe4f8,0xe4f9,0xe4fa,0xe4fb,0xe4fc,0xe4fd,0xe4fe,0xe4ff,
+ 0xe500,0xe501,0xe502,0xe503,0xe504,0xe505,0xe506,0xe507,
+ 0xe508,0xe509,0xe50a,0xe50b,0xe50c,0xe50d,0xe50e,0xe50f,
+ 0xe510,0xe511,0xe512,0xe513,0xe514,0xe515,0xe516,0xe517,
+ 0xe518,0xe519,0xe51a,0xe51b,0xe51c,0xe51d,0xe51e,0xe51f,
+ 0xe520,0xe521,0xe522,0xe523,0xe524,0xe525,0xe526,0xe527,
+ 0xe528,0xe529,0xe52a,0xe52b,0xe52c,0xe52d,0xe52e,0xe52f,
+ 0xe530,0xe531,0xe532,0xe533,0xe534,0xe535,0xe536,0xe537,
+ 0xe538,0xe539,0xe53a,0xe53b,0xe53c,0xe53d,0xe53e,0xe53f,
+ 0xe540,0xe541,0xe542,0xe543,0xe544,0xe545,0xe546,0xe547,
+ 0xe548,0xe549,0xe54a,0xe54b,0xe54c,0xe54d,0xe54e,0xe54f,
+ 0xe550,0xe551,0xe552,0xe553,0xe554,0xe555,0xe556,0xe557,
+ 0xe558,0xe559,0xe55a,0xe55b,0xe55c,0xe55d,0xe55e,0xe55f,
+ 0xe560,0xe561,0xe562,0xe563,0xe564,0xe565,0xe566,0xe567,
+ 0xe568,0xe569,0xe56a,0xe56b,0xe56c,0xe56d,0xe56e,0xe56f,
+ 0xe570,0xe571,0xe572,0xe573,0xe574,0xe575,0xe576,0xe577,
+ 0xe578,0xe579,0xe57a,0xe57b,0xe57c,0xe57d,0xe57e,0xe57f,
+ 0xe580,0xe581,0xe582,0xe583,0xe584,0xe585,0xe586,0xe587,
+ 0xe588,0xe589,0xe58a,0xe58b,0xe58c,0xe58d,0xe58e,0xe58f,
+ 0xe590,0xe591,0xe592,0xe593,0xe594,0xe595,0xe596,0xe597,
+ 0xe598,0xe599,0xe59a,0xe59b,0xe59c,0xe59d,0xe59e,0xe59f,
+ 0xe5a0,0xe5a1,0xe5a2,0xe5a3,0xe5a4,0xe5a5,0xe5a6,0xe5a7,
+ 0xe5a8,0xe5a9,0xe5aa,0xe5ab,0xe5ac,0xe5ad,0xe5ae,0xe5af,
+ 0xe5b0,0xe5b1,0xe5b2,0xe5b3,0xe5b4,0xe5b5,0xe5b6,0xe5b7,
+ 0xe5b8,0xe5b9,0xe5ba,0xe5bb,0xe5bc,0xe5bd,0xe5be,0xe5bf,
+ 0xe5c0,0xe5c1,0xe5c2,0xe5c3,0xe5c4,0xe5c5,0xe5c6,0xe5c7,
+ 0xe5c8,0xe5c9,0xe5ca,0xe5cb,0xe5cc,0xe5cd,0xe5ce,0xe5cf,
+ 0xe5d0,0xe5d1,0xe5d2,0xe5d3,0xe5d4,0xe5d5,0xe5d6,0xe5d7,
+ 0xe5d8,0xe5d9,0xe5da,0xe5db,0xe5dc,0xe5dd,0xe5de,0xe5df,
+ 0xe5e0,0xe5e1,0xe5e2,0xe5e3,0xe5e4,0xe5e5,0xe5e6,0xe5e7,
+ 0xe5e8,0xe5e9,0xe5ea,0xe5eb,0xe5ec,0xe5ed,0xe5ee,0xe5ef,
+ 0xe5f0,0xe5f1,0xe5f2,0xe5f3,0xe5f4,0xe5f5,0xe5f6,0xe5f7,
+ 0xe5f8,0xe5f9,0xe5fa,0xe5fb,0xe5fc,0xe5fd,0xe5fe,0xe5ff,
+ 0xe600,0xe601,0xe602,0xe603,0xe604,0xe605,0xe606,0xe607,
+ 0xe608,0xe609,0xe60a,0xe60b,0xe60c,0xe60d,0xe60e,0xe60f,
+ 0xe610,0xe611,0xe612,0xe613,0xe614,0xe615,0xe616,0xe617,
+ 0xe618,0xe619,0xe61a,0xe61b,0xe61c,0xe61d,0xe61e,0xe61f,
+ 0xe620,0xe621,0xe622,0xe623,0xe624,0xe625,0xe626,0xe627,
+ 0xe628,0xe629,0xe62a,0xe62b,0xe62c,0xe62d,0xe62e,0xe62f,
+ 0xe630,0xe631,0xe632,0xe633,0xe634,0xe635,0xe636,0xe637,
+ 0xe638,0xe639,0xe63a,0xe63b,0xe63c,0xe63d,0xe63e,0xe63f,
+ 0xe640,0xe641,0xe642,0xe643,0xe644,0xe645,0xe646,0xe647,
+ 0xe648,0xe649,0xe64a,0xe64b,0xe64c,0xe64d,0xe64e,0xe64f,
+ 0xe650,0xe651,0xe652,0xe653,0xe654,0xe655,0xe656,0xe657,
+ 0xe658,0xe659,0xe65a,0xe65b,0xe65c,0xe65d,0xe65e,0xe65f,
+ 0xe660,0xe661,0xe662,0xe663,0xe664,0xe665,0xe666,0xe667,
+ 0xe668,0xe669,0xe66a,0xe66b,0xe66c,0xe66d,0xe66e,0xe66f,
+ 0xe670,0xe671,0xe672,0xe673,0xe674,0xe675,0xe676,0xe677,
+ 0xe678,0xe679,0xe67a,0xe67b,0xe67c,0xe67d,0xe67e,0xe67f,
+ 0xe680,0xe681,0xe682,0xe683,0xe684,0xe685,0xe686,0xe687,
+ 0xe688,0xe689,0xe68a,0xe68b,0xe68c,0xe68d,0xe68e,0xe68f,
+ 0xe690,0xe691,0xe692,0xe693,0xe694,0xe695,0xe696,0xe697,
+ 0xe698,0xe699,0xe69a,0xe69b,0xe69c,0xe69d,0xe69e,0xe69f,
+ 0xe6a0,0xe6a1,0xe6a2,0xe6a3,0xe6a4,0xe6a5,0xe6a6,0xe6a7,
+ 0xe6a8,0xe6a9,0xe6aa,0xe6ab,0xe6ac,0xe6ad,0xe6ae,0xe6af,
+ 0xe6b0,0xe6b1,0xe6b2,0xe6b3,0xe6b4,0xe6b5,0xe6b6,0xe6b7,
+ 0xe6b8,0xe6b9,0xe6ba,0xe6bb,0xe6bc,0xe6bd,0xe6be,0xe6bf,
+ 0xe6c0,0xe6c1,0xe6c2,0xe6c3,0xe6c4,0xe6c5,0xe6c6,0xe6c7,
+ 0xe6c8,0xe6c9,0xe6ca,0xe6cb,0xe6cc,0xe6cd,0xe6ce,0xe6cf,
+ 0xe6d0,0xe6d1,0xe6d2,0xe6d3,0xe6d4,0xe6d5,0xe6d6,0xe6d7,
+ 0xe6d8,0xe6d9,0xe6da,0xe6db,0xe6dc,0xe6dd,0xe6de,0xe6df,
+ 0xe6e0,0xe6e1,0xe6e2,0xe6e3,0xe6e4,0xe6e5,0xe6e6,0xe6e7,
+ 0xe6e8,0xe6e9,0xe6ea,0xe6eb,0xe6ec,0xe6ed,0xe6ee,0xe6ef,
+ 0xe6f0,0xe6f1,0xe6f2,0xe6f3,0xe6f4,0xe6f5,0xe6f6,0xe6f7,
+ 0xe6f8,0xe6f9,0xe6fa,0xe6fb,0xe6fc,0xe6fd,0xe6fe,0xe6ff,
+ 0xe700,0xe701,0xe702,0xe703,0xe704,0xe705,0xe706,0xe707,
+ 0xe708,0xe709,0xe70a,0xe70b,0xe70c,0xe70d,0xe70e,0xe70f,
+ 0xe710,0xe711,0xe712,0xe713,0xe714,0xe715,0xe716,0xe717,
+ 0xe718,0xe719,0xe71a,0xe71b,0xe71c,0xe71d,0xe71e,0xe71f,
+ 0xe720,0xe721,0xe722,0xe723,0xe724,0xe725,0xe726,0xe727,
+ 0xe728,0xe729,0xe72a,0xe72b,0xe72c,0xe72d,0xe72e,0xe72f,
+ 0xe730,0xe731,0xe732,0xe733,0xe734,0xe735,0xe736,0xe737,
+ 0xe738,0xe739,0xe73a,0xe73b,0xe73c,0xe73d,0xe73e,0xe73f,
+ 0xe740,0xe741,0xe742,0xe743,0xe744,0xe745,0xe746,0xe747,
+ 0xe748,0xe749,0xe74a,0xe74b,0xe74c,0xe74d,0xe74e,0xe74f,
+ 0xe750,0xe751,0xe752,0xe753,0xe754,0xe755,0xe756,0xe757,
+ 0xe758,0xe759,0xe75a,0xe75b,0xe75c,0xe75d,0xe75e,0xe75f,
+ 0xe760,0xe761,0xe762,0xe763,0xe764,0xe765,0xe766,0xe767,
+ 0xe768,0xe769,0xe76a,0xe76b,0xe76c,0xe76d,0xe76e,0xe76f,
+ 0xe770,0xe771,0xe772,0xe773,0xe774,0xe775,0xe776,0xe777,
+ 0xe778,0xe779,0xe77a,0xe77b,0xe77c,0xe77d,0xe77e,0xe77f,
+ 0xe780,0xe781,0xe782,0xe783,0xe784,0xe785,0xe786,0xe787,
+ 0xe788,0xe789,0xe78a,0xe78b,0xe78c,0xe78d,0xe78e,0xe78f,
+ 0xe790,0xe791,0xe792,0xe793,0xe794,0xe795,0xe796,0xe797,
+ 0xe798,0xe799,0xe79a,0xe79b,0xe79c,0xe79d,0xe79e,0xe79f,
+ 0xe7a0,0xe7a1,0xe7a2,0xe7a3,0xe7a4,0xe7a5,0xe7a6,0xe7a7,
+ 0xe7a8,0xe7a9,0xe7aa,0xe7ab,0xe7ac,0xe7ad,0xe7ae,0xe7af,
+ 0xe7b0,0xe7b1,0xe7b2,0xe7b3,0xe7b4,0xe7b5,0xe7b6,0xe7b7,
+ 0xe7b8,0xe7b9,0xe7ba,0xe7bb,0xe7bc,0xe7bd,0xe7be,0xe7bf,
+ 0xe7c0,0xe7c1,0xe7c2,0xe7c3,0xe7c4,0xe7c5,0xe7c6,0xe7c7,
+ 0xe7c8,0xe7c9,0xe7ca,0xe7cb,0xe7cc,0xe7cd,0xe7ce,0xe7cf,
+ 0xe7d0,0xe7d1,0xe7d2,0xe7d3,0xe7d4,0xe7d5,0xe7d6,0xe7d7,
+ 0xe7d8,0xe7d9,0xe7da,0xe7db,0xe7dc,0xe7dd,0xe7de,0xe7df,
+ 0xe7e0,0xe7e1,0xe7e2,0xe7e3,0xe7e4,0xe7e5,0xe7e6,0xe7e7,
+ 0xe7e8,0xe7e9,0xe7ea,0xe7eb,0xe7ec,0xe7ed,0xe7ee,0xe7ef,
+ 0xe7f0,0xe7f1,0xe7f2,0xe7f3,0xe7f4,0xe7f5,0xe7f6,0xe7f7,
+ 0xe7f8,0xe7f9,0xe7fa,0xe7fb,0xe7fc,0xe7fd,0xe7fe,0xe7ff,
+ 0xe800,0xe801,0xe802,0xe803,0xe804,0xe805,0xe806,0xe807,
+ 0xe808,0xe809,0xe80a,0xe80b,0xe80c,0xe80d,0xe80e,0xe80f,
+ 0xe810,0xe811,0xe812,0xe813,0xe814,0xe815,0xe816,0xe817,
+ 0xe818,0xe819,0xe81a,0xe81b,0xe81c,0xe81d,0xe81e,0xe81f,
+ 0xe820,0xe821,0xe822,0xe823,0xe824,0xe825,0xe826,0xe827,
+ 0xe828,0xe829,0xe82a,0xe82b,0xe82c,0xe82d,0xe82e,0xe82f,
+ 0xe830,0xe831,0xe832,0xe833,0xe834,0xe835,0xe836,0xe837,
+ 0xe838,0xe839,0xe83a,0xe83b,0xe83c,0xe83d,0xe83e,0xe83f,
+ 0xe840,0xe841,0xe842,0xe843,0xe844,0xe845,0xe846,0xe847,
+ 0xe848,0xe849,0xe84a,0xe84b,0xe84c,0xe84d,0xe84e,0xe84f,
+ 0xe850,0xe851,0xe852,0xe853,0xe854,0xe855,0xe856,0xe857,
+ 0xe858,0xe859,0xe85a,0xe85b,0xe85c,0xe85d,0xe85e,0xe85f,
+ 0xe860,0xe861,0xe862,0xe863,0xe864,0xe865,0xe866,0xe867,
+ 0xe868,0xe869,0xe86a,0xe86b,0xe86c,0xe86d,0xe86e,0xe86f,
+ 0xe870,0xe871,0xe872,0xe873,0xe874,0xe875,0xe876,0xe877,
+ 0xe878,0xe879,0xe87a,0xe87b,0xe87c,0xe87d,0xe87e,0xe87f,
+ 0xe880,0xe881,0xe882,0xe883,0xe884,0xe885,0xe886,0xe887,
+ 0xe888,0xe889,0xe88a,0xe88b,0xe88c,0xe88d,0xe88e,0xe88f,
+ 0xe890,0xe891,0xe892,0xe893,0xe894,0xe895,0xe896,0xe897,
+ 0xe898,0xe899,0xe89a,0xe89b,0xe89c,0xe89d,0xe89e,0xe89f,
+ 0xe8a0,0xe8a1,0xe8a2,0xe8a3,0xe8a4,0xe8a5,0xe8a6,0xe8a7,
+ 0xe8a8,0xe8a9,0xe8aa,0xe8ab,0xe8ac,0xe8ad,0xe8ae,0xe8af,
+ 0xe8b0,0xe8b1,0xe8b2,0xe8b3,0xe8b4,0xe8b5,0xe8b6,0xe8b7,
+ 0xe8b8,0xe8b9,0xe8ba,0xe8bb,0xe8bc,0xe8bd,0xe8be,0xe8bf,
+ 0xe8c0,0xe8c1,0xe8c2,0xe8c3,0xe8c4,0xe8c5,0xe8c6,0xe8c7,
+ 0xe8c8,0xe8c9,0xe8ca,0xe8cb,0xe8cc,0xe8cd,0xe8ce,0xe8cf,
+ 0xe8d0,0xe8d1,0xe8d2,0xe8d3,0xe8d4,0xe8d5,0xe8d6,0xe8d7,
+ 0xe8d8,0xe8d9,0xe8da,0xe8db,0xe8dc,0xe8dd,0xe8de,0xe8df,
+ 0xe8e0,0xe8e1,0xe8e2,0xe8e3,0xe8e4,0xe8e5,0xe8e6,0xe8e7,
+ 0xe8e8,0xe8e9,0xe8ea,0xe8eb,0xe8ec,0xe8ed,0xe8ee,0xe8ef,
+ 0xe8f0,0xe8f1,0xe8f2,0xe8f3,0xe8f4,0xe8f5,0xe8f6,0xe8f7,
+ 0xe8f8,0xe8f9,0xe8fa,0xe8fb,0xe8fc,0xe8fd,0xe8fe,0xe8ff,
+ 0xe900,0xe901,0xe902,0xe903,0xe904,0xe905,0xe906,0xe907,
+ 0xe908,0xe909,0xe90a,0xe90b,0xe90c,0xe90d,0xe90e,0xe90f,
+ 0xe910,0xe911,0xe912,0xe913,0xe914,0xe915,0xe916,0xe917,
+ 0xe918,0xe919,0xe91a,0xe91b,0xe91c,0xe91d,0xe91e,0xe91f,
+ 0xe920,0xe921,0xe922,0xe923,0xe924,0xe925,0xe926,0xe927,
+ 0xe928,0xe929,0xe92a,0xe92b,0xe92c,0xe92d,0xe92e,0xe92f,
+ 0xe930,0xe931,0xe932,0xe933,0xe934,0xe935,0xe936,0xe937,
+ 0xe938,0xe939,0xe93a,0xe93b,0xe93c,0xe93d,0xe93e,0xe93f,
+ 0xe940,0xe941,0xe942,0xe943,0xe944,0xe945,0xe946,0xe947,
+ 0xe948,0xe949,0xe94a,0xe94b,0xe94c,0xe94d,0xe94e,0xe94f,
+ 0xe950,0xe951,0xe952,0xe953,0xe954,0xe955,0xe956,0xe957,
+ 0xe958,0xe959,0xe95a,0xe95b,0xe95c,0xe95d,0xe95e,0xe95f,
+ 0xe960,0xe961,0xe962,0xe963,0xe964,0xe965,0xe966,0xe967,
+ 0xe968,0xe969,0xe96a,0xe96b,0xe96c,0xe96d,0xe96e,0xe96f,
+ 0xe970,0xe971,0xe972,0xe973,0xe974,0xe975,0xe976,0xe977,
+ 0xe978,0xe979,0xe97a,0xe97b,0xe97c,0xe97d,0xe97e,0xe97f,
+ 0xe980,0xe981,0xe982,0xe983,0xe984,0xe985,0xe986,0xe987,
+ 0xe988,0xe989,0xe98a,0xe98b,0xe98c,0xe98d,0xe98e,0xe98f,
+ 0xe990,0xe991,0xe992,0xe993,0xe994,0xe995,0xe996,0xe997,
+ 0xe998,0xe999,0xe99a,0xe99b,0xe99c,0xe99d,0xe99e,0xe99f,
+ 0xe9a0,0xe9a1,0xe9a2,0xe9a3,0xe9a4,0xe9a5,0xe9a6,0xe9a7,
+ 0xe9a8,0xe9a9,0xe9aa,0xe9ab,0xe9ac,0xe9ad,0xe9ae,0xe9af,
+ 0xe9b0,0xe9b1,0xe9b2,0xe9b3,0xe9b4,0xe9b5,0xe9b6,0xe9b7,
+ 0xe9b8,0xe9b9,0xe9ba,0xe9bb,0xe9bc,0xe9bd,0xe9be,0xe9bf,
+ 0xe9c0,0xe9c1,0xe9c2,0xe9c3,0xe9c4,0xe9c5,0xe9c6,0xe9c7,
+ 0xe9c8,0xe9c9,0xe9ca,0xe9cb,0xe9cc,0xe9cd,0xe9ce,0xe9cf,
+ 0xe9d0,0xe9d1,0xe9d2,0xe9d3,0xe9d4,0xe9d5,0xe9d6,0xe9d7,
+ 0xe9d8,0xe9d9,0xe9da,0xe9db,0xe9dc,0xe9dd,0xe9de,0xe9df,
+ 0xe9e0,0xe9e1,0xe9e2,0xe9e3,0xe9e4,0xe9e5,0xe9e6,0xe9e7,
+ 0xe9e8,0xe9e9,0xe9ea,0xe9eb,0xe9ec,0xe9ed,0xe9ee,0xe9ef,
+ 0xe9f0,0xe9f1,0xe9f2,0xe9f3,0xe9f4,0xe9f5,0xe9f6,0xe9f7,
+ 0xe9f8,0xe9f9,0xe9fa,0xe9fb,0xe9fc,0xe9fd,0xe9fe,0xe9ff,
+ 0xea00,0xea01,0xea02,0xea03,0xea04,0xea05,0xea06,0xea07,
+ 0xea08,0xea09,0xea0a,0xea0b,0xea0c,0xea0d,0xea0e,0xea0f,
+ 0xea10,0xea11,0xea12,0xea13,0xea14,0xea15,0xea16,0xea17,
+ 0xea18,0xea19,0xea1a,0xea1b,0xea1c,0xea1d,0xea1e,0xea1f,
+ 0xea20,0xea21,0xea22,0xea23,0xea24,0xea25,0xea26,0xea27,
+ 0xea28,0xea29,0xea2a,0xea2b,0xea2c,0xea2d,0xea2e,0xea2f,
+ 0xea30,0xea31,0xea32,0xea33,0xea34,0xea35,0xea36,0xea37,
+ 0xea38,0xea39,0xea3a,0xea3b,0xea3c,0xea3d,0xea3e,0xea3f,
+ 0xea40,0xea41,0xea42,0xea43,0xea44,0xea45,0xea46,0xea47,
+ 0xea48,0xea49,0xea4a,0xea4b,0xea4c,0xea4d,0xea4e,0xea4f,
+ 0xea50,0xea51,0xea52,0xea53,0xea54,0xea55,0xea56,0xea57,
+ 0xea58,0xea59,0xea5a,0xea5b,0xea5c,0xea5d,0xea5e,0xea5f,
+ 0xea60,0xea61,0xea62,0xea63,0xea64,0xea65,0xea66,0xea67,
+ 0xea68,0xea69,0xea6a,0xea6b,0xea6c,0xea6d,0xea6e,0xea6f,
+ 0xea70,0xea71,0xea72,0xea73,0xea74,0xea75,0xea76,0xea77,
+ 0xea78,0xea79,0xea7a,0xea7b,0xea7c,0xea7d,0xea7e,0xea7f,
+ 0xea80,0xea81,0xea82,0xea83,0xea84,0xea85,0xea86,0xea87,
+ 0xea88,0xea89,0xea8a,0xea8b,0xea8c,0xea8d,0xea8e,0xea8f,
+ 0xea90,0xea91,0xea92,0xea93,0xea94,0xea95,0xea96,0xea97,
+ 0xea98,0xea99,0xea9a,0xea9b,0xea9c,0xea9d,0xea9e,0xea9f,
+ 0xeaa0,0xeaa1,0xeaa2,0xeaa3,0xeaa4,0xeaa5,0xeaa6,0xeaa7,
+ 0xeaa8,0xeaa9,0xeaaa,0xeaab,0xeaac,0xeaad,0xeaae,0xeaaf,
+ 0xeab0,0xeab1,0xeab2,0xeab3,0xeab4,0xeab5,0xeab6,0xeab7,
+ 0xeab8,0xeab9,0xeaba,0xeabb,0xeabc,0xeabd,0xeabe,0xeabf,
+ 0xeac0,0xeac1,0xeac2,0xeac3,0xeac4,0xeac5,0xeac6,0xeac7,
+ 0xeac8,0xeac9,0xeaca,0xeacb,0xeacc,0xeacd,0xeace,0xeacf,
+ 0xead0,0xead1,0xead2,0xead3,0xead4,0xead5,0xead6,0xead7,
+ 0xead8,0xead9,0xeada,0xeadb,0xeadc,0xeadd,0xeade,0xeadf,
+ 0xeae0,0xeae1,0xeae2,0xeae3,0xeae4,0xeae5,0xeae6,0xeae7,
+ 0xeae8,0xeae9,0xeaea,0xeaeb,0xeaec,0xeaed,0xeaee,0xeaef,
+ 0xeaf0,0xeaf1,0xeaf2,0xeaf3,0xeaf4,0xeaf5,0xeaf6,0xeaf7,
+ 0xeaf8,0xeaf9,0xeafa,0xeafb,0xeafc,0xeafd,0xeafe,0xeaff,
+ 0xeb00,0xeb01,0xeb02,0xeb03,0xeb04,0xeb05,0xeb06,0xeb07,
+ 0xeb08,0xeb09,0xeb0a,0xeb0b,0xeb0c,0xeb0d,0xeb0e,0xeb0f,
+ 0xeb10,0xeb11,0xeb12,0xeb13,0xeb14,0xeb15,0xeb16,0xeb17,
+ 0xeb18,0xeb19,0xeb1a,0xeb1b,0xeb1c,0xeb1d,0xeb1e,0xeb1f,
+ 0xeb20,0xeb21,0xeb22,0xeb23,0xeb24,0xeb25,0xeb26,0xeb27,
+ 0xeb28,0xeb29,0xeb2a,0xeb2b,0xeb2c,0xeb2d,0xeb2e,0xeb2f,
+ 0xeb30,0xeb31,0xeb32,0xeb33,0xeb34,0xeb35,0xeb36,0xeb37,
+ 0xeb38,0xeb39,0xeb3a,0xeb3b,0xeb3c,0xeb3d,0xeb3e,0xeb3f,
+ 0xeb40,0xeb41,0xeb42,0xeb43,0xeb44,0xeb45,0xeb46,0xeb47,
+ 0xeb48,0xeb49,0xeb4a,0xeb4b,0xeb4c,0xeb4d,0xeb4e,0xeb4f,
+ 0xeb50,0xeb51,0xeb52,0xeb53,0xeb54,0xeb55,0xeb56,0xeb57,
+ 0xeb58,0xeb59,0xeb5a,0xeb5b,0xeb5c,0xeb5d,0xeb5e,0xeb5f,
+ 0xeb60,0xeb61,0xeb62,0xeb63,0xeb64,0xeb65,0xeb66,0xeb67,
+ 0xeb68,0xeb69,0xeb6a,0xeb6b,0xeb6c,0xeb6d,0xeb6e,0xeb6f,
+ 0xeb70,0xeb71,0xeb72,0xeb73,0xeb74,0xeb75,0xeb76,0xeb77,
+ 0xeb78,0xeb79,0xeb7a,0xeb7b,0xeb7c,0xeb7d,0xeb7e,0xeb7f,
+ 0xeb80,0xeb81,0xeb82,0xeb83,0xeb84,0xeb85,0xeb86,0xeb87,
+ 0xeb88,0xeb89,0xeb8a,0xeb8b,0xeb8c,0xeb8d,0xeb8e,0xeb8f,
+ 0xeb90,0xeb91,0xeb92,0xeb93,0xeb94,0xeb95,0xeb96,0xeb97,
+ 0xeb98,0xeb99,0xeb9a,0xeb9b,0xeb9c,0xeb9d,0xeb9e,0xeb9f,
+ 0xeba0,0xeba1,0xeba2,0xeba3,0xeba4,0xeba5,0xeba6,0xeba7,
+ 0xeba8,0xeba9,0xebaa,0xebab,0xebac,0xebad,0xebae,0xebaf,
+ 0xebb0,0xebb1,0xebb2,0xebb3,0xebb4,0xebb5,0xebb6,0xebb7,
+ 0xebb8,0xebb9,0xebba,0xebbb,0xebbc,0xebbd,0xebbe,0xebbf,
+ 0xebc0,0xebc1,0xebc2,0xebc3,0xebc4,0xebc5,0xebc6,0xebc7,
+ 0xebc8,0xebc9,0xebca,0xebcb,0xebcc,0xebcd,0xebce,0xebcf,
+ 0xebd0,0xebd1,0xebd2,0xebd3,0xebd4,0xebd5,0xebd6,0xebd7,
+ 0xebd8,0xebd9,0xebda,0xebdb,0xebdc,0xebdd,0xebde,0xebdf,
+ 0xebe0,0xebe1,0xebe2,0xebe3,0xebe4,0xebe5,0xebe6,0xebe7,
+ 0xebe8,0xebe9,0xebea,0xebeb,0xebec,0xebed,0xebee,0xebef,
+ 0xebf0,0xebf1,0xebf2,0xebf3,0xebf4,0xebf5,0xebf6,0xebf7,
+ 0xebf8,0xebf9,0xebfa,0xebfb,0xebfc,0xebfd,0xebfe,0xebff,
+ 0xec00,0xec01,0xec02,0xec03,0xec04,0xec05,0xec06,0xec07,
+ 0xec08,0xec09,0xec0a,0xec0b,0xec0c,0xec0d,0xec0e,0xec0f,
+ 0xec10,0xec11,0xec12,0xec13,0xec14,0xec15,0xec16,0xec17,
+ 0xec18,0xec19,0xec1a,0xec1b,0xec1c,0xec1d,0xec1e,0xec1f,
+ 0xec20,0xec21,0xec22,0xec23,0xec24,0xec25,0xec26,0xec27,
+ 0xec28,0xec29,0xec2a,0xec2b,0xec2c,0xec2d,0xec2e,0xec2f,
+ 0xec30,0xec31,0xec32,0xec33,0xec34,0xec35,0xec36,0xec37,
+ 0xec38,0xec39,0xec3a,0xec3b,0xec3c,0xec3d,0xec3e,0xec3f,
+ 0xec40,0xec41,0xec42,0xec43,0xec44,0xec45,0xec46,0xec47,
+ 0xec48,0xec49,0xec4a,0xec4b,0xec4c,0xec4d,0xec4e,0xec4f,
+ 0xec50,0xec51,0xec52,0xec53,0xec54,0xec55,0xec56,0xec57,
+ 0xec58,0xec59,0xec5a,0xec5b,0xec5c,0xec5d,0xec5e,0xec5f,
+ 0xec60,0xec61,0xec62,0xec63,0xec64,0xec65,0xec66,0xec67,
+ 0xec68,0xec69,0xec6a,0xec6b,0xec6c,0xec6d,0xec6e,0xec6f,
+ 0xec70,0xec71,0xec72,0xec73,0xec74,0xec75,0xec76,0xec77,
+ 0xec78,0xec79,0xec7a,0xec7b,0xec7c,0xec7d,0xec7e,0xec7f,
+ 0xec80,0xec81,0xec82,0xec83,0xec84,0xec85,0xec86,0xec87,
+ 0xec88,0xec89,0xec8a,0xec8b,0xec8c,0xec8d,0xec8e,0xec8f,
+ 0xec90,0xec91,0xec92,0xec93,0xec94,0xec95,0xec96,0xec97,
+ 0xec98,0xec99,0xec9a,0xec9b,0xec9c,0xec9d,0xec9e,0xec9f,
+ 0xeca0,0xeca1,0xeca2,0xeca3,0xeca4,0xeca5,0xeca6,0xeca7,
+ 0xeca8,0xeca9,0xecaa,0xecab,0xecac,0xecad,0xecae,0xecaf,
+ 0xecb0,0xecb1,0xecb2,0xecb3,0xecb4,0xecb5,0xecb6,0xecb7,
+ 0xecb8,0xecb9,0xecba,0xecbb,0xecbc,0xecbd,0xecbe,0xecbf,
+ 0xecc0,0xecc1,0xecc2,0xecc3,0xecc4,0xecc5,0xecc6,0xecc7,
+ 0xecc8,0xecc9,0xecca,0xeccb,0xeccc,0xeccd,0xecce,0xeccf,
+ 0xecd0,0xecd1,0xecd2,0xecd3,0xecd4,0xecd5,0xecd6,0xecd7,
+ 0xecd8,0xecd9,0xecda,0xecdb,0xecdc,0xecdd,0xecde,0xecdf,
+ 0xece0,0xece1,0xece2,0xece3,0xece4,0xece5,0xece6,0xece7,
+ 0xece8,0xece9,0xecea,0xeceb,0xecec,0xeced,0xecee,0xecef,
+ 0xecf0,0xecf1,0xecf2,0xecf3,0xecf4,0xecf5,0xecf6,0xecf7,
+ 0xecf8,0xecf9,0xecfa,0xecfb,0xecfc,0xecfd,0xecfe,0xecff,
+ 0xed00,0xed01,0xed02,0xed03,0xed04,0xed05,0xed06,0xed07,
+ 0xed08,0xed09,0xed0a,0xed0b,0xed0c,0xed0d,0xed0e,0xed0f,
+ 0xed10,0xed11,0xed12,0xed13,0xed14,0xed15,0xed16,0xed17,
+ 0xed18,0xed19,0xed1a,0xed1b,0xed1c,0xed1d,0xed1e,0xed1f,
+ 0xed20,0xed21,0xed22,0xed23,0xed24,0xed25,0xed26,0xed27,
+ 0xed28,0xed29,0xed2a,0xed2b,0xed2c,0xed2d,0xed2e,0xed2f,
+ 0xed30,0xed31,0xed32,0xed33,0xed34,0xed35,0xed36,0xed37,
+ 0xed38,0xed39,0xed3a,0xed3b,0xed3c,0xed3d,0xed3e,0xed3f,
+ 0xed40,0xed41,0xed42,0xed43,0xed44,0xed45,0xed46,0xed47,
+ 0xed48,0xed49,0xed4a,0xed4b,0xed4c,0xed4d,0xed4e,0xed4f,
+ 0xed50,0xed51,0xed52,0xed53,0xed54,0xed55,0xed56,0xed57,
+ 0xed58,0xed59,0xed5a,0xed5b,0xed5c,0xed5d,0xed5e,0xed5f,
+ 0xed60,0xed61,0xed62,0xed63,0xed64,0xed65,0xed66,0xed67,
+ 0xed68,0xed69,0xed6a,0xed6b,0xed6c,0xed6d,0xed6e,0xed6f,
+ 0xed70,0xed71,0xed72,0xed73,0xed74,0xed75,0xed76,0xed77,
+ 0xed78,0xed79,0xed7a,0xed7b,0xed7c,0xed7d,0xed7e,0xed7f,
+ 0xed80,0xed81,0xed82,0xed83,0xed84,0xed85,0xed86,0xed87,
+ 0xed88,0xed89,0xed8a,0xed8b,0xed8c,0xed8d,0xed8e,0xed8f,
+ 0xed90,0xed91,0xed92,0xed93,0xed94,0xed95,0xed96,0xed97,
+ 0xed98,0xed99,0xed9a,0xed9b,0xed9c,0xed9d,0xed9e,0xed9f,
+ 0xeda0,0xeda1,0xeda2,0xeda3,0xeda4,0xeda5,0xeda6,0xeda7,
+ 0xeda8,0xeda9,0xedaa,0xedab,0xedac,0xedad,0xedae,0xedaf,
+ 0xedb0,0xedb1,0xedb2,0xedb3,0xedb4,0xedb5,0xedb6,0xedb7,
+ 0xedb8,0xedb9,0xedba,0xedbb,0xedbc,0xedbd,0xedbe,0xedbf,
+ 0xedc0,0xedc1,0xedc2,0xedc3,0xedc4,0xedc5,0xedc6,0xedc7,
+ 0xedc8,0xedc9,0xedca,0xedcb,0xedcc,0xedcd,0xedce,0xedcf,
+ 0xedd0,0xedd1,0xedd2,0xedd3,0xedd4,0xedd5,0xedd6,0xedd7,
+ 0xedd8,0xedd9,0xedda,0xeddb,0xeddc,0xeddd,0xedde,0xeddf,
+ 0xede0,0xede1,0xede2,0xede3,0xede4,0xede5,0xede6,0xede7,
+ 0xede8,0xede9,0xedea,0xedeb,0xedec,0xeded,0xedee,0xedef,
+ 0xedf0,0xedf1,0xedf2,0xedf3,0xedf4,0xedf5,0xedf6,0xedf7,
+ 0xedf8,0xedf9,0xedfa,0xedfb,0xedfc,0xedfd,0xedfe,0xedff,
+ 0xee00,0xee01,0xee02,0xee03,0xee04,0xee05,0xee06,0xee07,
+ 0xee08,0xee09,0xee0a,0xee0b,0xee0c,0xee0d,0xee0e,0xee0f,
+ 0xee10,0xee11,0xee12,0xee13,0xee14,0xee15,0xee16,0xee17,
+ 0xee18,0xee19,0xee1a,0xee1b,0xee1c,0xee1d,0xee1e,0xee1f,
+ 0xee20,0xee21,0xee22,0xee23,0xee24,0xee25,0xee26,0xee27,
+ 0xee28,0xee29,0xee2a,0xee2b,0xee2c,0xee2d,0xee2e,0xee2f,
+ 0xee30,0xee31,0xee32,0xee33,0xee34,0xee35,0xee36,0xee37,
+ 0xee38,0xee39,0xee3a,0xee3b,0xee3c,0xee3d,0xee3e,0xee3f,
+ 0xee40,0xee41,0xee42,0xee43,0xee44,0xee45,0xee46,0xee47,
+ 0xee48,0xee49,0xee4a,0xee4b,0xee4c,0xee4d,0xee4e,0xee4f,
+ 0xee50,0xee51,0xee52,0xee53,0xee54,0xee55,0xee56,0xee57,
+ 0xee58,0xee59,0xee5a,0xee5b,0xee5c,0xee5d,0xee5e,0xee5f,
+ 0xee60,0xee61,0xee62,0xee63,0xee64,0xee65,0xee66,0xee67,
+ 0xee68,0xee69,0xee6a,0xee6b,0xee6c,0xee6d,0xee6e,0xee6f,
+ 0xee70,0xee71,0xee72,0xee73,0xee74,0xee75,0xee76,0xee77,
+ 0xee78,0xee79,0xee7a,0xee7b,0xee7c,0xee7d,0xee7e,0xee7f,
+ 0xee80,0xee81,0xee82,0xee83,0xee84,0xee85,0xee86,0xee87,
+ 0xee88,0xee89,0xee8a,0xee8b,0xee8c,0xee8d,0xee8e,0xee8f,
+ 0xee90,0xee91,0xee92,0xee93,0xee94,0xee95,0xee96,0xee97,
+ 0xee98,0xee99,0xee9a,0xee9b,0xee9c,0xee9d,0xee9e,0xee9f,
+ 0xeea0,0xeea1,0xeea2,0xeea3,0xeea4,0xeea5,0xeea6,0xeea7,
+ 0xeea8,0xeea9,0xeeaa,0xeeab,0xeeac,0xeead,0xeeae,0xeeaf,
+ 0xeeb0,0xeeb1,0xeeb2,0xeeb3,0xeeb4,0xeeb5,0xeeb6,0xeeb7,
+ 0xeeb8,0xeeb9,0xeeba,0xeebb,0xeebc,0xeebd,0xeebe,0xeebf,
+ 0xeec0,0xeec1,0xeec2,0xeec3,0xeec4,0xeec5,0xeec6,0xeec7,
+ 0xeec8,0xeec9,0xeeca,0xeecb,0xeecc,0xeecd,0xeece,0xeecf,
+ 0xeed0,0xeed1,0xeed2,0xeed3,0xeed4,0xeed5,0xeed6,0xeed7,
+ 0xeed8,0xeed9,0xeeda,0xeedb,0xeedc,0xeedd,0xeede,0xeedf,
+ 0xeee0,0xeee1,0xeee2,0xeee3,0xeee4,0xeee5,0xeee6,0xeee7,
+ 0xeee8,0xeee9,0xeeea,0xeeeb,0xeeec,0xeeed,0xeeee,0xeeef,
+ 0xeef0,0xeef1,0xeef2,0xeef3,0xeef4,0xeef5,0xeef6,0xeef7,
+ 0xeef8,0xeef9,0xeefa,0xeefb,0xeefc,0xeefd,0xeefe,0xeeff,
+ 0xef00,0xef01,0xef02,0xef03,0xef04,0xef05,0xef06,0xef07,
+ 0xef08,0xef09,0xef0a,0xef0b,0xef0c,0xef0d,0xef0e,0xef0f,
+ 0xef10,0xef11,0xef12,0xef13,0xef14,0xef15,0xef16,0xef17,
+ 0xef18,0xef19,0xef1a,0xef1b,0xef1c,0xef1d,0xef1e,0xef1f,
+ 0xef20,0xef21,0xef22,0xef23,0xef24,0xef25,0xef26,0xef27,
+ 0xef28,0xef29,0xef2a,0xef2b,0xef2c,0xef2d,0xef2e,0xef2f,
+ 0xef30,0xef31,0xef32,0xef33,0xef34,0xef35,0xef36,0xef37,
+ 0xef38,0xef39,0xef3a,0xef3b,0xef3c,0xef3d,0xef3e,0xef3f,
+ 0xef40,0xef41,0xef42,0xef43,0xef44,0xef45,0xef46,0xef47,
+ 0xef48,0xef49,0xef4a,0xef4b,0xef4c,0xef4d,0xef4e,0xef4f,
+ 0xef50,0xef51,0xef52,0xef53,0xef54,0xef55,0xef56,0xef57,
+ 0xef58,0xef59,0xef5a,0xef5b,0xef5c,0xef5d,0xef5e,0xef5f,
+ 0xef60,0xef61,0xef62,0xef63,0xef64,0xef65,0xef66,0xef67,
+ 0xef68,0xef69,0xef6a,0xef6b,0xef6c,0xef6d,0xef6e,0xef6f,
+ 0xef70,0xef71,0xef72,0xef73,0xef74,0xef75,0xef76,0xef77,
+ 0xef78,0xef79,0xef7a,0xef7b,0xef7c,0xef7d,0xef7e,0xef7f,
+ 0xef80,0xef81,0xef82,0xef83,0xef84,0xef85,0xef86,0xef87,
+ 0xef88,0xef89,0xef8a,0xef8b,0xef8c,0xef8d,0xef8e,0xef8f,
+ 0xef90,0xef91,0xef92,0xef93,0xef94,0xef95,0xef96,0xef97,
+ 0xef98,0xef99,0xef9a,0xef9b,0xef9c,0xef9d,0xef9e,0xef9f,
+ 0xefa0,0xefa1,0xefa2,0xefa3,0xefa4,0xefa5,0xefa6,0xefa7,
+ 0xefa8,0xefa9,0xefaa,0xefab,0xefac,0xefad,0xefae,0xefaf,
+ 0xefb0,0xefb1,0xefb2,0xefb3,0xefb4,0xefb5,0xefb6,0xefb7,
+ 0xefb8,0xefb9,0xefba,0xefbb,0xefbc,0xefbd,0xefbe,0xefbf,
+ 0xefc0,0xefc1,0xefc2,0xefc3,0xefc4,0xefc5,0xefc6,0xefc7,
+ 0xefc8,0xefc9,0xefca,0xefcb,0xefcc,0xefcd,0xefce,0xefcf,
+ 0xefd0,0xefd1,0xefd2,0xefd3,0xefd4,0xefd5,0xefd6,0xefd7,
+ 0xefd8,0xefd9,0xefda,0xefdb,0xefdc,0xefdd,0xefde,0xefdf,
+ 0xefe0,0xefe1,0xefe2,0xefe3,0xefe4,0xefe5,0xefe6,0xefe7,
+ 0xefe8,0xefe9,0xefea,0xefeb,0xefec,0xefed,0xefee,0xefef,
+ 0xeff0,0xeff1,0xeff2,0xeff3,0xeff4,0xeff5,0xeff6,0xeff7,
+ 0xeff8,0xeff9,0xeffa,0xeffb,0xeffc,0xeffd,0xeffe,0xefff,
+ 0xf000,0xf001,0xf002,0xf003,0xf004,0xf005,0xf006,0xf007,
+ 0xf008,0xf009,0xf00a,0xf00b,0xf00c,0xf00d,0xf00e,0xf00f,
+ 0xf010,0xf011,0xf012,0xf013,0xf014,0xf015,0xf016,0xf017,
+ 0xf018,0xf019,0xf01a,0xf01b,0xf01c,0xf01d,0xf01e,0xf01f,
+ 0xf020,0xf021,0xf022,0xf023,0xf024,0xf025,0xf026,0xf027,
+ 0xf028,0xf029,0xf02a,0xf02b,0xf02c,0xf02d,0xf02e,0xf02f,
+ 0xf030,0xf031,0xf032,0xf033,0xf034,0xf035,0xf036,0xf037,
+ 0xf038,0xf039,0xf03a,0xf03b,0xf03c,0xf03d,0xf03e,0xf03f,
+ 0xf040,0xf041,0xf042,0xf043,0xf044,0xf045,0xf046,0xf047,
+ 0xf048,0xf049,0xf04a,0xf04b,0xf04c,0xf04d,0xf04e,0xf04f,
+ 0xf050,0xf051,0xf052,0xf053,0xf054,0xf055,0xf056,0xf057,
+ 0xf058,0xf059,0xf05a,0xf05b,0xf05c,0xf05d,0xf05e,0xf05f,
+ 0xf060,0xf061,0xf062,0xf063,0xf064,0xf065,0xf066,0xf067,
+ 0xf068,0xf069,0xf06a,0xf06b,0xf06c,0xf06d,0xf06e,0xf06f,
+ 0xf070,0xf071,0xf072,0xf073,0xf074,0xf075,0xf076,0xf077,
+ 0xf078,0xf079,0xf07a,0xf07b,0xf07c,0xf07d,0xf07e,0xf07f,
+ 0xf080,0xf081,0xf082,0xf083,0xf084,0xf085,0xf086,0xf087,
+ 0xf088,0xf089,0xf08a,0xf08b,0xf08c,0xf08d,0xf08e,0xf08f,
+ 0xf090,0xf091,0xf092,0xf093,0xf094,0xf095,0xf096,0xf097,
+ 0xf098,0xf099,0xf09a,0xf09b,0xf09c,0xf09d,0xf09e,0xf09f,
+ 0xf0a0,0xf0a1,0xf0a2,0xf0a3,0xf0a4,0xf0a5,0xf0a6,0xf0a7,
+ 0xf0a8,0xf0a9,0xf0aa,0xf0ab,0xf0ac,0xf0ad,0xf0ae,0xf0af,
+ 0xf0b0,0xf0b1,0xf0b2,0xf0b3,0xf0b4,0xf0b5,0xf0b6,0xf0b7,
+ 0xf0b8,0xf0b9,0xf0ba,0xf0bb,0xf0bc,0xf0bd,0xf0be,0xf0bf,
+ 0xf0c0,0xf0c1,0xf0c2,0xf0c3,0xf0c4,0xf0c5,0xf0c6,0xf0c7,
+ 0xf0c8,0xf0c9,0xf0ca,0xf0cb,0xf0cc,0xf0cd,0xf0ce,0xf0cf,
+ 0xf0d0,0xf0d1,0xf0d2,0xf0d3,0xf0d4,0xf0d5,0xf0d6,0xf0d7,
+ 0xf0d8,0xf0d9,0xf0da,0xf0db,0xf0dc,0xf0dd,0xf0de,0xf0df,
+ 0xf0e0,0xf0e1,0xf0e2,0xf0e3,0xf0e4,0xf0e5,0xf0e6,0xf0e7,
+ 0xf0e8,0xf0e9,0xf0ea,0xf0eb,0xf0ec,0xf0ed,0xf0ee,0xf0ef,
+ 0xf0f0,0xf0f1,0xf0f2,0xf0f3,0xf0f4,0xf0f5,0xf0f6,0xf0f7,
+ 0xf0f8,0xf0f9,0xf0fa,0xf0fb,0xf0fc,0xf0fd,0xf0fe,0xf0ff,
+ 0xf100,0xf101,0xf102,0xf103,0xf104,0xf105,0xf106,0xf107,
+ 0xf108,0xf109,0xf10a,0xf10b,0xf10c,0xf10d,0xf10e,0xf10f,
+ 0xf110,0xf111,0xf112,0xf113,0xf114,0xf115,0xf116,0xf117,
+ 0xf118,0xf119,0xf11a,0xf11b,0xf11c,0xf11d,0xf11e,0xf11f,
+ 0xf120,0xf121,0xf122,0xf123,0xf124,0xf125,0xf126,0xf127,
+ 0xf128,0xf129,0xf12a,0xf12b,0xf12c,0xf12d,0xf12e,0xf12f,
+ 0xf130,0xf131,0xf132,0xf133,0xf134,0xf135,0xf136,0xf137,
+ 0xf138,0xf139,0xf13a,0xf13b,0xf13c,0xf13d,0xf13e,0xf13f,
+ 0xf140,0xf141,0xf142,0xf143,0xf144,0xf145,0xf146,0xf147,
+ 0xf148,0xf149,0xf14a,0xf14b,0xf14c,0xf14d,0xf14e,0xf14f,
+ 0xf150,0xf151,0xf152,0xf153,0xf154,0xf155,0xf156,0xf157,
+ 0xf158,0xf159,0xf15a,0xf15b,0xf15c,0xf15d,0xf15e,0xf15f,
+ 0xf160,0xf161,0xf162,0xf163,0xf164,0xf165,0xf166,0xf167,
+ 0xf168,0xf169,0xf16a,0xf16b,0xf16c,0xf16d,0xf16e,0xf16f,
+ 0xf170,0xf171,0xf172,0xf173,0xf174,0xf175,0xf176,0xf177,
+ 0xf178,0xf179,0xf17a,0xf17b,0xf17c,0xf17d,0xf17e,0xf17f,
+ 0xf180,0xf181,0xf182,0xf183,0xf184,0xf185,0xf186,0xf187,
+ 0xf188,0xf189,0xf18a,0xf18b,0xf18c,0xf18d,0xf18e,0xf18f,
+ 0xf190,0xf191,0xf192,0xf193,0xf194,0xf195,0xf196,0xf197,
+ 0xf198,0xf199,0xf19a,0xf19b,0xf19c,0xf19d,0xf19e,0xf19f,
+ 0xf1a0,0xf1a1,0xf1a2,0xf1a3,0xf1a4,0xf1a5,0xf1a6,0xf1a7,
+ 0xf1a8,0xf1a9,0xf1aa,0xf1ab,0xf1ac,0xf1ad,0xf1ae,0xf1af,
+ 0xf1b0,0xf1b1,0xf1b2,0xf1b3,0xf1b4,0xf1b5,0xf1b6,0xf1b7,
+ 0xf1b8,0xf1b9,0xf1ba,0xf1bb,0xf1bc,0xf1bd,0xf1be,0xf1bf,
+ 0xf1c0,0xf1c1,0xf1c2,0xf1c3,0xf1c4,0xf1c5,0xf1c6,0xf1c7,
+ 0xf1c8,0xf1c9,0xf1ca,0xf1cb,0xf1cc,0xf1cd,0xf1ce,0xf1cf,
+ 0xf1d0,0xf1d1,0xf1d2,0xf1d3,0xf1d4,0xf1d5,0xf1d6,0xf1d7,
+ 0xf1d8,0xf1d9,0xf1da,0xf1db,0xf1dc,0xf1dd,0xf1de,0xf1df,
+ 0xf1e0,0xf1e1,0xf1e2,0xf1e3,0xf1e4,0xf1e5,0xf1e6,0xf1e7,
+ 0xf1e8,0xf1e9,0xf1ea,0xf1eb,0xf1ec,0xf1ed,0xf1ee,0xf1ef,
+ 0xf1f0,0xf1f1,0xf1f2,0xf1f3,0xf1f4,0xf1f5,0xf1f6,0xf1f7,
+ 0xf1f8,0xf1f9,0xf1fa,0xf1fb,0xf1fc,0xf1fd,0xf1fe,0xf1ff,
+ 0xf200,0xf201,0xf202,0xf203,0xf204,0xf205,0xf206,0xf207,
+ 0xf208,0xf209,0xf20a,0xf20b,0xf20c,0xf20d,0xf20e,0xf20f,
+ 0xf210,0xf211,0xf212,0xf213,0xf214,0xf215,0xf216,0xf217,
+ 0xf218,0xf219,0xf21a,0xf21b,0xf21c,0xf21d,0xf21e,0xf21f,
+ 0xf220,0xf221,0xf222,0xf223,0xf224,0xf225,0xf226,0xf227,
+ 0xf228,0xf229,0xf22a,0xf22b,0xf22c,0xf22d,0xf22e,0xf22f,
+ 0xf230,0xf231,0xf232,0xf233,0xf234,0xf235,0xf236,0xf237,
+ 0xf238,0xf239,0xf23a,0xf23b,0xf23c,0xf23d,0xf23e,0xf23f,
+ 0xf240,0xf241,0xf242,0xf243,0xf244,0xf245,0xf246,0xf247,
+ 0xf248,0xf249,0xf24a,0xf24b,0xf24c,0xf24d,0xf24e,0xf24f,
+ 0xf250,0xf251,0xf252,0xf253,0xf254,0xf255,0xf256,0xf257,
+ 0xf258,0xf259,0xf25a,0xf25b,0xf25c,0xf25d,0xf25e,0xf25f,
+ 0xf260,0xf261,0xf262,0xf263,0xf264,0xf265,0xf266,0xf267,
+ 0xf268,0xf269,0xf26a,0xf26b,0xf26c,0xf26d,0xf26e,0xf26f,
+ 0xf270,0xf271,0xf272,0xf273,0xf274,0xf275,0xf276,0xf277,
+ 0xf278,0xf279,0xf27a,0xf27b,0xf27c,0xf27d,0xf27e,0xf27f,
+ 0xf280,0xf281,0xf282,0xf283,0xf284,0xf285,0xf286,0xf287,
+ 0xf288,0xf289,0xf28a,0xf28b,0xf28c,0xf28d,0xf28e,0xf28f,
+ 0xf290,0xf291,0xf292,0xf293,0xf294,0xf295,0xf296,0xf297,
+ 0xf298,0xf299,0xf29a,0xf29b,0xf29c,0xf29d,0xf29e,0xf29f,
+ 0xf2a0,0xf2a1,0xf2a2,0xf2a3,0xf2a4,0xf2a5,0xf2a6,0xf2a7,
+ 0xf2a8,0xf2a9,0xf2aa,0xf2ab,0xf2ac,0xf2ad,0xf2ae,0xf2af,
+ 0xf2b0,0xf2b1,0xf2b2,0xf2b3,0xf2b4,0xf2b5,0xf2b6,0xf2b7,
+ 0xf2b8,0xf2b9,0xf2ba,0xf2bb,0xf2bc,0xf2bd,0xf2be,0xf2bf,
+ 0xf2c0,0xf2c1,0xf2c2,0xf2c3,0xf2c4,0xf2c5,0xf2c6,0xf2c7,
+ 0xf2c8,0xf2c9,0xf2ca,0xf2cb,0xf2cc,0xf2cd,0xf2ce,0xf2cf,
+ 0xf2d0,0xf2d1,0xf2d2,0xf2d3,0xf2d4,0xf2d5,0xf2d6,0xf2d7,
+ 0xf2d8,0xf2d9,0xf2da,0xf2db,0xf2dc,0xf2dd,0xf2de,0xf2df,
+ 0xf2e0,0xf2e1,0xf2e2,0xf2e3,0xf2e4,0xf2e5,0xf2e6,0xf2e7,
+ 0xf2e8,0xf2e9,0xf2ea,0xf2eb,0xf2ec,0xf2ed,0xf2ee,0xf2ef,
+ 0xf2f0,0xf2f1,0xf2f2,0xf2f3,0xf2f4,0xf2f5,0xf2f6,0xf2f7,
+ 0xf2f8,0xf2f9,0xf2fa,0xf2fb,0xf2fc,0xf2fd,0xf2fe,0xf2ff,
+ 0xf300,0xf301,0xf302,0xf303,0xf304,0xf305,0xf306,0xf307,
+ 0xf308,0xf309,0xf30a,0xf30b,0xf30c,0xf30d,0xf30e,0xf30f,
+ 0xf310,0xf311,0xf312,0xf313,0xf314,0xf315,0xf316,0xf317,
+ 0xf318,0xf319,0xf31a,0xf31b,0xf31c,0xf31d,0xf31e,0xf31f,
+ 0xf320,0xf321,0xf322,0xf323,0xf324,0xf325,0xf326,0xf327,
+ 0xf328,0xf329,0xf32a,0xf32b,0xf32c,0xf32d,0xf32e,0xf32f,
+ 0xf330,0xf331,0xf332,0xf333,0xf334,0xf335,0xf336,0xf337,
+ 0xf338,0xf339,0xf33a,0xf33b,0xf33c,0xf33d,0xf33e,0xf33f,
+ 0xf340,0xf341,0xf342,0xf343,0xf344,0xf345,0xf346,0xf347,
+ 0xf348,0xf349,0xf34a,0xf34b,0xf34c,0xf34d,0xf34e,0xf34f,
+ 0xf350,0xf351,0xf352,0xf353,0xf354,0xf355,0xf356,0xf357,
+ 0xf358,0xf359,0xf35a,0xf35b,0xf35c,0xf35d,0xf35e,0xf35f,
+ 0xf360,0xf361,0xf362,0xf363,0xf364,0xf365,0xf366,0xf367,
+ 0xf368,0xf369,0xf36a,0xf36b,0xf36c,0xf36d,0xf36e,0xf36f,
+ 0xf370,0xf371,0xf372,0xf373,0xf374,0xf375,0xf376,0xf377,
+ 0xf378,0xf379,0xf37a,0xf37b,0xf37c,0xf37d,0xf37e,0xf37f,
+ 0xf380,0xf381,0xf382,0xf383,0xf384,0xf385,0xf386,0xf387,
+ 0xf388,0xf389,0xf38a,0xf38b,0xf38c,0xf38d,0xf38e,0xf38f,
+ 0xf390,0xf391,0xf392,0xf393,0xf394,0xf395,0xf396,0xf397,
+ 0xf398,0xf399,0xf39a,0xf39b,0xf39c,0xf39d,0xf39e,0xf39f,
+ 0xf3a0,0xf3a1,0xf3a2,0xf3a3,0xf3a4,0xf3a5,0xf3a6,0xf3a7,
+ 0xf3a8,0xf3a9,0xf3aa,0xf3ab,0xf3ac,0xf3ad,0xf3ae,0xf3af,
+ 0xf3b0,0xf3b1,0xf3b2,0xf3b3,0xf3b4,0xf3b5,0xf3b6,0xf3b7,
+ 0xf3b8,0xf3b9,0xf3ba,0xf3bb,0xf3bc,0xf3bd,0xf3be,0xf3bf,
+ 0xf3c0,0xf3c1,0xf3c2,0xf3c3,0xf3c4,0xf3c5,0xf3c6,0xf3c7,
+ 0xf3c8,0xf3c9,0xf3ca,0xf3cb,0xf3cc,0xf3cd,0xf3ce,0xf3cf,
+ 0xf3d0,0xf3d1,0xf3d2,0xf3d3,0xf3d4,0xf3d5,0xf3d6,0xf3d7,
+ 0xf3d8,0xf3d9,0xf3da,0xf3db,0xf3dc,0xf3dd,0xf3de,0xf3df,
+ 0xf3e0,0xf3e1,0xf3e2,0xf3e3,0xf3e4,0xf3e5,0xf3e6,0xf3e7,
+ 0xf3e8,0xf3e9,0xf3ea,0xf3eb,0xf3ec,0xf3ed,0xf3ee,0xf3ef,
+ 0xf3f0,0xf3f1,0xf3f2,0xf3f3,0xf3f4,0xf3f5,0xf3f6,0xf3f7,
+ 0xf3f8,0xf3f9,0xf3fa,0xf3fb,0xf3fc,0xf3fd,0xf3fe,0xf3ff,
+ 0xf400,0xf401,0xf402,0xf403,0xf404,0xf405,0xf406,0xf407,
+ 0xf408,0xf409,0xf40a,0xf40b,0xf40c,0xf40d,0xf40e,0xf40f,
+ 0xf410,0xf411,0xf412,0xf413,0xf414,0xf415,0xf416,0xf417,
+ 0xf418,0xf419,0xf41a,0xf41b,0xf41c,0xf41d,0xf41e,0xf41f,
+ 0xf420,0xf421,0xf422,0xf423,0xf424,0xf425,0xf426,0xf427,
+ 0xf428,0xf429,0xf42a,0xf42b,0xf42c,0xf42d,0xf42e,0xf42f,
+ 0xf430,0xf431,0xf432,0xf433,0xf434,0xf435,0xf436,0xf437,
+ 0xf438,0xf439,0xf43a,0xf43b,0xf43c,0xf43d,0xf43e,0xf43f,
+ 0xf440,0xf441,0xf442,0xf443,0xf444,0xf445,0xf446,0xf447,
+ 0xf448,0xf449,0xf44a,0xf44b,0xf44c,0xf44d,0xf44e,0xf44f,
+ 0xf450,0xf451,0xf452,0xf453,0xf454,0xf455,0xf456,0xf457,
+ 0xf458,0xf459,0xf45a,0xf45b,0xf45c,0xf45d,0xf45e,0xf45f,
+ 0xf460,0xf461,0xf462,0xf463,0xf464,0xf465,0xf466,0xf467,
+ 0xf468,0xf469,0xf46a,0xf46b,0xf46c,0xf46d,0xf46e,0xf46f,
+ 0xf470,0xf471,0xf472,0xf473,0xf474,0xf475,0xf476,0xf477,
+ 0xf478,0xf479,0xf47a,0xf47b,0xf47c,0xf47d,0xf47e,0xf47f,
+ 0xf480,0xf481,0xf482,0xf483,0xf484,0xf485,0xf486,0xf487,
+ 0xf488,0xf489,0xf48a,0xf48b,0xf48c,0xf48d,0xf48e,0xf48f,
+ 0xf490,0xf491,0xf492,0xf493,0xf494,0xf495,0xf496,0xf497,
+ 0xf498,0xf499,0xf49a,0xf49b,0xf49c,0xf49d,0xf49e,0xf49f,
+ 0xf4a0,0xf4a1,0xf4a2,0xf4a3,0xf4a4,0xf4a5,0xf4a6,0xf4a7,
+ 0xf4a8,0xf4a9,0xf4aa,0xf4ab,0xf4ac,0xf4ad,0xf4ae,0xf4af,
+ 0xf4b0,0xf4b1,0xf4b2,0xf4b3,0xf4b4,0xf4b5,0xf4b6,0xf4b7,
+ 0xf4b8,0xf4b9,0xf4ba,0xf4bb,0xf4bc,0xf4bd,0xf4be,0xf4bf,
+ 0xf4c0,0xf4c1,0xf4c2,0xf4c3,0xf4c4,0xf4c5,0xf4c6,0xf4c7,
+ 0xf4c8,0xf4c9,0xf4ca,0xf4cb,0xf4cc,0xf4cd,0xf4ce,0xf4cf,
+ 0xf4d0,0xf4d1,0xf4d2,0xf4d3,0xf4d4,0xf4d5,0xf4d6,0xf4d7,
+ 0xf4d8,0xf4d9,0xf4da,0xf4db,0xf4dc,0xf4dd,0xf4de,0xf4df,
+ 0xf4e0,0xf4e1,0xf4e2,0xf4e3,0xf4e4,0xf4e5,0xf4e6,0xf4e7,
+ 0xf4e8,0xf4e9,0xf4ea,0xf4eb,0xf4ec,0xf4ed,0xf4ee,0xf4ef,
+ 0xf4f0,0xf4f1,0xf4f2,0xf4f3,0xf4f4,0xf4f5,0xf4f6,0xf4f7,
+ 0xf4f8,0xf4f9,0xf4fa,0xf4fb,0xf4fc,0xf4fd,0xf4fe,0xf4ff,
+ 0xf500,0xf501,0xf502,0xf503,0xf504,0xf505,0xf506,0xf507,
+ 0xf508,0xf509,0xf50a,0xf50b,0xf50c,0xf50d,0xf50e,0xf50f,
+ 0xf510,0xf511,0xf512,0xf513,0xf514,0xf515,0xf516,0xf517,
+ 0xf518,0xf519,0xf51a,0xf51b,0xf51c,0xf51d,0xf51e,0xf51f,
+ 0xf520,0xf521,0xf522,0xf523,0xf524,0xf525,0xf526,0xf527,
+ 0xf528,0xf529,0xf52a,0xf52b,0xf52c,0xf52d,0xf52e,0xf52f,
+ 0xf530,0xf531,0xf532,0xf533,0xf534,0xf535,0xf536,0xf537,
+ 0xf538,0xf539,0xf53a,0xf53b,0xf53c,0xf53d,0xf53e,0xf53f,
+ 0xf540,0xf541,0xf542,0xf543,0xf544,0xf545,0xf546,0xf547,
+ 0xf548,0xf549,0xf54a,0xf54b,0xf54c,0xf54d,0xf54e,0xf54f,
+ 0xf550,0xf551,0xf552,0xf553,0xf554,0xf555,0xf556,0xf557,
+ 0xf558,0xf559,0xf55a,0xf55b,0xf55c,0xf55d,0xf55e,0xf55f,
+ 0xf560,0xf561,0xf562,0xf563,0xf564,0xf565,0xf566,0xf567,
+ 0xf568,0xf569,0xf56a,0xf56b,0xf56c,0xf56d,0xf56e,0xf56f,
+ 0xf570,0xf571,0xf572,0xf573,0xf574,0xf575,0xf576,0xf577,
+ 0xf578,0xf579,0xf57a,0xf57b,0xf57c,0xf57d,0xf57e,0xf57f,
+ 0xf580,0xf581,0xf582,0xf583,0xf584,0xf585,0xf586,0xf587,
+ 0xf588,0xf589,0xf58a,0xf58b,0xf58c,0xf58d,0xf58e,0xf58f,
+ 0xf590,0xf591,0xf592,0xf593,0xf594,0xf595,0xf596,0xf597,
+ 0xf598,0xf599,0xf59a,0xf59b,0xf59c,0xf59d,0xf59e,0xf59f,
+ 0xf5a0,0xf5a1,0xf5a2,0xf5a3,0xf5a4,0xf5a5,0xf5a6,0xf5a7,
+ 0xf5a8,0xf5a9,0xf5aa,0xf5ab,0xf5ac,0xf5ad,0xf5ae,0xf5af,
+ 0xf5b0,0xf5b1,0xf5b2,0xf5b3,0xf5b4,0xf5b5,0xf5b6,0xf5b7,
+ 0xf5b8,0xf5b9,0xf5ba,0xf5bb,0xf5bc,0xf5bd,0xf5be,0xf5bf,
+ 0xf5c0,0xf5c1,0xf5c2,0xf5c3,0xf5c4,0xf5c5,0xf5c6,0xf5c7,
+ 0xf5c8,0xf5c9,0xf5ca,0xf5cb,0xf5cc,0xf5cd,0xf5ce,0xf5cf,
+ 0xf5d0,0xf5d1,0xf5d2,0xf5d3,0xf5d4,0xf5d5,0xf5d6,0xf5d7,
+ 0xf5d8,0xf5d9,0xf5da,0xf5db,0xf5dc,0xf5dd,0xf5de,0xf5df,
+ 0xf5e0,0xf5e1,0xf5e2,0xf5e3,0xf5e4,0xf5e5,0xf5e6,0xf5e7,
+ 0xf5e8,0xf5e9,0xf5ea,0xf5eb,0xf5ec,0xf5ed,0xf5ee,0xf5ef,
+ 0xf5f0,0xf5f1,0xf5f2,0xf5f3,0xf5f4,0xf5f5,0xf5f6,0xf5f7,
+ 0xf5f8,0xf5f9,0xf5fa,0xf5fb,0xf5fc,0xf5fd,0xf5fe,0xf5ff,
+ 0xf600,0xf601,0xf602,0xf603,0xf604,0xf605,0xf606,0xf607,
+ 0xf608,0xf609,0xf60a,0xf60b,0xf60c,0xf60d,0xf60e,0xf60f,
+ 0xf610,0xf611,0xf612,0xf613,0xf614,0xf615,0xf616,0xf617,
+ 0xf618,0xf619,0xf61a,0xf61b,0xf61c,0xf61d,0xf61e,0xf61f,
+ 0xf620,0xf621,0xf622,0xf623,0xf624,0xf625,0xf626,0xf627,
+ 0xf628,0xf629,0xf62a,0xf62b,0xf62c,0xf62d,0xf62e,0xf62f,
+ 0xf630,0xf631,0xf632,0xf633,0xf634,0xf635,0xf636,0xf637,
+ 0xf638,0xf639,0xf63a,0xf63b,0xf63c,0xf63d,0xf63e,0xf63f,
+ 0xf640,0xf641,0xf642,0xf643,0xf644,0xf645,0xf646,0xf647,
+ 0xf648,0xf649,0xf64a,0xf64b,0xf64c,0xf64d,0xf64e,0xf64f,
+ 0xf650,0xf651,0xf652,0xf653,0xf654,0xf655,0xf656,0xf657,
+ 0xf658,0xf659,0xf65a,0xf65b,0xf65c,0xf65d,0xf65e,0xf65f,
+ 0xf660,0xf661,0xf662,0xf663,0xf664,0xf665,0xf666,0xf667,
+ 0xf668,0xf669,0xf66a,0xf66b,0xf66c,0xf66d,0xf66e,0xf66f,
+ 0xf670,0xf671,0xf672,0xf673,0xf674,0xf675,0xf676,0xf677,
+ 0xf678,0xf679,0xf67a,0xf67b,0xf67c,0xf67d,0xf67e,0xf67f,
+ 0xf680,0xf681,0xf682,0xf683,0xf684,0xf685,0xf686,0xf687,
+ 0xf688,0xf689,0xf68a,0xf68b,0xf68c,0xf68d,0xf68e,0xf68f,
+ 0xf690,0xf691,0xf692,0xf693,0xf694,0xf695,0xf696,0xf697,
+ 0xf698,0xf699,0xf69a,0xf69b,0xf69c,0xf69d,0xf69e,0xf69f,
+ 0xf6a0,0xf6a1,0xf6a2,0xf6a3,0xf6a4,0xf6a5,0xf6a6,0xf6a7,
+ 0xf6a8,0xf6a9,0xf6aa,0xf6ab,0xf6ac,0xf6ad,0xf6ae,0xf6af,
+ 0xf6b0,0xf6b1,0xf6b2,0xf6b3,0xf6b4,0xf6b5,0xf6b6,0xf6b7,
+ 0xf6b8,0xf6b9,0xf6ba,0xf6bb,0xf6bc,0xf6bd,0xf6be,0xf6bf,
+ 0xf6c0,0xf6c1,0xf6c2,0xf6c3,0xf6c4,0xf6c5,0xf6c6,0xf6c7,
+ 0xf6c8,0xf6c9,0xf6ca,0xf6cb,0xf6cc,0xf6cd,0xf6ce,0xf6cf,
+ 0xf6d0,0xf6d1,0xf6d2,0xf6d3,0xf6d4,0xf6d5,0xf6d6,0xf6d7,
+ 0xf6d8,0xf6d9,0xf6da,0xf6db,0xf6dc,0xf6dd,0xf6de,0xf6df,
+ 0xf6e0,0xf6e1,0xf6e2,0xf6e3,0xf6e4,0xf6e5,0xf6e6,0xf6e7,
+ 0xf6e8,0xf6e9,0xf6ea,0xf6eb,0xf6ec,0xf6ed,0xf6ee,0xf6ef,
+ 0xf6f0,0xf6f1,0xf6f2,0xf6f3,0xf6f4,0xf6f5,0xf6f6,0xf6f7,
+ 0xf6f8,0xf6f9,0xf6fa,0xf6fb,0xf6fc,0xf6fd,0xf6fe,0xf6ff,
+ 0xf700,0xf701,0xf702,0xf703,0xf704,0xf705,0xf706,0xf707,
+ 0xf708,0xf709,0xf70a,0xf70b,0xf70c,0xf70d,0xf70e,0xf70f,
+ 0xf710,0xf711,0xf712,0xf713,0xf714,0xf715,0xf716,0xf717,
+ 0xf718,0xf719,0xf71a,0xf71b,0xf71c,0xf71d,0xf71e,0xf71f,
+ 0xf720,0xf721,0xf722,0xf723,0xf724,0xf725,0xf726,0xf727,
+ 0xf728,0xf729,0xf72a,0xf72b,0xf72c,0xf72d,0xf72e,0xf72f,
+ 0xf730,0xf731,0xf732,0xf733,0xf734,0xf735,0xf736,0xf737,
+ 0xf738,0xf739,0xf73a,0xf73b,0xf73c,0xf73d,0xf73e,0xf73f,
+ 0xf740,0xf741,0xf742,0xf743,0xf744,0xf745,0xf746,0xf747,
+ 0xf748,0xf749,0xf74a,0xf74b,0xf74c,0xf74d,0xf74e,0xf74f,
+ 0xf750,0xf751,0xf752,0xf753,0xf754,0xf755,0xf756,0xf757,
+ 0xf758,0xf759,0xf75a,0xf75b,0xf75c,0xf75d,0xf75e,0xf75f,
+ 0xf760,0xf761,0xf762,0xf763,0xf764,0xf765,0xf766,0xf767,
+ 0xf768,0xf769,0xf76a,0xf76b,0xf76c,0xf76d,0xf76e,0xf76f,
+ 0xf770,0xf771,0xf772,0xf773,0xf774,0xf775,0xf776,0xf777,
+ 0xf778,0xf779,0xf77a,0xf77b,0xf77c,0xf77d,0xf77e,0xf77f,
+ 0xf780,0xf781,0xf782,0xf783,0xf784,0xf785,0xf786,0xf787,
+ 0xf788,0xf789,0xf78a,0xf78b,0xf78c,0xf78d,0xf78e,0xf78f,
+ 0xf790,0xf791,0xf792,0xf793,0xf794,0xf795,0xf796,0xf797,
+ 0xf798,0xf799,0xf79a,0xf79b,0xf79c,0xf79d,0xf79e,0xf79f,
+ 0xf7a0,0xf7a1,0xf7a2,0xf7a3,0xf7a4,0xf7a5,0xf7a6,0xf7a7,
+ 0xf7a8,0xf7a9,0xf7aa,0xf7ab,0xf7ac,0xf7ad,0xf7ae,0xf7af,
+ 0xf7b0,0xf7b1,0xf7b2,0xf7b3,0xf7b4,0xf7b5,0xf7b6,0xf7b7,
+ 0xf7b8,0xf7b9,0xf7ba,0xf7bb,0xf7bc,0xf7bd,0xf7be,0xf7bf,
+ 0xf7c0,0xf7c1,0xf7c2,0xf7c3,0xf7c4,0xf7c5,0xf7c6,0xf7c7,
+ 0xf7c8,0xf7c9,0xf7ca,0xf7cb,0xf7cc,0xf7cd,0xf7ce,0xf7cf,
+ 0xf7d0,0xf7d1,0xf7d2,0xf7d3,0xf7d4,0xf7d5,0xf7d6,0xf7d7,
+ 0xf7d8,0xf7d9,0xf7da,0xf7db,0xf7dc,0xf7dd,0xf7de,0xf7df,
+ 0xf7e0,0xf7e1,0xf7e2,0xf7e3,0xf7e4,0xf7e5,0xf7e6,0xf7e7,
+ 0xf7e8,0xf7e9,0xf7ea,0xf7eb,0xf7ec,0xf7ed,0xf7ee,0xf7ef,
+ 0xf7f0,0xf7f1,0xf7f2,0xf7f3,0xf7f4,0xf7f5,0xf7f6,0xf7f7,
+ 0xf7f8,0xf7f9,0xf7fa,0xf7fb,0xf7fc,0xf7fd,0xf7fe,0xf7ff,
+ 0xf800,0xf801,0xf802,0xf803,0xf804,0xf805,0xf806,0xf807,
+ 0xf808,0xf809,0xf80a,0xf80b,0xf80c,0xf80d,0xf80e,0xf80f,
+ 0xf810,0xf811,0xf812,0xf813,0xf814,0xf815,0xf816,0xf817,
+ 0xf818,0xf819,0xf81a,0xf81b,0xf81c,0xf81d,0xf81e,0xf81f,
+ 0xf820,0xf821,0xf822,0xf823,0xf824,0xf825,0xf826,0xf827,
+ 0xf828,0xf829,0xf82a,0xf82b,0xf82c,0xf82d,0xf82e,0xf82f,
+ 0xf830,0xf831,0xf832,0xf833,0xf834,0xf835,0xf836,0xf837,
+ 0xf838,0xf839,0xf83a,0xf83b,0xf83c,0xf83d,0xf83e,0xf83f,
+ 0xf840,0xf841,0xf842,0xf843,0xf844,0xf845,0xf846,0xf847,
+ 0xf848,0xf849,0xf84a,0xf84b,0xf84c,0xf84d,0xf84e,0xf84f,
+ 0xf850,0xf851,0xf852,0xf853,0xf854,0xf855,0xf856,0xf857,
+ 0xf858,0xf859,0xf85a,0xf85b,0xf85c,0xf85d,0xf85e,0xf85f,
+ 0xf860,0xf861,0xf862,0xf863,0xf864,0xf865,0xf866,0xf867,
+ 0xf868,0xf869,0xf86a,0xf86b,0xf86c,0xf86d,0xf86e,0xf86f,
+ 0xf870,0xf871,0xf872,0xf873,0xf874,0xf875,0xf876,0xf877,
+ 0xf878,0xf879,0xf87a,0xf87b,0xf87c,0xf87d,0xf87e,0xf87f,
+ 0xf880,0xf881,0xf882,0xf883,0xf884,0xf885,0xf886,0xf887,
+ 0xf888,0xf889,0xf88a,0xf88b,0xf88c,0xf88d,0xf88e,0xf88f,
+ 0xf890,0xf891,0xf892,0xf893,0xf894,0xf895,0xf896,0xf897,
+ 0xf898,0xf899,0xf89a,0xf89b,0xf89c,0xf89d,0xf89e,0xf89f,
+ 0xf8a0,0xf8a1,0xf8a2,0xf8a3,0xf8a4,0xf8a5,0xf8a6,0xf8a7,
+ 0xf8a8,0xf8a9,0xf8aa,0xf8ab,0xf8ac,0xf8ad,0xf8ae,0xf8af,
+ 0xf8b0,0xf8b1,0xf8b2,0xf8b3,0xf8b4,0xf8b5,0xf8b6,0xf8b7,
+ 0xf8b8,0xf8b9,0xf8ba,0xf8bb,0xf8bc,0xf8bd,0xf8be,0xf8bf,
+ 0xf8c0,0xf8c1,0xf8c2,0xf8c3,0xf8c4,0xf8c5,0xf8c6,0xf8c7,
+ 0xf8c8,0xf8c9,0xf8ca,0xf8cb,0xf8cc,0xf8cd,0xf8ce,0xf8cf,
+ 0xf8d0,0xf8d1,0xf8d2,0xf8d3,0xf8d4,0xf8d5,0xf8d6,0xf8d7,
+ 0xf8d8,0xf8d9,0xf8da,0xf8db,0xf8dc,0xf8dd,0xf8de,0xf8df,
+ 0xf8e0,0xf8e1,0xf8e2,0xf8e3,0xf8e4,0xf8e5,0xf8e6,0xf8e7,
+ 0xf8e8,0xf8e9,0xf8ea,0xf8eb,0xf8ec,0xf8ed,0xf8ee,0xf8ef,
+ 0xf8f0,0xf8f1,0xf8f2,0xf8f3,0xf8f4,0xf8f5,0xf8f6,0xf8f7,
+ 0xf8f8,0xf8f9,0xf8fa,0xf8fb,0xf8fc,0xf8fd,0xf8fe,0xf8ff,
+ 0xf900,0xf901,0xf902,0xf903,0xf904,0xf905,0xf906,0xf907,
+ 0xf908,0xf909,0xf90a,0xf90b,0xf90c,0xf90d,0xf90e,0xf90f,
+ 0xf910,0xf911,0xf912,0xf913,0xf914,0xf915,0xf916,0xf917,
+ 0xf918,0xf919,0xf91a,0xf91b,0xf91c,0xf91d,0xf91e,0xf91f,
+ 0xf920,0xf921,0xf922,0xf923,0xf924,0xf925,0xf926,0xf927,
+ 0xf928,0xf929,0xf92a,0xf92b,0xf92c,0xf92d,0xf92e,0xf92f,
+ 0xf930,0xf931,0xf932,0xf933,0xf934,0xf935,0xf936,0xf937,
+ 0xf938,0xf939,0xf93a,0xf93b,0xf93c,0xf93d,0xf93e,0xf93f,
+ 0xf940,0xf941,0xf942,0xf943,0xf944,0xf945,0xf946,0xf947,
+ 0xf948,0xf949,0xf94a,0xf94b,0xf94c,0xf94d,0xf94e,0xf94f,
+ 0xf950,0xf951,0xf952,0xf953,0xf954,0xf955,0xf956,0xf957,
+ 0xf958,0xf959,0xf95a,0xf95b,0xf95c,0xf95d,0xf95e,0xf95f,
+ 0xf960,0xf961,0xf962,0xf963,0xf964,0xf965,0xf966,0xf967,
+ 0xf968,0xf969,0xf96a,0xf96b,0xf96c,0xf96d,0xf96e,0xf96f,
+ 0xf970,0xf971,0xf972,0xf973,0xf974,0xf975,0xf976,0xf977,
+ 0xf978,0xf979,0xf97a,0xf97b,0xf97c,0xf97d,0xf97e,0xf97f,
+ 0xf980,0xf981,0xf982,0xf983,0xf984,0xf985,0xf986,0xf987,
+ 0xf988,0xf989,0xf98a,0xf98b,0xf98c,0xf98d,0xf98e,0xf98f,
+ 0xf990,0xf991,0xf992,0xf993,0xf994,0xf995,0xf996,0xf997,
+ 0xf998,0xf999,0xf99a,0xf99b,0xf99c,0xf99d,0xf99e,0xf99f,
+ 0xf9a0,0xf9a1,0xf9a2,0xf9a3,0xf9a4,0xf9a5,0xf9a6,0xf9a7,
+ 0xf9a8,0xf9a9,0xf9aa,0xf9ab,0xf9ac,0xf9ad,0xf9ae,0xf9af,
+ 0xf9b0,0xf9b1,0xf9b2,0xf9b3,0xf9b4,0xf9b5,0xf9b6,0xf9b7,
+ 0xf9b8,0xf9b9,0xf9ba,0xf9bb,0xf9bc,0xf9bd,0xf9be,0xf9bf,
+ 0xf9c0,0xf9c1,0xf9c2,0xf9c3,0xf9c4,0xf9c5,0xf9c6,0xf9c7,
+ 0xf9c8,0xf9c9,0xf9ca,0xf9cb,0xf9cc,0xf9cd,0xf9ce,0xf9cf,
+ 0xf9d0,0xf9d1,0xf9d2,0xf9d3,0xf9d4,0xf9d5,0xf9d6,0xf9d7,
+ 0xf9d8,0xf9d9,0xf9da,0xf9db,0xf9dc,0xf9dd,0xf9de,0xf9df,
+ 0xf9e0,0xf9e1,0xf9e2,0xf9e3,0xf9e4,0xf9e5,0xf9e6,0xf9e7,
+ 0xf9e8,0xf9e9,0xf9ea,0xf9eb,0xf9ec,0xf9ed,0xf9ee,0xf9ef,
+ 0xf9f0,0xf9f1,0xf9f2,0xf9f3,0xf9f4,0xf9f5,0xf9f6,0xf9f7,
+ 0xf9f8,0xf9f9,0xf9fa,0xf9fb,0xf9fc,0xf9fd,0xf9fe,0xf9ff,
+ 0xfa00,0xfa01,0xfa02,0xfa03,0xfa04,0xfa05,0xfa06,0xfa07,
+ 0xfa08,0xfa09,0xfa0a,0xfa0b,0xfa0c,0xfa0d,0xfa0e,0xfa0f,
+ 0xfa10,0xfa11,0xfa12,0xfa13,0xfa14,0xfa15,0xfa16,0xfa17,
+ 0xfa18,0xfa19,0xfa1a,0xfa1b,0xfa1c,0xfa1d,0xfa1e,0xfa1f,
+ 0xfa20,0xfa21,0xfa22,0xfa23,0xfa24,0xfa25,0xfa26,0xfa27,
+ 0xfa28,0xfa29,0xfa2a,0xfa2b,0xfa2c,0xfa2d,0xfa2e,0xfa2f,
+ 0xfa30,0xfa31,0xfa32,0xfa33,0xfa34,0xfa35,0xfa36,0xfa37,
+ 0xfa38,0xfa39,0xfa3a,0xfa3b,0xfa3c,0xfa3d,0xfa3e,0xfa3f,
+ 0xfa40,0xfa41,0xfa42,0xfa43,0xfa44,0xfa45,0xfa46,0xfa47,
+ 0xfa48,0xfa49,0xfa4a,0xfa4b,0xfa4c,0xfa4d,0xfa4e,0xfa4f,
+ 0xfa50,0xfa51,0xfa52,0xfa53,0xfa54,0xfa55,0xfa56,0xfa57,
+ 0xfa58,0xfa59,0xfa5a,0xfa5b,0xfa5c,0xfa5d,0xfa5e,0xfa5f,
+ 0xfa60,0xfa61,0xfa62,0xfa63,0xfa64,0xfa65,0xfa66,0xfa67,
+ 0xfa68,0xfa69,0xfa6a,0xfa6b,0xfa6c,0xfa6d,0xfa6e,0xfa6f,
+ 0xfa70,0xfa71,0xfa72,0xfa73,0xfa74,0xfa75,0xfa76,0xfa77,
+ 0xfa78,0xfa79,0xfa7a,0xfa7b,0xfa7c,0xfa7d,0xfa7e,0xfa7f,
+ 0xfa80,0xfa81,0xfa82,0xfa83,0xfa84,0xfa85,0xfa86,0xfa87,
+ 0xfa88,0xfa89,0xfa8a,0xfa8b,0xfa8c,0xfa8d,0xfa8e,0xfa8f,
+ 0xfa90,0xfa91,0xfa92,0xfa93,0xfa94,0xfa95,0xfa96,0xfa97,
+ 0xfa98,0xfa99,0xfa9a,0xfa9b,0xfa9c,0xfa9d,0xfa9e,0xfa9f,
+ 0xfaa0,0xfaa1,0xfaa2,0xfaa3,0xfaa4,0xfaa5,0xfaa6,0xfaa7,
+ 0xfaa8,0xfaa9,0xfaaa,0xfaab,0xfaac,0xfaad,0xfaae,0xfaaf,
+ 0xfab0,0xfab1,0xfab2,0xfab3,0xfab4,0xfab5,0xfab6,0xfab7,
+ 0xfab8,0xfab9,0xfaba,0xfabb,0xfabc,0xfabd,0xfabe,0xfabf,
+ 0xfac0,0xfac1,0xfac2,0xfac3,0xfac4,0xfac5,0xfac6,0xfac7,
+ 0xfac8,0xfac9,0xfaca,0xfacb,0xfacc,0xfacd,0xface,0xfacf,
+ 0xfad0,0xfad1,0xfad2,0xfad3,0xfad4,0xfad5,0xfad6,0xfad7,
+ 0xfad8,0xfad9,0xfada,0xfadb,0xfadc,0xfadd,0xfade,0xfadf,
+ 0xfae0,0xfae1,0xfae2,0xfae3,0xfae4,0xfae5,0xfae6,0xfae7,
+ 0xfae8,0xfae9,0xfaea,0xfaeb,0xfaec,0xfaed,0xfaee,0xfaef,
+ 0xfaf0,0xfaf1,0xfaf2,0xfaf3,0xfaf4,0xfaf5,0xfaf6,0xfaf7,
+ 0xfaf8,0xfaf9,0xfafa,0xfafb,0xfafc,0xfafd,0xfafe,0xfaff,
+ 0xfb00,0xfb01,0xfb02,0xfb03,0xfb04,0xfb05,0xfb06,0xfb07,
+ 0xfb08,0xfb09,0xfb0a,0xfb0b,0xfb0c,0xfb0d,0xfb0e,0xfb0f,
+ 0xfb10,0xfb11,0xfb12,0xfb13,0xfb14,0xfb15,0xfb16,0xfb17,
+ 0xfb18,0xfb19,0xfb1a,0xfb1b,0xfb1c,0xfb1d,0xfb1e,0xfb1f,
+ 0xfb20,0xfb21,0xfb22,0xfb23,0xfb24,0xfb25,0xfb26,0xfb27,
+ 0xfb28,0xfb29,0xfb2a,0xfb2b,0xfb2c,0xfb2d,0xfb2e,0xfb2f,
+ 0xfb30,0xfb31,0xfb32,0xfb33,0xfb34,0xfb35,0xfb36,0xfb37,
+ 0xfb38,0xfb39,0xfb3a,0xfb3b,0xfb3c,0xfb3d,0xfb3e,0xfb3f,
+ 0xfb40,0xfb41,0xfb42,0xfb43,0xfb44,0xfb45,0xfb46,0xfb47,
+ 0xfb48,0xfb49,0xfb4a,0xfb4b,0xfb4c,0xfb4d,0xfb4e,0xfb4f,
+ 0xfb50,0xfb51,0xfb52,0xfb53,0xfb54,0xfb55,0xfb56,0xfb57,
+ 0xfb58,0xfb59,0xfb5a,0xfb5b,0xfb5c,0xfb5d,0xfb5e,0xfb5f,
+ 0xfb60,0xfb61,0xfb62,0xfb63,0xfb64,0xfb65,0xfb66,0xfb67,
+ 0xfb68,0xfb69,0xfb6a,0xfb6b,0xfb6c,0xfb6d,0xfb6e,0xfb6f,
+ 0xfb70,0xfb71,0xfb72,0xfb73,0xfb74,0xfb75,0xfb76,0xfb77,
+ 0xfb78,0xfb79,0xfb7a,0xfb7b,0xfb7c,0xfb7d,0xfb7e,0xfb7f,
+ 0xfb80,0xfb81,0xfb82,0xfb83,0xfb84,0xfb85,0xfb86,0xfb87,
+ 0xfb88,0xfb89,0xfb8a,0xfb8b,0xfb8c,0xfb8d,0xfb8e,0xfb8f,
+ 0xfb90,0xfb91,0xfb92,0xfb93,0xfb94,0xfb95,0xfb96,0xfb97,
+ 0xfb98,0xfb99,0xfb9a,0xfb9b,0xfb9c,0xfb9d,0xfb9e,0xfb9f,
+ 0xfba0,0xfba1,0xfba2,0xfba3,0xfba4,0xfba5,0xfba6,0xfba7,
+ 0xfba8,0xfba9,0xfbaa,0xfbab,0xfbac,0xfbad,0xfbae,0xfbaf,
+ 0xfbb0,0xfbb1,0xfbb2,0xfbb3,0xfbb4,0xfbb5,0xfbb6,0xfbb7,
+ 0xfbb8,0xfbb9,0xfbba,0xfbbb,0xfbbc,0xfbbd,0xfbbe,0xfbbf,
+ 0xfbc0,0xfbc1,0xfbc2,0xfbc3,0xfbc4,0xfbc5,0xfbc6,0xfbc7,
+ 0xfbc8,0xfbc9,0xfbca,0xfbcb,0xfbcc,0xfbcd,0xfbce,0xfbcf,
+ 0xfbd0,0xfbd1,0xfbd2,0xfbd3,0xfbd4,0xfbd5,0xfbd6,0xfbd7,
+ 0xfbd8,0xfbd9,0xfbda,0xfbdb,0xfbdc,0xfbdd,0xfbde,0xfbdf,
+ 0xfbe0,0xfbe1,0xfbe2,0xfbe3,0xfbe4,0xfbe5,0xfbe6,0xfbe7,
+ 0xfbe8,0xfbe9,0xfbea,0xfbeb,0xfbec,0xfbed,0xfbee,0xfbef,
+ 0xfbf0,0xfbf1,0xfbf2,0xfbf3,0xfbf4,0xfbf5,0xfbf6,0xfbf7,
+ 0xfbf8,0xfbf9,0xfbfa,0xfbfb,0xfbfc,0xfbfd,0xfbfe,0xfbff,
+ 0xfc00,0xfc01,0xfc02,0xfc03,0xfc04,0xfc05,0xfc06,0xfc07,
+ 0xfc08,0xfc09,0xfc0a,0xfc0b,0xfc0c,0xfc0d,0xfc0e,0xfc0f,
+ 0xfc10,0xfc11,0xfc12,0xfc13,0xfc14,0xfc15,0xfc16,0xfc17,
+ 0xfc18,0xfc19,0xfc1a,0xfc1b,0xfc1c,0xfc1d,0xfc1e,0xfc1f,
+ 0xfc20,0xfc21,0xfc22,0xfc23,0xfc24,0xfc25,0xfc26,0xfc27,
+ 0xfc28,0xfc29,0xfc2a,0xfc2b,0xfc2c,0xfc2d,0xfc2e,0xfc2f,
+ 0xfc30,0xfc31,0xfc32,0xfc33,0xfc34,0xfc35,0xfc36,0xfc37,
+ 0xfc38,0xfc39,0xfc3a,0xfc3b,0xfc3c,0xfc3d,0xfc3e,0xfc3f,
+ 0xfc40,0xfc41,0xfc42,0xfc43,0xfc44,0xfc45,0xfc46,0xfc47,
+ 0xfc48,0xfc49,0xfc4a,0xfc4b,0xfc4c,0xfc4d,0xfc4e,0xfc4f,
+ 0xfc50,0xfc51,0xfc52,0xfc53,0xfc54,0xfc55,0xfc56,0xfc57,
+ 0xfc58,0xfc59,0xfc5a,0xfc5b,0xfc5c,0xfc5d,0xfc5e,0xfc5f,
+ 0xfc60,0xfc61,0xfc62,0xfc63,0xfc64,0xfc65,0xfc66,0xfc67,
+ 0xfc68,0xfc69,0xfc6a,0xfc6b,0xfc6c,0xfc6d,0xfc6e,0xfc6f,
+ 0xfc70,0xfc71,0xfc72,0xfc73,0xfc74,0xfc75,0xfc76,0xfc77,
+ 0xfc78,0xfc79,0xfc7a,0xfc7b,0xfc7c,0xfc7d,0xfc7e,0xfc7f,
+ 0xfc80,0xfc81,0xfc82,0xfc83,0xfc84,0xfc85,0xfc86,0xfc87,
+ 0xfc88,0xfc89,0xfc8a,0xfc8b,0xfc8c,0xfc8d,0xfc8e,0xfc8f,
+ 0xfc90,0xfc91,0xfc92,0xfc93,0xfc94,0xfc95,0xfc96,0xfc97,
+ 0xfc98,0xfc99,0xfc9a,0xfc9b,0xfc9c,0xfc9d,0xfc9e,0xfc9f,
+ 0xfca0,0xfca1,0xfca2,0xfca3,0xfca4,0xfca5,0xfca6,0xfca7,
+ 0xfca8,0xfca9,0xfcaa,0xfcab,0xfcac,0xfcad,0xfcae,0xfcaf,
+ 0xfcb0,0xfcb1,0xfcb2,0xfcb3,0xfcb4,0xfcb5,0xfcb6,0xfcb7,
+ 0xfcb8,0xfcb9,0xfcba,0xfcbb,0xfcbc,0xfcbd,0xfcbe,0xfcbf,
+ 0xfcc0,0xfcc1,0xfcc2,0xfcc3,0xfcc4,0xfcc5,0xfcc6,0xfcc7,
+ 0xfcc8,0xfcc9,0xfcca,0xfccb,0xfccc,0xfccd,0xfcce,0xfccf,
+ 0xfcd0,0xfcd1,0xfcd2,0xfcd3,0xfcd4,0xfcd5,0xfcd6,0xfcd7,
+ 0xfcd8,0xfcd9,0xfcda,0xfcdb,0xfcdc,0xfcdd,0xfcde,0xfcdf,
+ 0xfce0,0xfce1,0xfce2,0xfce3,0xfce4,0xfce5,0xfce6,0xfce7,
+ 0xfce8,0xfce9,0xfcea,0xfceb,0xfcec,0xfced,0xfcee,0xfcef,
+ 0xfcf0,0xfcf1,0xfcf2,0xfcf3,0xfcf4,0xfcf5,0xfcf6,0xfcf7,
+ 0xfcf8,0xfcf9,0xfcfa,0xfcfb,0xfcfc,0xfcfd,0xfcfe,0xfcff,
+ 0xfd00,0xfd01,0xfd02,0xfd03,0xfd04,0xfd05,0xfd06,0xfd07,
+ 0xfd08,0xfd09,0xfd0a,0xfd0b,0xfd0c,0xfd0d,0xfd0e,0xfd0f,
+ 0xfd10,0xfd11,0xfd12,0xfd13,0xfd14,0xfd15,0xfd16,0xfd17,
+ 0xfd18,0xfd19,0xfd1a,0xfd1b,0xfd1c,0xfd1d,0xfd1e,0xfd1f,
+ 0xfd20,0xfd21,0xfd22,0xfd23,0xfd24,0xfd25,0xfd26,0xfd27,
+ 0xfd28,0xfd29,0xfd2a,0xfd2b,0xfd2c,0xfd2d,0xfd2e,0xfd2f,
+ 0xfd30,0xfd31,0xfd32,0xfd33,0xfd34,0xfd35,0xfd36,0xfd37,
+ 0xfd38,0xfd39,0xfd3a,0xfd3b,0xfd3c,0xfd3d,0xfd3e,0xfd3f,
+ 0xfd40,0xfd41,0xfd42,0xfd43,0xfd44,0xfd45,0xfd46,0xfd47,
+ 0xfd48,0xfd49,0xfd4a,0xfd4b,0xfd4c,0xfd4d,0xfd4e,0xfd4f,
+ 0xfd50,0xfd51,0xfd52,0xfd53,0xfd54,0xfd55,0xfd56,0xfd57,
+ 0xfd58,0xfd59,0xfd5a,0xfd5b,0xfd5c,0xfd5d,0xfd5e,0xfd5f,
+ 0xfd60,0xfd61,0xfd62,0xfd63,0xfd64,0xfd65,0xfd66,0xfd67,
+ 0xfd68,0xfd69,0xfd6a,0xfd6b,0xfd6c,0xfd6d,0xfd6e,0xfd6f,
+ 0xfd70,0xfd71,0xfd72,0xfd73,0xfd74,0xfd75,0xfd76,0xfd77,
+ 0xfd78,0xfd79,0xfd7a,0xfd7b,0xfd7c,0xfd7d,0xfd7e,0xfd7f,
+ 0xfd80,0xfd81,0xfd82,0xfd83,0xfd84,0xfd85,0xfd86,0xfd87,
+ 0xfd88,0xfd89,0xfd8a,0xfd8b,0xfd8c,0xfd8d,0xfd8e,0xfd8f,
+ 0xfd90,0xfd91,0xfd92,0xfd93,0xfd94,0xfd95,0xfd96,0xfd97,
+ 0xfd98,0xfd99,0xfd9a,0xfd9b,0xfd9c,0xfd9d,0xfd9e,0xfd9f,
+ 0xfda0,0xfda1,0xfda2,0xfda3,0xfda4,0xfda5,0xfda6,0xfda7,
+ 0xfda8,0xfda9,0xfdaa,0xfdab,0xfdac,0xfdad,0xfdae,0xfdaf,
+ 0xfdb0,0xfdb1,0xfdb2,0xfdb3,0xfdb4,0xfdb5,0xfdb6,0xfdb7,
+ 0xfdb8,0xfdb9,0xfdba,0xfdbb,0xfdbc,0xfdbd,0xfdbe,0xfdbf,
+ 0xfdc0,0xfdc1,0xfdc2,0xfdc3,0xfdc4,0xfdc5,0xfdc6,0xfdc7,
+ 0xfdc8,0xfdc9,0xfdca,0xfdcb,0xfdcc,0xfdcd,0xfdce,0xfdcf,
+ 0xfdd0,0xfdd1,0xfdd2,0xfdd3,0xfdd4,0xfdd5,0xfdd6,0xfdd7,
+ 0xfdd8,0xfdd9,0xfdda,0xfddb,0xfddc,0xfddd,0xfdde,0xfddf,
+ 0xfde0,0xfde1,0xfde2,0xfde3,0xfde4,0xfde5,0xfde6,0xfde7,
+ 0xfde8,0xfde9,0xfdea,0xfdeb,0xfdec,0xfded,0xfdee,0xfdef,
+ 0xfdf0,0xfdf1,0xfdf2,0xfdf3,0xfdf4,0xfdf5,0xfdf6,0xfdf7,
+ 0xfdf8,0xfdf9,0xfdfa,0xfdfb,0xfdfc,0xfdfd,0xfdfe,0xfdff,
+ 0xfe00,0xfe01,0xfe02,0xfe03,0xfe04,0xfe05,0xfe06,0xfe07,
+ 0xfe08,0xfe09,0xfe0a,0xfe0b,0xfe0c,0xfe0d,0xfe0e,0xfe0f,
+ 0xfe10,0xfe11,0xfe12,0xfe13,0xfe14,0xfe15,0xfe16,0xfe17,
+ 0xfe18,0xfe19,0xfe1a,0xfe1b,0xfe1c,0xfe1d,0xfe1e,0xfe1f,
+ 0xfe20,0xfe21,0xfe22,0xfe23,0xfe24,0xfe25,0xfe26,0xfe27,
+ 0xfe28,0xfe29,0xfe2a,0xfe2b,0xfe2c,0xfe2d,0xfe2e,0xfe2f,
+ 0xfe30,0xfe31,0xfe32,0xfe33,0xfe34,0xfe35,0xfe36,0xfe37,
+ 0xfe38,0xfe39,0xfe3a,0xfe3b,0xfe3c,0xfe3d,0xfe3e,0xfe3f,
+ 0xfe40,0xfe41,0xfe42,0xfe43,0xfe44,0xfe45,0xfe46,0xfe47,
+ 0xfe48,0xfe49,0xfe4a,0xfe4b,0xfe4c,0xfe4d,0xfe4e,0xfe4f,
+ 0xfe50,0xfe51,0xfe52,0xfe53,0xfe54,0xfe55,0xfe56,0xfe57,
+ 0xfe58,0xfe59,0xfe5a,0xfe5b,0xfe5c,0xfe5d,0xfe5e,0xfe5f,
+ 0xfe60,0xfe61,0xfe62,0xfe63,0xfe64,0xfe65,0xfe66,0xfe67,
+ 0xfe68,0xfe69,0xfe6a,0xfe6b,0xfe6c,0xfe6d,0xfe6e,0xfe6f,
+ 0xfe70,0xfe71,0xfe72,0xfe73,0xfe74,0xfe75,0xfe76,0xfe77,
+ 0xfe78,0xfe79,0xfe7a,0xfe7b,0xfe7c,0xfe7d,0xfe7e,0xfe7f,
+ 0xfe80,0xfe81,0xfe82,0xfe83,0xfe84,0xfe85,0xfe86,0xfe87,
+ 0xfe88,0xfe89,0xfe8a,0xfe8b,0xfe8c,0xfe8d,0xfe8e,0xfe8f,
+ 0xfe90,0xfe91,0xfe92,0xfe93,0xfe94,0xfe95,0xfe96,0xfe97,
+ 0xfe98,0xfe99,0xfe9a,0xfe9b,0xfe9c,0xfe9d,0xfe9e,0xfe9f,
+ 0xfea0,0xfea1,0xfea2,0xfea3,0xfea4,0xfea5,0xfea6,0xfea7,
+ 0xfea8,0xfea9,0xfeaa,0xfeab,0xfeac,0xfead,0xfeae,0xfeaf,
+ 0xfeb0,0xfeb1,0xfeb2,0xfeb3,0xfeb4,0xfeb5,0xfeb6,0xfeb7,
+ 0xfeb8,0xfeb9,0xfeba,0xfebb,0xfebc,0xfebd,0xfebe,0xfebf,
+ 0xfec0,0xfec1,0xfec2,0xfec3,0xfec4,0xfec5,0xfec6,0xfec7,
+ 0xfec8,0xfec9,0xfeca,0xfecb,0xfecc,0xfecd,0xfece,0xfecf,
+ 0xfed0,0xfed1,0xfed2,0xfed3,0xfed4,0xfed5,0xfed6,0xfed7,
+ 0xfed8,0xfed9,0xfeda,0xfedb,0xfedc,0xfedd,0xfede,0xfedf,
+ 0xfee0,0xfee1,0xfee2,0xfee3,0xfee4,0xfee5,0xfee6,0xfee7,
+ 0xfee8,0xfee9,0xfeea,0xfeeb,0xfeec,0xfeed,0xfeee,0xfeef,
+ 0xfef0,0xfef1,0xfef2,0xfef3,0xfef4,0xfef5,0xfef6,0xfef7,
+ 0xfef8,0xfef9,0xfefa,0xfefb,0xfefc,0xfefd,0xfefe,0xfeff,
+ 0xff00,0xff01,0xff02,0xff03,0xff04,0xff05,0xff06,0xff07,
+ 0xff08,0xff09,0xff0a,0xff0b,0xff0c,0xff0d,0xff0e,0xff0f,
+ 0xff10,0xff11,0xff12,0xff13,0xff14,0xff15,0xff16,0xff17,
+ 0xff18,0xff19,0xff1a,0xff1b,0xff1c,0xff1d,0xff1e,0xff1f,
+ 0xff20,0xff21,0xff22,0xff23,0xff24,0xff25,0xff26,0xff27,
+ 0xff28,0xff29,0xff2a,0xff2b,0xff2c,0xff2d,0xff2e,0xff2f,
+ 0xff30,0xff31,0xff32,0xff33,0xff34,0xff35,0xff36,0xff37,
+ 0xff38,0xff39,0xff3a,0xff3b,0xff3c,0xff3d,0xff3e,0xff3f,
+ 0xff40,0xff21,0xff22,0xff23,0xff24,0xff25,0xff26,0xff27,
+ 0xff28,0xff29,0xff2a,0xff2b,0xff2c,0xff2d,0xff2e,0xff2f,
+ 0xff30,0xff31,0xff32,0xff33,0xff34,0xff35,0xff36,0xff37,
+ 0xff38,0xff39,0xff3a,0xff5b,0xff5c,0xff5d,0xff5e,0xff5f,
+ 0xff60,0xff61,0xff62,0xff63,0xff64,0xff65,0xff66,0xff67,
+ 0xff68,0xff69,0xff6a,0xff6b,0xff6c,0xff6d,0xff6e,0xff6f,
+ 0xff70,0xff71,0xff72,0xff73,0xff74,0xff75,0xff76,0xff77,
+ 0xff78,0xff79,0xff7a,0xff7b,0xff7c,0xff7d,0xff7e,0xff7f,
+ 0xff80,0xff81,0xff82,0xff83,0xff84,0xff85,0xff86,0xff87,
+ 0xff88,0xff89,0xff8a,0xff8b,0xff8c,0xff8d,0xff8e,0xff8f,
+ 0xff90,0xff91,0xff92,0xff93,0xff94,0xff95,0xff96,0xff97,
+ 0xff98,0xff99,0xff9a,0xff9b,0xff9c,0xff9d,0xff9e,0xff9f,
+ 0xffa0,0xffa1,0xffa2,0xffa3,0xffa4,0xffa5,0xffa6,0xffa7,
+ 0xffa8,0xffa9,0xffaa,0xffab,0xffac,0xffad,0xffae,0xffaf,
+ 0xffb0,0xffb1,0xffb2,0xffb3,0xffb4,0xffb5,0xffb6,0xffb7,
+ 0xffb8,0xffb9,0xffba,0xffbb,0xffbc,0xffbd,0xffbe,0xffbf,
+ 0xffc0,0xffc1,0xffc2,0xffc3,0xffc4,0xffc5,0xffc6,0xffc7,
+ 0xffc8,0xffc9,0xffca,0xffcb,0xffcc,0xffcd,0xffce,0xffcf,
+ 0xffd0,0xffd1,0xffd2,0xffd3,0xffd4,0xffd5,0xffd6,0xffd7,
+ 0xffd8,0xffd9,0xffda,0xffdb,0xffdc,0xffdd,0xffde,0xffdf,
+ 0xffe0,0xffe1,0xffe2,0xffe3,0xffe4,0xffe5,0xffe6,0xffe7,
+ 0xffe8,0xffe9,0xffea,0xffeb,0xffec,0xffed,0xffee,0xffef,
+ 0xfff0,0xfff1,0xfff2,0xfff3,0xfff4,0xfff5,0xfff6,0xfff7,
+ 0xfff8,0xfff9,0xfffa,0xfffb,0xfffc,0xfffd,0xfffe,0xffff
+};
+
+void smb_init_locale(void)
+{
+ /* This is a useful global hook where we can ensure that the
+ * locale is set from the environment. This is needed so that
+ * we can use LOCALE as a codepage */
+#ifdef HAVE_SETLOCALE
+ setlocale(LC_ALL, "");
+#endif
+}
+
+/**
+ Convert a codepoint_t to upper case.
+**/
+_PUBLIC_ codepoint_t toupper_m(codepoint_t val)
+{
+ if (val >= ARRAY_SIZE(upcase_table)) {
+ return val;
+ }
+ return upcase_table[val];
+}
+
+/**
+ Convert a codepoint_t to lower case.
+**/
+_PUBLIC_ codepoint_t tolower_m(codepoint_t val)
+{
+ if (val >= ARRAY_SIZE(lowcase_table)) {
+ return val;
+ }
+ return lowcase_table[val];
+}
+
+/**
+ If we upper cased this character, would we get the same character?
+**/
+_PUBLIC_ bool islower_m(codepoint_t val)
+{
+ return (toupper_m(val) != val);
+}
+
+/**
+ If we lower cased this character, would we get the same character?
+**/
+_PUBLIC_ bool isupper_m(codepoint_t val)
+{
+ return (tolower_m(val) != val);
+}
+
+/**
+ compare two codepoints case insensitively
+*/
+_PUBLIC_ int codepoint_cmpi(codepoint_t c1, codepoint_t c2)
+{
+ if (c1 == c2 ||
+ toupper_m(c1) == toupper_m(c2)) {
+ return 0;
+ }
+ return c1 - c2;
+}
+
+
+struct smb_iconv_handle {
+ TALLOC_CTX *child_ctx;
+ const char *unix_charset;
+ const char *dos_charset;
+ const char *display_charset;
+ bool use_builtin_handlers;
+ smb_iconv_t conv_handles[NUM_CHARSETS][NUM_CHARSETS];
+};
+
+static struct smb_iconv_handle *global_iconv_handle = NULL;
+
+struct smb_iconv_handle *get_iconv_handle(void)
+{
+ if (global_iconv_handle == NULL) {
+ global_iconv_handle =
+ smb_iconv_handle_reinit(NULL,
+ "ASCII",
+ "UTF-8",
+ true,
+ NULL);
+ }
+
+ return global_iconv_handle;
+}
+
+struct smb_iconv_handle *get_iconv_testing_handle(TALLOC_CTX *mem_ctx,
+ const char *dos_charset,
+ const char *unix_charset,
+ bool use_builtin_handlers)
+{
+ return smb_iconv_handle_reinit(mem_ctx,
+ dos_charset, unix_charset, use_builtin_handlers, NULL);
+}
+
+struct smb_iconv_handle *reinit_iconv_handle(TALLOC_CTX *mem_ctx,
+ const char *dos_charset,
+ const char *unix_charset)
+{
+ global_iconv_handle =
+ smb_iconv_handle_reinit(mem_ctx,
+ dos_charset,
+ unix_charset,
+ true,
+ global_iconv_handle);
+ return global_iconv_handle;
+}
+
+void free_iconv_handle(void)
+{
+ TALLOC_FREE(global_iconv_handle);
+}
+
+/**
+ * Return the name of a charset to give to iconv().
+ **/
+const char *charset_name(struct smb_iconv_handle *ic, charset_t ch)
+{
+ switch (ch) {
+ case CH_UTF16: return "UTF-16LE";
+ case CH_UNIX: return ic->unix_charset;
+ case CH_DOS: return ic->dos_charset;
+ case CH_UTF8: return "UTF8";
+ case CH_UTF16BE: return "UTF-16BE";
+ case CH_UTF16MUNGED: return "UTF16_MUNGED";
+ default:
+ return "ASCII";
+ }
+}
+
+/**
+ re-initialize iconv conversion descriptors
+**/
+static int close_iconv_handle(struct smb_iconv_handle *data)
+{
+ unsigned c1, c2;
+ for (c1=0;c1<NUM_CHARSETS;c1++) {
+ for (c2=0;c2<NUM_CHARSETS;c2++) {
+ if (data->conv_handles[c1][c2] != NULL) {
+ if (data->conv_handles[c1][c2] != (smb_iconv_t)-1) {
+ smb_iconv_close(data->conv_handles[c1][c2]);
+ }
+ data->conv_handles[c1][c2] = NULL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ the old_ic is passed in here as the smb_iconv_handle structure
+ is used as a global pointer in some places (eg. python modules). We
+ don't want to invalidate those global pointers, but we do want to
+ update them with the right charset information when loadparm
+ runs. To do that we need to re-use the structure pointer, but
+ re-fill the elements in the structure with the updated values
+ */
+_PUBLIC_ struct smb_iconv_handle *smb_iconv_handle_reinit(TALLOC_CTX *mem_ctx,
+ const char *dos_charset,
+ const char *unix_charset,
+ bool use_builtin_handlers,
+ struct smb_iconv_handle *old_ic)
+{
+ struct smb_iconv_handle *ret;
+
+ if (old_ic != NULL) {
+ ret = old_ic;
+ close_iconv_handle(ret);
+ talloc_free(ret->child_ctx);
+ ZERO_STRUCTP(ret);
+ } else {
+ ret = talloc_zero(mem_ctx, struct smb_iconv_handle);
+ }
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ /* we use a child context to allow us to free all ptrs without
+ freeing the structure itself */
+ ret->child_ctx = talloc_new(ret);
+ if (ret->child_ctx == NULL) {
+ return NULL;
+ }
+
+ talloc_set_destructor(ret, close_iconv_handle);
+
+ if (strcasecmp(dos_charset, "UTF8") == 0 || strcasecmp(dos_charset, "UTF-8") == 0) {
+ DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not be UTF8, using (default value) CP850 instead\n"));
+ dos_charset = "CP850";
+ }
+
+ ret->dos_charset = talloc_strdup(ret->child_ctx, dos_charset);
+ ret->unix_charset = talloc_strdup(ret->child_ctx, unix_charset);
+ ret->use_builtin_handlers = use_builtin_handlers;
+
+ return ret;
+}
+
+/*
+ on-demand initialisation of conversion handles
+*/
+smb_iconv_t get_conv_handle(struct smb_iconv_handle *ic,
+ charset_t from, charset_t to)
+{
+ const char *n1, *n2;
+
+ if (ic->conv_handles[from][to]) {
+ return ic->conv_handles[from][to];
+ }
+
+ n1 = charset_name(ic, from);
+ n2 = charset_name(ic, to);
+
+ ic->conv_handles[from][to] = smb_iconv_open_ex(ic, n2, n1,
+ ic->use_builtin_handlers);
+
+ if (ic->conv_handles[from][to] == (smb_iconv_t)-1) {
+ if ((from == CH_DOS || to == CH_DOS) &&
+ strcasecmp(charset_name(ic, CH_DOS), "ASCII") != 0) {
+ DEBUG(0,("dos charset '%s' unavailable - using ASCII\n",
+ charset_name(ic, CH_DOS)));
+ ic->dos_charset = "ASCII";
+
+ n1 = charset_name(ic, from);
+ n2 = charset_name(ic, to);
+
+ ic->conv_handles[from][to] =
+ smb_iconv_open_ex(ic, n2, n1, ic->use_builtin_handlers);
+ }
+ }
+
+ return ic->conv_handles[from][to];
+}
+
+/**
+ * Return the unicode codepoint for the next character in the input
+ * string in the given src_charset.
+ * The unicode codepoint (codepoint_t) is an unsigned 32 bit value.
+ *
+ * Also return the number of bytes consumed (which tells the caller
+ * how many bytes to skip to get to the next src_charset-character).
+ *
+ * This is implemented (in the non-ascii-case) by first converting the
+ * next character in the input string to UTF16_LE and then calculating
+ * the unicode codepoint from that.
+ *
+ * Return INVALID_CODEPOINT if the next character cannot be converted.
+ */
+_PUBLIC_ codepoint_t next_codepoint_handle_ext(
+ struct smb_iconv_handle *ic,
+ const char *str, size_t len,
+ charset_t src_charset,
+ size_t *bytes_consumed)
+{
+ /* it cannot occupy more than 4 bytes in UTF16 format */
+ uint8_t buf[4];
+ smb_iconv_t descriptor;
+ size_t ilen_orig;
+ size_t ilen;
+ size_t olen;
+ char *outbuf;
+
+
+ if (((str[0] & 0x80) == 0) && (src_charset == CH_DOS ||
+ src_charset == CH_UNIX ||
+ src_charset == CH_UTF8)) {
+ *bytes_consumed = 1;
+ return (codepoint_t)str[0];
+ }
+
+ /*
+ * we assume that no multi-byte character can take more than 5 bytes.
+ * This is OK as we only support codepoints up to 1M (U+100000)
+ */
+ ilen_orig = MIN(len, 5);
+ ilen = ilen_orig;
+
+ descriptor = get_conv_handle(ic, src_charset, CH_UTF16);
+ if (descriptor == (smb_iconv_t)-1) {
+ *bytes_consumed = 1;
+ return INVALID_CODEPOINT;
+ }
+
+ /*
+ * this looks a little strange, but it is needed to cope with
+ * codepoints above 64k (U+1000) which are encoded as per RFC2781.
+ */
+ olen = 2;
+ outbuf = (char *)buf;
+ smb_iconv(descriptor, &str, &ilen, &outbuf, &olen);
+ if (olen == 2) {
+ olen = 4;
+ outbuf = (char *)buf;
+ smb_iconv(descriptor, &str, &ilen, &outbuf, &olen);
+ if (olen == 4) {
+ /* we didn't convert any bytes */
+ *bytes_consumed = 1;
+ return INVALID_CODEPOINT;
+ }
+ olen = 4 - olen;
+ } else {
+ olen = 2 - olen;
+ }
+
+ *bytes_consumed = ilen_orig - ilen;
+
+ if (olen == 2) {
+ return (codepoint_t)SVAL(buf, 0);
+ }
+ if (olen == 4) {
+ /* decode a 4 byte UTF16 character manually */
+ return (codepoint_t)0x10000 +
+ (buf[2] | ((buf[3] & 0x3)<<8) |
+ (buf[0]<<10) | ((buf[1] & 0x3)<<18));
+ }
+
+ /* no other length is valid */
+ return INVALID_CODEPOINT;
+}
+
+/*
+ return the unicode codepoint for the next multi-byte CH_UNIX character
+ in the string
+
+ also return the number of bytes consumed (which tells the caller
+ how many bytes to skip to get to the next CH_UNIX character)
+
+ return INVALID_CODEPOINT if the next character cannot be converted
+*/
+_PUBLIC_ codepoint_t next_codepoint_handle(struct smb_iconv_handle *ic,
+ const char *str, size_t *size)
+{
+ /*
+ * We assume that no multi-byte character can take more than 5 bytes
+ * thus avoiding walking all the way down a long string. This is OK as
+ * Unicode codepoints only go up to (U+10ffff), which can always be
+ * encoded in 4 bytes or less.
+ */
+ return next_codepoint_handle_ext(ic, str, strnlen(str, 5), CH_UNIX,
+ size);
+}
+
+/*
+ push a single codepoint into a CH_UNIX string the target string must
+ be able to hold the full character, which is guaranteed if it is at
+ least 5 bytes in size. The caller may pass less than 5 bytes if they
+ are sure the character will fit (for example, you can assume that
+ uppercase/lowercase of a character will not add more than 1 byte)
+
+ return the number of bytes occupied by the CH_UNIX character, or
+ -1 on failure
+*/
+_PUBLIC_ ssize_t push_codepoint_handle(struct smb_iconv_handle *ic,
+ char *str, codepoint_t c)
+{
+ smb_iconv_t descriptor;
+ uint8_t buf[4];
+ size_t ilen, olen;
+ const char *inbuf;
+
+ if (c < 128) {
+ *str = c;
+ return 1;
+ }
+
+ descriptor = get_conv_handle(ic,
+ CH_UTF16, CH_UNIX);
+ if (descriptor == (smb_iconv_t)-1) {
+ return -1;
+ }
+
+ if (c < 0x10000) {
+ ilen = 2;
+ olen = 5;
+ inbuf = (char *)buf;
+ SSVAL(buf, 0, c);
+ smb_iconv(descriptor, &inbuf, &ilen, &str, &olen);
+ if (ilen != 0) {
+ return -1;
+ }
+ return 5 - olen;
+ }
+
+ c -= 0x10000;
+
+ buf[0] = (c>>10) & 0xFF;
+ buf[1] = (c>>18) | 0xd8;
+ buf[2] = c & 0xFF;
+ buf[3] = ((c>>8) & 0x3) | 0xdc;
+
+ ilen = 4;
+ olen = 5;
+ inbuf = (char *)buf;
+
+ smb_iconv(descriptor, &inbuf, &ilen, &str, &olen);
+ if (ilen != 0) {
+ return -1;
+ }
+ return 5 - olen;
+}
+
+_PUBLIC_ codepoint_t next_codepoint_ext(const char *str, size_t len,
+ charset_t src_charset, size_t *size)
+{
+ return next_codepoint_handle_ext(get_iconv_handle(), str, len,
+ src_charset, size);
+}
+
+_PUBLIC_ codepoint_t next_codepoint(const char *str, size_t *size)
+{
+ if ((str[0] & 0x80) == 0) {
+ *size = 1;
+ return str[0];
+ }
+ return next_codepoint_handle(get_iconv_handle(), str, size);
+}
+
+_PUBLIC_ ssize_t push_codepoint(char *str, codepoint_t c)
+{
+ return push_codepoint_handle(get_iconv_handle(), str, c);
+}
diff --git a/lib/util/charset/convert_string.c b/lib/util/charset/convert_string.c
new file mode 100644
index 0000000..859b002
--- /dev/null
+++ b/lib/util/charset/convert_string.c
@@ -0,0 +1,556 @@
+/*
+ Unix SMB/CIFS implementation.
+ Character set conversion Extensions
+ Copyright (C) Igor Vergeichik <iverg@mail.ru> 2001
+ Copyright (C) Andrew Tridgell 2001-2011
+ Copyright (C) Andrew Bartlett 2011
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Martin Pool 2003
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+#include "replace.h"
+#include "system/iconv.h"
+#include "charset.h"
+#include "lib/util/debug.h"
+#include "lib/util/fault.h"
+
+/**
+ * @file
+ *
+ * @brief Character-set conversion routines built on our iconv.
+ *
+ * @note Samba's internal character set (at least in the 3.0 series)
+ * is always the same as the one for the Unix filesystem. It is
+ * <b>not</b> necessarily UTF-8 and may be different on machines that
+ * need i18n filenames to be compatible with Unix software. It does
+ * have to be a superset of ASCII. All multibyte sequences must start
+ * with a byte with the high bit set.
+ *
+ * @sa lib/iconv.c
+ */
+
+
+/**
+ * Convert string from one encoding to another, making error checking etc
+ * Slow path version - uses (slow) iconv.
+ *
+ * @param src pointer to source string (multibyte or singlebyte)
+ * @param srclen length of the source string in bytes
+ * @param dest pointer to destination string (multibyte or singlebyte)
+ * @param destlen maximal length allowed for string
+ * @param converted size is the number of bytes occupied in the destination
+ *
+ * @returns false and sets errno on fail, true on success.
+ *
+ * Ensure the srclen contains the terminating zero.
+ *
+ **/
+
+static bool convert_string_internal(struct smb_iconv_handle *ic,
+ charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t destlen, size_t *converted_size)
+{
+ size_t i_len, o_len;
+ size_t retval;
+ const char* inbuf = (const char*)src;
+ char* outbuf = (char*)dest;
+ smb_iconv_t descriptor;
+
+ descriptor = get_conv_handle(ic, from, to);
+
+ if (srclen == (size_t)-1) {
+ if (from == CH_UTF16LE || from == CH_UTF16BE) {
+ srclen = (strlen_w((const smb_ucs2_t *)src)+1) * 2;
+ } else {
+ srclen = strlen((const char *)src)+1;
+ }
+ }
+
+
+ if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
+ errno = EINVAL;
+ return false;
+ }
+
+ i_len=srclen;
+ o_len=destlen;
+
+ retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len);
+ *converted_size = destlen-o_len;
+
+ return (retval != (size_t)-1);
+}
+
+/**
+ * Convert string from one encoding to another, making error checking etc
+ * Fast path version - handles ASCII first.
+ *
+ * @param src pointer to source string (multibyte or singlebyte)
+ * @param srclen length of the source string in bytes, or -1 for nul terminated.
+ * @param dest pointer to destination string (multibyte or singlebyte)
+ * @param destlen maximal length allowed for string - *NEVER* -1.
+ * @param converted size is the number of bytes occupied in the destination
+ *
+ * @returns false and sets errno on fail, true on success.
+ *
+ * Ensure the srclen contains the terminating zero.
+ *
+ * This function has been hand-tuned to provide a fast path.
+ * Don't change unless you really know what you are doing. JRA.
+ **/
+
+bool convert_string_error_handle(struct smb_iconv_handle *ic,
+ charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t destlen,
+ size_t *converted_size)
+{
+ /*
+ * NB. We deliberately don't do a strlen here if srclen == -1.
+ * This is very expensive over millions of calls and is taken
+ * care of in the slow path in convert_string_internal. JRA.
+ */
+
+#ifdef DEVELOPER
+ SMB_ASSERT(destlen != (size_t)-1);
+#endif
+
+ if (srclen == 0) {
+ *converted_size = 0;
+ return true;
+ }
+
+ if (from != CH_UTF16LE && from != CH_UTF16BE && to != CH_UTF16LE && to != CH_UTF16BE) {
+ const unsigned char *p = (const unsigned char *)src;
+ unsigned char *q = (unsigned char *)dest;
+ size_t slen = srclen;
+ size_t dlen = destlen;
+ unsigned char lastp = '\0';
+ size_t retval = 0;
+
+ /* If all characters are ascii, fast path here. */
+ while (slen && dlen) {
+ if ((lastp = *p) <= 0x7f) {
+ *q++ = *p++;
+ if (slen != (size_t)-1) {
+ slen--;
+ }
+ dlen--;
+ retval++;
+ if (!lastp)
+ break;
+ } else {
+#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
+ goto general_case;
+#else
+ bool ret = convert_string_internal(ic, from, to, p, slen, q, dlen, converted_size);
+ *converted_size += retval;
+ return ret;
+#endif
+ }
+ }
+
+ *converted_size = retval;
+
+ if (!dlen) {
+ /* Even if we fast path we should note if we ran out of room. */
+ if (((slen != (size_t)-1) && slen) ||
+ ((slen == (size_t)-1) && lastp)) {
+ errno = E2BIG;
+ return false;
+ }
+ }
+ return true;
+ } else if (from == CH_UTF16LE && to != CH_UTF16LE) {
+ const unsigned char *p = (const unsigned char *)src;
+ unsigned char *q = (unsigned char *)dest;
+ size_t retval = 0;
+ size_t slen = srclen;
+ size_t dlen = destlen;
+ unsigned char lastp = '\0';
+#ifndef BROKEN_UNICODE_COMPOSE_CHARACTERS
+ bool ret;
+#endif
+
+ if (slen == (size_t)-1) {
+ while (dlen &&
+ ((lastp = *p) <= 0x7f) && (p[1] == 0)) {
+ *q++ = *p;
+ p += 2;
+ dlen--;
+ retval++;
+ if (!lastp)
+ break;
+ }
+ if (lastp != 0) goto slow_path;
+ } else {
+ while (slen >= 2 && dlen &&
+ (*p <= 0x7f) && (p[1] == 0)) {
+ *q++ = *p;
+ slen -= 2;
+ p += 2;
+ dlen--;
+ retval++;
+ }
+ if (slen != 0) goto slow_path;
+ }
+
+ *converted_size = retval;
+
+ if (!dlen) {
+ /* Even if we fast path we should note if we ran out of room. */
+ if (((slen != (size_t)-1) && slen) ||
+ ((slen == (size_t)-1) && lastp)) {
+ errno = E2BIG;
+ return false;
+ }
+ }
+ return true;
+
+ slow_path:
+ /* come here when we hit a character we can't deal
+ * with in the fast path
+ */
+#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
+ goto general_case;
+#else
+ ret = convert_string_internal(ic, from, to, p, slen, q, dlen, converted_size);
+ *converted_size += retval;
+ return ret;
+#endif
+
+ } else if (from != CH_UTF16LE && from != CH_UTF16BE && to == CH_UTF16LE) {
+ const unsigned char *p = (const unsigned char *)src;
+ unsigned char *q = (unsigned char *)dest;
+ size_t retval = 0;
+ size_t slen = srclen;
+ size_t dlen = destlen;
+ unsigned char lastp = '\0';
+
+ /* If all characters are ascii, fast path here. */
+ while (slen && (dlen >= 1)) {
+ if (dlen >=2 && (lastp = *p) <= 0x7F) {
+ *q++ = *p++;
+ *q++ = '\0';
+ if (slen != (size_t)-1) {
+ slen--;
+ }
+ dlen -= 2;
+ retval += 2;
+ if (!lastp)
+ break;
+ } else {
+#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
+ goto general_case;
+#else
+ bool ret = convert_string_internal(ic, from, to, p, slen, q, dlen, converted_size);
+ *converted_size += retval;
+ return ret;
+#endif
+ }
+ }
+
+ *converted_size = retval;
+
+ if (!dlen) {
+ /* Even if we fast path we should note if we ran out of room. */
+ if (((slen != (size_t)-1) && slen) ||
+ ((slen == (size_t)-1) && lastp)) {
+ errno = E2BIG;
+ return false;
+ }
+ }
+ return true;
+ }
+
+#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
+ general_case:
+#endif
+ return convert_string_internal(ic, from, to, src, srclen, dest, destlen, converted_size);
+}
+
+bool convert_string_handle(struct smb_iconv_handle *ic,
+ charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t destlen,
+ size_t *converted_size)
+{
+ bool ret = convert_string_error_handle(ic, from, to, src, srclen, dest, destlen, converted_size);
+
+ if(ret==false) {
+ const char *reason="unknown error";
+ switch(errno) {
+ case EINVAL:
+ reason="Incomplete multibyte sequence";
+ DBG_NOTICE("Conversion error: %s\n",
+ reason);
+ break;
+ case E2BIG:
+ {
+ reason="No more room";
+ if (from == CH_UNIX) {
+ DBG_NOTICE("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u error: %s\n",
+ charset_name(ic, from), charset_name(ic, to),
+ (unsigned int)srclen, (unsigned int)destlen, reason);
+ } else {
+ DBG_NOTICE("E2BIG: convert_string(%s,%s): srclen=%u destlen=%u error: %s\n",
+ charset_name(ic, from), charset_name(ic, to),
+ (unsigned int)srclen, (unsigned int)destlen, reason);
+ }
+ break;
+ }
+ case EILSEQ:
+ reason="Illegal multibyte sequence";
+ DBG_NOTICE("convert_string_internal: Conversion error: %s\n",
+ reason);
+ break;
+ default:
+ DBG_ERR("convert_string_internal: Conversion error: %s\n",
+ reason);
+ break;
+ }
+ /* smb_panic(reason); */
+ }
+ return ret;
+}
+
+
+/**
+ * Convert between character sets, allocating a new buffer using talloc for the result.
+ *
+ * @param srclen length of source buffer.
+ * @param dest always set at least to NULL
+ * @param converted_size set to the number of bytes occupied by the string in
+ * the destination on success.
+ * @note -1 is not accepted for srclen.
+ *
+ * @return true if new buffer was correctly allocated, and string was
+ * converted.
+ *
+ * Ensure the srclen contains the terminating zero.
+ */
+bool convert_string_talloc_handle(TALLOC_CTX *ctx, struct smb_iconv_handle *ic,
+ charset_t from, charset_t to,
+ void const *src, size_t srclen, void *dst,
+ size_t *converted_size)
+
+{
+ size_t i_len, o_len, destlen;
+ size_t retval;
+ const char *inbuf = NULL;
+ char *outbuf = NULL, *ob = NULL;
+ smb_iconv_t descriptor;
+ void **dest = dst;
+
+ *dest = NULL;
+ if (converted_size != NULL) {
+ *converted_size = 0;
+ }
+
+ if (src == NULL || srclen == (size_t)-1) {
+ errno = EINVAL;
+ return false;
+ }
+
+ if (srclen == 0) {
+ /* We really should treat this as an error, but
+ there are too many callers that need this to
+ return a NULL terminated string in the correct
+ character set. */
+ if (to == CH_UTF16LE|| to == CH_UTF16BE || to == CH_UTF16MUNGED) {
+ destlen = 2;
+ } else {
+ destlen = 1;
+ }
+ ob = talloc_zero_array(ctx, char, destlen);
+ if (ob == NULL) {
+ DBG_ERR("Could not talloc destination buffer.\n");
+ errno = ENOMEM;
+ return false;
+ }
+ if (converted_size != NULL) {
+ *converted_size = destlen;
+ }
+ *dest = ob;
+ return true;
+ }
+
+ descriptor = get_conv_handle(ic, from, to);
+
+ if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
+ DEBUG(0,("convert_string_talloc: Conversion not supported.\n"));
+ errno = EOPNOTSUPP;
+ return false;
+ }
+
+ if (srclen >= (SIZE_MAX - 2) / 3) {
+ DBG_ERR("convert_string_talloc: "
+ "srclen is %zu, destlen would wrap!\n",
+ srclen);
+ errno = EOPNOTSUPP;
+ return false;
+ }
+ destlen = srclen * 3;
+
+ /* +2 is for ucs2 null termination. */
+ ob = talloc_realloc(ctx, ob, char, destlen + 2);
+
+ if (!ob) {
+ DEBUG(0, ("convert_string_talloc: realloc failed!\n"));
+ errno = ENOMEM;
+ return false;
+ }
+ outbuf = ob;
+ i_len = srclen;
+ o_len = destlen;
+ inbuf = (const char *)src;
+
+ retval = smb_iconv(descriptor,
+ &inbuf, &i_len,
+ &outbuf, &o_len);
+ if(retval == (size_t)-1) {
+ const char *reason="unknown error";
+ switch(errno) {
+ case EINVAL:
+ reason="Incomplete multibyte sequence";
+ DBG_NOTICE("Conversion error: %s\n",
+ reason);
+ break;
+ case E2BIG:
+ reason = "output buffer is too small";
+ DBG_ERR("Conversion error: %s\n",
+ reason);
+ break;
+ case EILSEQ:
+ reason="Illegal multibyte sequence";
+ DBG_NOTICE("Conversion error: %s\n",
+ reason);
+ break;
+ default:
+ DBG_ERR("Conversion error: %s\n",
+ reason);
+ break;
+ }
+ /* smb_panic(reason); */
+ TALLOC_FREE(ob);
+ return false;
+ }
+
+ destlen = destlen - o_len;
+ /* Don't shrink unless we're reclaiming a lot of
+ * space. This is in the hot codepath and these
+ * reallocs *cost*. JRA.
+ */
+ if (o_len > 1024) {
+ /* We're shrinking here so we know the +2 is safe from wrap. */
+ ob = talloc_realloc(ctx,ob, char, destlen + 2);
+ }
+
+ if (destlen && !ob) {
+ DEBUG(0, ("convert_string_talloc: out of memory!\n"));
+ errno = ENOMEM;
+ return false;
+ }
+
+ *dest = ob;
+
+ /* Must ucs2 null terminate in the extra space we allocated. */
+ ob[destlen] = '\0';
+ ob[destlen+1] = '\0';
+
+ /* Ensure we can never return a *converted_size of zero. */
+ if (destlen == 0) {
+ /* As we're now returning false on a bad smb_iconv call,
+ this should never happen. But be safe anyway. */
+ if (to == CH_UTF16LE|| to == CH_UTF16BE || to == CH_UTF16MUNGED) {
+ destlen = 2;
+ } else {
+ destlen = 1;
+ }
+ }
+
+ if (converted_size != NULL) {
+ *converted_size = destlen;
+ }
+ return true;
+}
+
+/**
+ * Convert string from one encoding to another, with error checking.
+ * This version produces more logging information than
+ * convert_string_error(), but is otherwise functionally identical.
+ *
+ * @param src pointer to source string (multibyte or singlebyte)
+ * @param srclen length of the source string in bytes
+ * @param dest pointer to destination string (multibyte or singlebyte)
+ * @param destlen maximal length allowed for string
+ * @param converted_size the number of bytes occupied in the destination
+ *
+ * @returns true on success, false on fail.
+ **/
+_PUBLIC_ bool convert_string(charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t destlen,
+ size_t *converted_size)
+{
+ return convert_string_handle(get_iconv_handle(), from, to,
+ src, srclen,
+ dest, destlen, converted_size);
+}
+
+/**
+ * Convert string from one encoding to another, with error checking.
+ * This version is less verbose than convert_string().
+ *
+ * @param src pointer to source string (multibyte or singlebyte)
+ * @param srclen length of the source string in bytes
+ * @param dest pointer to destination string (multibyte or singlebyte)
+ * @param destlen maximal length allowed for string
+ * @param converted_size the number of bytes occupied in the destination
+ *
+ * @returns true on success, false on fail.
+ **/
+_PUBLIC_ bool convert_string_error(charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t destlen,
+ size_t *converted_size)
+{
+ return convert_string_error_handle(get_iconv_handle(), from, to,
+ src, srclen,
+ dest, destlen, converted_size);
+}
+
+/**
+ * Convert between character sets, allocating a new buffer using talloc for the result.
+ *
+ * @param srclen length of source buffer.
+ * @param dest always set at least to NULL
+ * @param converted_size Size in bytes of the converted string
+ * @note -1 is not accepted for srclen.
+ *
+ * @returns boolean indication whether the conversion succeeded
+ **/
+
+_PUBLIC_ bool convert_string_talloc(TALLOC_CTX *ctx,
+ charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t *converted_size)
+{
+ return convert_string_talloc_handle(ctx, get_iconv_handle(),
+ from, to, src, srclen, dest,
+ converted_size);
+}
diff --git a/lib/util/charset/iconv.c b/lib/util/charset/iconv.c
new file mode 100644
index 0000000..131df64
--- /dev/null
+++ b/lib/util/charset/iconv.c
@@ -0,0 +1,1196 @@
+/*
+ Unix SMB/CIFS implementation.
+ minimal iconv implementation
+ Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Jelmer Vernooij 2002
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/iconv.h"
+#include "system/filesys.h"
+#include "lib/util/byteorder.h"
+#include "lib/util/dlinklist.h"
+#include "lib/util/charset/charset.h"
+#include "lib/util/charset/charset_proto.h"
+
+#ifdef HAVE_ICU_I18N
+#include <unicode/ustring.h>
+#include <unicode/utrans.h>
+#endif
+
+#ifdef strcasecmp
+#undef strcasecmp
+#endif
+
+/**
+ * @file
+ *
+ * @brief Samba wrapper/stub for iconv character set conversion.
+ *
+ * iconv is the XPG2 interface for converting between character
+ * encodings. This file provides a Samba wrapper around it, and also
+ * a simple reimplementation that is used if the system does not
+ * implement iconv.
+ *
+ * Samba only works with encodings that are supersets of ASCII: ascii
+ * characters like whitespace can be tested for directly, multibyte
+ * sequences start with a byte with the high bit set, and strings are
+ * terminated by a nul byte.
+ *
+ * Note that the only function provided by iconv is conversion between
+ * characters. It doesn't directly support operations like
+ * uppercasing or comparison. We have to convert to UTF-16LE and
+ * compare there.
+ *
+ * @sa Samba Developers Guide
+ **/
+
+static size_t ascii_pull (void *,const char **, size_t *, char **, size_t *);
+static size_t ascii_push (void *,const char **, size_t *, char **, size_t *);
+static size_t latin1_pull(void *,const char **, size_t *, char **, size_t *);
+static size_t latin1_push(void *,const char **, size_t *, char **, size_t *);
+static size_t utf8_pull (void *,const char **, size_t *, char **, size_t *);
+static size_t utf8_push (void *,const char **, size_t *, char **, size_t *);
+static size_t utf16_munged_pull(void *,const char **, size_t *, char **, size_t *);
+static size_t ucs2hex_pull(void *,const char **, size_t *, char **, size_t *);
+static size_t ucs2hex_push(void *,const char **, size_t *, char **, size_t *);
+static size_t iconv_copy (void *,const char **, size_t *, char **, size_t *);
+static size_t iconv_swab (void *,const char **, size_t *, char **, size_t *);
+
+static const struct charset_functions builtin_functions[] = {
+ /* windows is closest to UTF-16 */
+ {
+ .name = "UCS-2LE",
+ .pull = iconv_copy,
+ .push = iconv_copy
+ },
+ {
+ .name = "UTF-16LE",
+ .pull = iconv_copy,
+ .push = iconv_copy
+ },
+ {
+ .name = "UCS-2BE",
+ .pull = iconv_swab,
+ .push = iconv_swab
+ },
+ {
+ .name = "UTF-16BE",
+ .pull = iconv_swab,
+ .push = iconv_swab
+ },
+
+ /* we include the UTF-8 alias to cope with differing locale settings */
+ {
+ .name = "UTF8",
+ .pull = utf8_pull,
+ .push = utf8_push
+ },
+ {
+ .name = "UTF-8",
+ .pull = utf8_pull,
+ .push = utf8_push
+ },
+
+ /* this handles the munging needed for String2Key */
+ {
+ .name = "UTF16_MUNGED",
+ .pull = utf16_munged_pull,
+ .push = iconv_copy,
+ .samba_internal_charset = true
+ },
+
+ {
+ .name = "ASCII",
+ .pull = ascii_pull,
+ .push = ascii_push
+ },
+ {
+ .name = "646",
+ .pull = ascii_pull,
+ .push = ascii_push
+ },
+ {
+ .name = "ISO-8859-1",
+ .pull = latin1_pull,
+ .push = latin1_push
+ },
+#ifdef DEVELOPER
+ {
+ .name = "WEIRD",
+ .pull = weird_pull,
+ .push = weird_push,
+ .samba_internal_charset = true
+ },
+#endif
+#ifdef DARWINOS
+ {
+ .name = "MACOSXFS",
+ .pull = macosxfs_encoding_pull,
+ .push = macosxfs_encoding_push,
+ .samba_internal_charset = true
+ },
+#endif
+ {
+ .name = "UCS2-HEX",
+ .pull = ucs2hex_pull,
+ .push = ucs2hex_push,
+ .samba_internal_charset = true
+ }
+};
+
+#ifdef HAVE_NATIVE_ICONV
+/* if there was an error then reset the internal state,
+ this ensures that we don't have a shift state remaining for
+ character sets like SJIS */
+static size_t sys_iconv(void *cd,
+ const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ size_t ret = iconv((iconv_t)cd,
+ discard_const_p(char *, inbuf), inbytesleft,
+ outbuf, outbytesleft);
+ if (ret == (size_t)-1) iconv(cd, NULL, NULL, NULL, NULL);
+ return ret;
+}
+#endif
+
+#ifdef HAVE_ICU_I18N
+static size_t sys_uconv(void *cd,
+ const char **inbuf,
+ size_t *inbytesleft,
+ char **outbuf,
+ size_t *outbytesleft)
+{
+ UTransliterator *t = (UTransliterator *)cd;
+ size_t bufsize = *inbytesleft * 2;
+ UChar ustr[bufsize];
+ UChar *up = NULL;
+ char *p = NULL;
+ int32_t ustrlen;
+ int32_t limit;
+ int32_t converted_len;
+ size_t inbuf_consumed;
+ size_t outbut_consumed;
+ UErrorCode ue;
+
+ /* Convert from UTF8 to UCS2 */
+ ue = 0;
+ up = u_strFromUTF8(ustr, /* dst */
+ bufsize, /* dst buflen */
+ &converted_len, /* dst written */
+ *inbuf, /* src */
+ *inbytesleft, /* src length */
+ &ue);
+ if (up == NULL || U_FAILURE(ue)) {
+ return -1;
+ }
+ if (converted_len > bufsize) {
+ /*
+ * u_strFromUTF8() returns the required size in
+ * converted_len. In theory this should never overflow as the
+ * ustr[] array is allocated with a size twice as big as
+ * inbytesleft and converted_len should be equal to inbytesleft,
+ * but you never know...
+ */
+ errno = EOVERFLOW;
+ return -1;
+ }
+ inbuf_consumed = converted_len;
+
+ /*
+ * The following transliteration function takes two parameters, the
+ * length of the text to be converted (converted_len) and a limit which
+ * may be smaller then converted_len. We just set limit to converted_len
+ * and also ignore the value returned in limit.
+ */
+ limit = converted_len;
+
+ /* Inplace transliteration */
+ utrans_transUChars(t,
+ ustr, /* text */
+ &converted_len, /* text length */
+ bufsize, /* text buflen */
+ 0, /* start */
+ &limit, /* limit */
+ &ue);
+ if (U_FAILURE(ue)) {
+ return -1;
+ }
+ if (converted_len > bufsize) {
+ /*
+ * In theory this should never happen as the ustr[] array is
+ * allocated with a size twice as big as inbytesleft and
+ * converted_len should be equal to inbytesleft, but you never
+ * know...
+ */
+ errno = EOVERFLOW;
+ return -1;
+ }
+ ustrlen = converted_len;
+
+ /* Convert from UCS2 back to UTF8 */
+ ue = 0;
+ p = u_strToUTF8(*outbuf, /* dst */
+ *outbytesleft, /* dst buflen */
+ &converted_len, /* dst required length */
+ ustr, /* src */
+ ustrlen, /* src length */
+ &ue);
+ if (p == NULL || U_FAILURE(ue)) {
+ return -1;
+ }
+
+ outbut_consumed = converted_len;
+ if (converted_len > *outbytesleft) {
+ /*
+ * The caller's result buffer is too small...
+ */
+ outbut_consumed = *outbytesleft;
+ }
+
+ *inbuf += inbuf_consumed;
+ *inbytesleft -= inbuf_consumed;
+ *outbuf += outbut_consumed;
+ *outbytesleft -= outbut_consumed;
+
+ return converted_len;
+}
+#endif
+
+/**
+ * This is a simple portable iconv() implementation.
+ *
+ * It only knows about a very small number of character sets - just
+ * enough that Samba works on systems that don't have iconv.
+ **/
+_PUBLIC_ size_t smb_iconv(smb_iconv_t cd,
+ const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ /* in many cases we can go direct */
+ if (cd->direct) {
+ return cd->direct(cd->cd_direct,
+ inbuf, inbytesleft, outbuf, outbytesleft);
+ }
+
+ /* otherwise we have to do it chunks at a time */
+ {
+#ifndef SMB_ICONV_BUFSIZE
+#define SMB_ICONV_BUFSIZE 2048
+#endif
+ size_t bufsize;
+ char cvtbuf[SMB_ICONV_BUFSIZE];
+
+ while (*inbytesleft > 0) {
+ char *bufp1 = cvtbuf;
+ const char *bufp2 = cvtbuf;
+ int saved_errno = errno;
+ bool pull_failed = false;
+ bufsize = SMB_ICONV_BUFSIZE;
+
+ if (cd->pull(cd->cd_pull,
+ inbuf, inbytesleft, &bufp1, &bufsize) == -1
+ && errno != E2BIG) {
+ saved_errno = errno;
+ pull_failed = true;
+ }
+
+ bufsize = SMB_ICONV_BUFSIZE - bufsize;
+
+ if (cd->push(cd->cd_push,
+ &bufp2, &bufsize,
+ outbuf, outbytesleft) == -1) {
+ return -1;
+ } else if (pull_failed) {
+ /* We want the pull errno if possible */
+ errno = saved_errno;
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static bool is_utf16(const char *name)
+{
+ return strcasecmp(name, "UCS-2LE") == 0 ||
+ strcasecmp(name, "UTF-16LE") == 0;
+}
+
+static int smb_iconv_t_destructor(smb_iconv_t hwd)
+{
+#ifdef HAVE_ICU_I18N
+ /*
+ * This has to come first, as the cd_direct member won't be an iconv
+ * handle and must not be passed to iconv_close().
+ */
+ if (hwd->direct == sys_uconv) {
+ utrans_close(hwd->cd_direct);
+ return 0;
+ }
+#endif
+#ifdef HAVE_NATIVE_ICONV
+ if (hwd->cd_pull != NULL && hwd->cd_pull != (iconv_t)-1)
+ iconv_close(hwd->cd_pull);
+ if (hwd->cd_push != NULL && hwd->cd_push != (iconv_t)-1)
+ iconv_close(hwd->cd_push);
+ if (hwd->cd_direct != NULL && hwd->cd_direct != (iconv_t)-1)
+ iconv_close(hwd->cd_direct);
+#endif
+
+ return 0;
+}
+
+_PUBLIC_ smb_iconv_t smb_iconv_open_ex(TALLOC_CTX *mem_ctx, const char *tocode,
+ const char *fromcode, bool use_builtin_handlers)
+{
+ smb_iconv_t ret;
+ const struct charset_functions *from=NULL, *to=NULL;
+ int i;
+
+ ret = (smb_iconv_t)talloc_named(mem_ctx,
+ sizeof(*ret),
+ "iconv(%s,%s)", tocode, fromcode);
+ if (!ret) {
+ errno = ENOMEM;
+ return (smb_iconv_t)-1;
+ }
+ memset(ret, 0, sizeof(*ret));
+ talloc_set_destructor(ret, smb_iconv_t_destructor);
+
+ /* check for the simplest null conversion */
+ if (strcmp(fromcode, tocode) == 0) {
+ ret->direct = iconv_copy;
+ return ret;
+ }
+
+ /* check if we have a builtin function for this conversion */
+ for (i=0;i<ARRAY_SIZE(builtin_functions);i++) {
+ if (strcasecmp(fromcode, builtin_functions[i].name) == 0) {
+ if (use_builtin_handlers || builtin_functions[i].samba_internal_charset) {
+ from = &builtin_functions[i];
+ }
+ }
+ if (strcasecmp(tocode, builtin_functions[i].name) == 0) {
+ if (use_builtin_handlers || builtin_functions[i].samba_internal_charset) {
+ to = &builtin_functions[i];
+ }
+ }
+ }
+
+#ifdef HAVE_NATIVE_ICONV
+ /* the from and to variables indicate a samba module or
+ * internal conversion, ret->pull and ret->push are
+ * initialised only in this block for iconv based
+ * conversions */
+
+ if (from == NULL) {
+ ret->cd_pull = iconv_open("UTF-16LE", fromcode);
+ if (ret->cd_pull == (iconv_t)-1)
+ ret->cd_pull = iconv_open("UCS-2LE", fromcode);
+ if (ret->cd_pull != (iconv_t)-1) {
+ ret->pull = sys_iconv;
+ }
+ }
+
+ if (to == NULL) {
+ ret->cd_push = iconv_open(tocode, "UTF-16LE");
+ if (ret->cd_push == (iconv_t)-1)
+ ret->cd_push = iconv_open(tocode, "UCS-2LE");
+ if (ret->cd_push != (iconv_t)-1) {
+ ret->push = sys_iconv;
+ }
+ }
+#endif
+
+#ifdef HAVE_ICU_I18N
+ if (strcasecmp(fromcode, "UTF8-NFD") == 0 &&
+ strcasecmp(tocode, "UTF8-NFC") == 0)
+ {
+ U_STRING_DECL(t, "any-nfc", 7);
+ UErrorCode ue = 0;
+
+ U_STRING_INIT(t, "any-nfc", 7);
+
+ ret->cd_direct = utrans_openU(t,
+ strlen("any-nfc"),
+ UTRANS_FORWARD,
+ NULL,
+ 0,
+ NULL,
+ &ue);
+ if (U_FAILURE(ue)) {
+ return (smb_iconv_t)-1;
+ }
+ ret->direct = sys_uconv;
+ return ret;
+ }
+
+ if (strcasecmp(fromcode, "UTF8-NFC") == 0 &&
+ strcasecmp(tocode, "UTF8-NFD") == 0)
+ {
+ U_STRING_DECL(tname, "any-nfd", 7);
+ UErrorCode ue = 0;
+
+ U_STRING_INIT(tname, "any-nfd", 7);
+
+ ret->cd_direct = utrans_openU(tname,
+ 7,
+ UTRANS_FORWARD,
+ NULL,
+ 0,
+ NULL,
+ &ue);
+ if (U_FAILURE(ue)) {
+ return (smb_iconv_t)-1;
+ }
+ ret->direct = sys_uconv;
+ return ret;
+ }
+#endif
+
+ if (ret->pull == NULL && from == NULL) {
+ goto failed;
+ }
+
+ if (ret->push == NULL && to == NULL) {
+ goto failed;
+ }
+
+ /* check for conversion to/from ucs2 */
+ if (is_utf16(fromcode) && to) {
+ ret->direct = to->push;
+ return ret;
+ }
+ if (is_utf16(tocode) && from) {
+ ret->direct = from->pull;
+ return ret;
+ }
+
+#ifdef HAVE_NATIVE_ICONV
+ if (is_utf16(fromcode)) {
+ ret->direct = sys_iconv;
+ ret->cd_direct = ret->cd_push;
+ ret->cd_push = NULL;
+ return ret;
+ }
+ if (is_utf16(tocode)) {
+ ret->direct = sys_iconv;
+ ret->cd_direct = ret->cd_pull;
+ ret->cd_pull = NULL;
+ return ret;
+ }
+#endif
+
+ /* the general case has to go via a buffer */
+ if (!ret->pull) ret->pull = from->pull;
+ if (!ret->push) ret->push = to->push;
+ return ret;
+
+failed:
+ talloc_free(ret);
+ errno = EINVAL;
+ return (smb_iconv_t)-1;
+}
+
+/*
+ simple iconv_open() wrapper
+ */
+_PUBLIC_ smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode)
+{
+ return smb_iconv_open_ex(NULL, tocode, fromcode, true);
+}
+
+/*
+ simple iconv_close() wrapper
+*/
+_PUBLIC_ int smb_iconv_close(smb_iconv_t cd)
+{
+ talloc_free(cd);
+ return 0;
+}
+
+
+/**********************************************************************
+ the following functions implement the builtin character sets in Samba
+ and also the "test" character sets that are designed to test
+ multi-byte character set support for english users
+***********************************************************************/
+
+/*
+ this takes an ASCII sequence and produces a UTF16 sequence
+
+ The first 127 codepoints of latin1 matches the first 127 codepoints
+ of unicode, and so can be put into the first byte of UTF16LE
+
+ */
+
+static size_t ascii_pull(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ while (*inbytesleft >= 1 && *outbytesleft >= 2) {
+ if (((*inbuf)[0] & 0x7F) != (*inbuf)[0]) {
+ /* If this is multi-byte, then it isn't legal ASCII */
+ errno = EILSEQ;
+ return -1;
+ }
+ (*outbuf)[0] = (*inbuf)[0];
+ (*outbuf)[1] = 0;
+ (*inbytesleft) -= 1;
+ (*outbytesleft) -= 2;
+ (*inbuf) += 1;
+ (*outbuf) += 2;
+ }
+
+ if (*inbytesleft > 0) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ this takes a UTF16 sequence and produces an ASCII sequence
+
+ The first 127 codepoints of ASCII matches the first 127 codepoints
+ of unicode, and so can be read directly from the first byte of UTF16LE
+
+ */
+static size_t ascii_push(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ int ir_count=0;
+
+ while (*inbytesleft >= 2 && *outbytesleft >= 1) {
+ if (((*inbuf)[0] & 0x7F) != (*inbuf)[0] ||
+ (*inbuf)[1] != 0) {
+ /* If this is multi-byte, then it isn't legal ASCII */
+ errno = EILSEQ;
+ return -1;
+ }
+ (*outbuf)[0] = (*inbuf)[0];
+ (*inbytesleft) -= 2;
+ (*outbytesleft) -= 1;
+ (*inbuf) += 2;
+ (*outbuf) += 1;
+ }
+
+ if (*inbytesleft == 1) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (*inbytesleft > 1) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return ir_count;
+}
+
+/*
+ this takes a latin1/ISO-8859-1 sequence and produces a UTF16 sequence
+
+ The first 256 codepoints of latin1 matches the first 256 codepoints
+ of unicode, and so can be put into the first byte of UTF16LE
+
+ */
+static size_t latin1_pull(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ while (*inbytesleft >= 1 && *outbytesleft >= 2) {
+ (*outbuf)[0] = (*inbuf)[0];
+ (*outbuf)[1] = 0;
+ (*inbytesleft) -= 1;
+ (*outbytesleft) -= 2;
+ (*inbuf) += 1;
+ (*outbuf) += 2;
+ }
+
+ if (*inbytesleft > 0) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ this takes a UTF16 sequence and produces a latin1/ISO-8859-1 sequence
+
+ The first 256 codepoints of latin1 matches the first 256 codepoints
+ of unicode, and so can be read directly from the first byte of UTF16LE
+
+ */
+static size_t latin1_push(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ int ir_count=0;
+
+ while (*inbytesleft >= 2 && *outbytesleft >= 1) {
+ (*outbuf)[0] = (*inbuf)[0];
+ if ((*inbuf)[1] != 0) {
+ /* If this is multi-byte, then it isn't legal latin1 */
+ errno = EILSEQ;
+ return -1;
+ }
+ (*inbytesleft) -= 2;
+ (*outbytesleft) -= 1;
+ (*inbuf) += 2;
+ (*outbuf) += 1;
+ }
+
+ if (*inbytesleft == 1) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (*inbytesleft > 1) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return ir_count;
+}
+
+static size_t ucs2hex_pull(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ while (*inbytesleft >= 1 && *outbytesleft >= 2) {
+ uint8_t hi = 0, lo = 0;
+ bool ok;
+
+ if ((*inbuf)[0] != '@') {
+ /* seven bit ascii case */
+ (*outbuf)[0] = (*inbuf)[0];
+ (*outbuf)[1] = 0;
+ (*inbytesleft) -= 1;
+ (*outbytesleft) -= 2;
+ (*inbuf) += 1;
+ (*outbuf) += 2;
+ continue;
+ }
+ /* it's a hex character */
+ if (*inbytesleft < 5) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ ok = hex_byte(&(*inbuf)[1], &hi) && hex_byte(&(*inbuf)[3], &lo);
+ if (!ok) {
+ errno = EILSEQ;
+ return -1;
+ }
+
+ (*outbuf)[0] = lo;
+ (*outbuf)[1] = hi;
+ (*inbytesleft) -= 5;
+ (*outbytesleft) -= 2;
+ (*inbuf) += 5;
+ (*outbuf) += 2;
+ }
+
+ if (*inbytesleft > 0) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return 0;
+}
+
+static size_t ucs2hex_push(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ while (*inbytesleft >= 2 && *outbytesleft >= 1) {
+ char buf[6];
+
+ if ((*inbuf)[1] == 0 &&
+ ((*inbuf)[0] & 0x80) == 0 &&
+ (*inbuf)[0] != '@') {
+ (*outbuf)[0] = (*inbuf)[0];
+ (*inbytesleft) -= 2;
+ (*outbytesleft) -= 1;
+ (*inbuf) += 2;
+ (*outbuf) += 1;
+ continue;
+ }
+ if (*outbytesleft < 5) {
+ errno = E2BIG;
+ return -1;
+ }
+ snprintf(buf, 6, "@%04x", SVAL(*inbuf, 0));
+ memcpy(*outbuf, buf, 5);
+ (*inbytesleft) -= 2;
+ (*outbytesleft) -= 5;
+ (*inbuf) += 2;
+ (*outbuf) += 5;
+ }
+
+ if (*inbytesleft == 1) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (*inbytesleft > 1) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return 0;
+}
+
+static size_t iconv_swab(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ int n;
+
+ n = MIN(*inbytesleft, *outbytesleft);
+
+ swab(*inbuf, *outbuf, (n&~1));
+ if (n&1) {
+ (*outbuf)[n-1] = 0;
+ }
+
+ (*inbytesleft) -= n;
+ (*outbytesleft) -= n;
+ (*inbuf) += n;
+ (*outbuf) += n;
+
+ if (*inbytesleft > 0) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static size_t iconv_copy(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ int n;
+
+ n = MIN(*inbytesleft, *outbytesleft);
+
+ memmove(*outbuf, *inbuf, n);
+
+ (*inbytesleft) -= n;
+ (*outbytesleft) -= n;
+ (*inbuf) += n;
+ (*outbuf) += n;
+
+ if (*inbytesleft > 0) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ this takes a UTF8 sequence and produces a UTF16 sequence
+ */
+static size_t utf8_pull(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ size_t in_left=*inbytesleft, out_left=*outbytesleft;
+ const uint8_t *c = (const uint8_t *)*inbuf;
+ uint8_t *uc = (uint8_t *)*outbuf;
+
+ while (in_left >= 1 && out_left >= 2) {
+ if ((c[0] & 0x80) == 0) {
+ uc[0] = c[0];
+ uc[1] = 0;
+ c += 1;
+ in_left -= 1;
+ out_left -= 2;
+ uc += 2;
+ continue;
+ }
+
+ if ((c[0] & 0xe0) == 0xc0) {
+ if (in_left < 2 ||
+ (c[1] & 0xc0) != 0x80) {
+ errno = EILSEQ;
+ goto error;
+ }
+ uc[1] = (c[0]>>2) & 0x7;
+ uc[0] = (c[0]<<6) | (c[1]&0x3f);
+ if (uc[1] == 0 && uc[0] < 0x80) {
+ /* this should have been a single byte */
+ errno = EILSEQ;
+ goto error;
+ }
+ c += 2;
+ in_left -= 2;
+ out_left -= 2;
+ uc += 2;
+ continue;
+ }
+
+ if ((c[0] & 0xf0) == 0xe0) {
+ unsigned int codepoint;
+ if (in_left < 3 ||
+ (c[1] & 0xc0) != 0x80 ||
+ (c[2] & 0xc0) != 0x80) {
+ errno = EILSEQ;
+ goto error;
+ }
+ codepoint = ((c[2] & 0x3f) |
+ ((c[1] & 0x3f) << 6) |
+ ((c[0] & 0x0f) << 12));
+
+ if (codepoint < 0x800) {
+ /* this should be a 1 or 2 byte sequence */
+ errno = EILSEQ;
+ goto error;
+ }
+ if (codepoint >= 0xd800 && codepoint <= 0xdfff) {
+ /*
+ * This is an invalid codepoint, per
+ * RFC3629, as it encodes part of a
+ * UTF-16 surrogate pair for a
+ * character over U+10000, which ought
+ * to have been encoded as a four byte
+ * utf-8 sequence.
+ *
+ * Prior to Vista, Windows might
+ * sometimes produce invalid strings
+ * where a utf-16 sequence containing
+ * surrogate pairs was converted
+ * "verbatim" into utf-8, instead of
+ * encoding the actual codepoint. This
+ * format is sometimes called "WTF-8".
+ *
+ * If we were to support that, we'd
+ * have a branch here for the case
+ * where the codepoint is between
+ * 0xd800 and 0xdbff (a "high
+ * surrogate"), and read a *six*
+ * character sequence from there which
+ * would include a low surrogate. But
+ * that would undermine the
+ * hard-learnt principle that each
+ * character should only have one
+ * encoding.
+ */
+ errno = EILSEQ;
+ goto error;
+ }
+
+ uc[0] = codepoint & 0xff;
+ uc[1] = codepoint >> 8;
+ c += 3;
+ in_left -= 3;
+ out_left -= 2;
+ uc += 2;
+ continue;
+ }
+
+ if ((c[0] & 0xf8) == 0xf0) {
+ unsigned int codepoint;
+ if (in_left < 4 ||
+ (c[1] & 0xc0) != 0x80 ||
+ (c[2] & 0xc0) != 0x80 ||
+ (c[3] & 0xc0) != 0x80) {
+ errno = EILSEQ;
+ goto error;
+ }
+ codepoint =
+ (c[3]&0x3f) |
+ ((c[2]&0x3f)<<6) |
+ ((c[1]&0x3f)<<12) |
+ ((c[0]&0x7)<<18);
+ if (codepoint < 0x10000) {
+ /* reject UTF-8 characters that are not
+ minimally packed */
+ errno = EILSEQ;
+ goto error;
+ }
+ if (codepoint > 0x10ffff) {
+ /*
+ * Unicode stops at 0x10ffff, and if
+ * we ignore that, we'll end up
+ * encoding the wrong characters in
+ * the surrogate pair.
+ */
+ errno = EILSEQ;
+ goto error;
+ }
+
+ codepoint -= 0x10000;
+
+ if (out_left < 4) {
+ errno = E2BIG;
+ goto error;
+ }
+
+ uc[0] = (codepoint>>10) & 0xFF;
+ uc[1] = (codepoint>>18) | 0xd8;
+ uc[2] = codepoint & 0xFF;
+ uc[3] = ((codepoint>>8) & 0x3) | 0xdc;
+ c += 4;
+ in_left -= 4;
+ out_left -= 4;
+ uc += 4;
+ continue;
+ }
+
+ /* we don't handle 5 byte sequences */
+ errno = EINVAL;
+ goto error;
+ }
+
+ if (in_left > 0) {
+ errno = E2BIG;
+ goto error;
+ }
+
+ *inbytesleft = in_left;
+ *outbytesleft = out_left;
+ *inbuf = (const char *)c;
+ *outbuf = (char *)uc;
+ return 0;
+
+error:
+ *inbytesleft = in_left;
+ *outbytesleft = out_left;
+ *inbuf = (const char *)c;
+ *outbuf = (char *)uc;
+ return -1;
+}
+
+
+/*
+ this takes a UTF16 sequence and produces a UTF8 sequence
+ */
+static size_t utf8_push(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ size_t in_left=*inbytesleft, out_left=*outbytesleft;
+ uint8_t *c = (uint8_t *)*outbuf;
+ const uint8_t *uc = (const uint8_t *)*inbuf;
+
+ while (in_left >= 2 && out_left >= 1) {
+ unsigned int codepoint;
+
+ if (uc[1] == 0 && !(uc[0] & 0x80)) {
+ /* simplest case */
+ c[0] = uc[0];
+ in_left -= 2;
+ out_left -= 1;
+ uc += 2;
+ c += 1;
+ continue;
+ }
+
+ if ((uc[1]&0xf8) == 0) {
+ /* next simplest case */
+ if (out_left < 2) {
+ errno = E2BIG;
+ goto error;
+ }
+ c[0] = 0xc0 | (uc[0]>>6) | (uc[1]<<2);
+ c[1] = 0x80 | (uc[0] & 0x3f);
+ in_left -= 2;
+ out_left -= 2;
+ uc += 2;
+ c += 2;
+ continue;
+ }
+
+ if ((uc[1] & 0xfc) == 0xdc) {
+ errno = EILSEQ;
+#ifndef HAVE_ICONV_ERRNO_ILLEGAL_MULTIBYTE
+ if (in_left < 4) {
+ errno = EINVAL;
+ }
+#endif
+ goto error;
+ }
+
+ if ((uc[1] & 0xfc) != 0xd8) {
+ codepoint = uc[0] | (uc[1]<<8);
+ if (out_left < 3) {
+ errno = E2BIG;
+ goto error;
+ }
+ c[0] = 0xe0 | (codepoint >> 12);
+ c[1] = 0x80 | ((codepoint >> 6) & 0x3f);
+ c[2] = 0x80 | (codepoint & 0x3f);
+
+ in_left -= 2;
+ out_left -= 3;
+ uc += 2;
+ c += 3;
+ continue;
+ }
+
+ /* its the first part of a 4 byte sequence */
+ if (in_left < 4) {
+ errno = EINVAL;
+ goto error;
+ }
+ if ((uc[3] & 0xfc) != 0xdc) {
+ errno = EILSEQ;
+ goto error;
+ }
+ codepoint = 0x10000 + (uc[2] | ((uc[3] & 0x3)<<8) |
+ (uc[0]<<10) | ((uc[1] & 0x3)<<18));
+
+ if (out_left < 4) {
+ errno = E2BIG;
+ goto error;
+ }
+ c[0] = 0xf0 | (codepoint >> 18);
+ c[1] = 0x80 | ((codepoint >> 12) & 0x3f);
+ c[2] = 0x80 | ((codepoint >> 6) & 0x3f);
+ c[3] = 0x80 | (codepoint & 0x3f);
+
+ in_left -= 4;
+ out_left -= 4;
+ uc += 4;
+ c += 4;
+ }
+
+ if (in_left == 1) {
+ errno = EINVAL;
+ goto error;
+ }
+
+ if (in_left > 1) {
+ errno = E2BIG;
+ goto error;
+ }
+
+ *inbytesleft = in_left;
+ *outbytesleft = out_left;
+ *inbuf = (const char *)uc;
+ *outbuf = (char *)c;
+
+ return 0;
+
+error:
+ *inbytesleft = in_left;
+ *outbytesleft = out_left;
+ *inbuf = (const char *)uc;
+ *outbuf = (char *)c;
+ return -1;
+}
+
+
+/*
+ this takes a UTF16 munged sequence, modifies it according to the
+ string2key rules, and produces a UTF16 sequence
+
+The rules are:
+
+ 1) any 0x0000 characters are mapped to 0x0001
+
+ 2) convert any instance of 0xD800 - 0xDBFF (high surrogate)
+ without an immediately following 0xDC00 - 0x0xDFFF (low surrogate) to
+ U+FFFD (OBJECT REPLACEMENT CHARACTER).
+
+ 3) the same for any low surrogate that was not preceded by a high surrogate.
+
+ */
+static size_t utf16_munged_pull(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ size_t in_left=*inbytesleft, out_left=*outbytesleft;
+ uint8_t *c = (uint8_t *)*outbuf;
+ const uint8_t *uc = (const uint8_t *)*inbuf;
+
+ while (in_left >= 2 && out_left >= 2) {
+ unsigned int codepoint = uc[0] | (uc[1]<<8);
+
+ if (codepoint == 0) {
+ codepoint = 1;
+ }
+
+ if ((codepoint & 0xfc00) == 0xd800) {
+ /* a high surrogate */
+ unsigned int codepoint2;
+ if (in_left < 4) {
+ codepoint = 0xfffd;
+ goto codepoint16;
+ }
+ codepoint2 = uc[2] | (uc[3]<<8);
+ if ((codepoint2 & 0xfc00) != 0xdc00) {
+ /* high surrogate not followed by low
+ surrogate: convert to 0xfffd */
+ codepoint = 0xfffd;
+ goto codepoint16;
+ }
+ if (out_left < 4) {
+ errno = E2BIG;
+ goto error;
+ }
+ memcpy(c, uc, 4);
+ in_left -= 4;
+ out_left -= 4;
+ uc += 4;
+ c += 4;
+ continue;
+ }
+
+ if ((codepoint & 0xfc00) == 0xdc00) {
+ /* low surrogate not preceded by high
+ surrogate: convert to 0xfffd */
+ codepoint = 0xfffd;
+ }
+
+ codepoint16:
+ c[0] = codepoint & 0xFF;
+ c[1] = (codepoint>>8) & 0xFF;
+
+ in_left -= 2;
+ out_left -= 2;
+ uc += 2;
+ c += 2;
+ continue;
+ }
+
+ if (in_left == 1) {
+ errno = EINVAL;
+ goto error;
+ }
+
+ if (in_left > 1) {
+ errno = E2BIG;
+ goto error;
+ }
+
+ *inbytesleft = in_left;
+ *outbytesleft = out_left;
+ *inbuf = (const char *)uc;
+ *outbuf = (char *)c;
+
+ return 0;
+
+error:
+ *inbytesleft = in_left;
+ *outbytesleft = out_left;
+ *inbuf = (const char *)uc;
+ *outbuf = (char *)c;
+ return -1;
+}
+
+
+
diff --git a/lib/util/charset/pull_push.c b/lib/util/charset/pull_push.c
new file mode 100644
index 0000000..8ec6498
--- /dev/null
+++ b/lib/util/charset/pull_push.c
@@ -0,0 +1,160 @@
+/*
+ Unix SMB/CIFS implementation.
+ Character set conversion Extensions
+ Copyright (C) Igor Vergeichik <iverg@mail.ru> 2001
+ Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Martin Pool 2003
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "replace.h"
+#include "system/locale.h"
+#include "charset.h"
+
+/**
+ * Copy a string from a unix char* src to a UCS2 destination,
+ * allocating a buffer using talloc().
+ *
+ * @param dest always set at least to NULL
+ * @param converted_size set to the number of bytes occupied by the string in
+ * the destination on success.
+ *
+ * @return true if new buffer was correctly allocated, and string was
+ * converted.
+ **/
+bool push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src,
+ size_t *converted_size)
+{
+ size_t src_len = strlen(src)+1;
+
+ *dest = NULL;
+ return convert_string_talloc(ctx, CH_UNIX, CH_UTF16LE, src, src_len,
+ (void **)dest, converted_size);
+}
+
+/**
+ * @brief Create a UTF-8 string from a unix charset string.
+ *
+ * The resulting UTF-8 string is talloc'ed.
+ *
+ * @param[in] ctx The talloc memory context.
+ *
+ * @param[in] dest A pointer to store the pointer to the talloc'ed UTF-8
+ * string.
+ *
+ * @param[in] src The unix charset string to convert.
+ *
+ * @param[in] converted_size A pointer to store the length of the talloc'ed
+ * UTF-8 string including the nul-termination bytes.
+ *
+ * The destination string should be free'd using talloc_free() if no longer
+ * needed.
+ *
+ * @return True on success, false otherwise.
+ */
+bool push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
+ size_t *converted_size)
+{
+ size_t src_len = strlen(src)+1;
+
+ *dest = NULL;
+ return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len,
+ (void**)dest, converted_size);
+}
+
+/**
+ * Copy a string from a unix char* src to an ASCII destination,
+ * allocating a buffer using talloc().
+ *
+ * @param dest always set at least to NULL
+ *
+ * @param converted_size The number of bytes occupied by the string in the destination
+ * @returns boolean indicating if the conversion was successful
+ **/
+bool push_ascii_talloc(TALLOC_CTX *mem_ctx, char **dest, const char *src, size_t *converted_size)
+{
+ size_t src_len = strlen(src)+1;
+
+ *dest = NULL;
+ return convert_string_talloc(mem_ctx, CH_UNIX, CH_DOS, src, src_len,
+ (void **)dest, converted_size);
+}
+
+/**
+ * Copy a string from a UCS2 src to a unix char * destination, allocating a buffer using talloc
+ *
+ * @param dest always set at least to NULL
+ * @param converted_size set to the number of bytes occupied by the string in
+ * the destination on success.
+ *
+ * @return true if new buffer was correctly allocated, and string was
+ * converted.
+ **/
+
+bool pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const smb_ucs2_t *src,
+ size_t *converted_size)
+{
+ size_t src_len = (strlen_w(src)+1) * sizeof(smb_ucs2_t);
+
+ *dest = NULL;
+ return convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX, src, src_len,
+ (void **)dest, converted_size);
+}
+
+
+/**
+ * Copy a string from a UTF-8 src to a unix char * destination, allocating a buffer using talloc
+ *
+ * @param dest always set at least to NULL
+ * @param converted_size set to the number of bytes occupied by the string in
+ * the destination on success.
+ *
+ * @return true if new buffer was correctly allocated, and string was
+ * converted.
+ **/
+
+bool pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
+ size_t *converted_size)
+{
+ size_t src_len = strlen(src)+1;
+
+ *dest = NULL;
+ return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len,
+ (void **)dest, converted_size);
+}
+
+
+/**
+ * Copy a string from a DOS src to a unix char * destination, allocating a buffer using talloc
+ *
+ * @param dest always set at least to NULL
+ * @param converted_size set to the number of bytes occupied by the string in
+ * the destination on success.
+ *
+ * @return true if new buffer was correctly allocated, and string was
+ * converted.
+ **/
+
+bool pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src,
+ size_t *converted_size)
+{
+ size_t src_len = strlen(src)+1;
+
+ *dest = NULL;
+ return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len,
+ (void **)dest, converted_size);
+}
diff --git a/lib/util/charset/tests/charset.c b/lib/util/charset/tests/charset.c
new file mode 100644
index 0000000..547dc51
--- /dev/null
+++ b/lib/util/charset/tests/charset.c
@@ -0,0 +1,342 @@
+/*
+ Unix SMB/CIFS implementation.
+ test suite for the charcnv functions
+
+ Copyright (C) Jelmer Vernooij 2007
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+
+#undef strcasecmp
+#undef strncasecmp
+
+struct torture_suite *torture_local_charset(TALLOC_CTX *mem_ctx);
+
+static bool test_toupper_m(struct torture_context *tctx)
+{
+ torture_assert_int_equal(tctx, toupper_m('c'), 'C', "c");
+ torture_assert_int_equal(tctx, toupper_m('Z'), 'Z', "z");
+ torture_assert_int_equal(tctx, toupper_m(0xFFFF4565), 0xFFFF4565, "0xFFFF4565");
+ return true;
+}
+
+static bool test_tolower_m(struct torture_context *tctx)
+{
+ torture_assert_int_equal(tctx, tolower_m('C'), 'c', "c");
+ torture_assert_int_equal(tctx, tolower_m('z'), 'z', "z");
+ torture_assert_int_equal(tctx, tolower_m(0xFFFF4565), 0xFFFF4565, "0xFFFF4565");
+ return true;
+}
+
+static bool test_codepoint_cmpi(struct torture_context *tctx)
+{
+ torture_assert_int_equal(tctx, codepoint_cmpi('a', 'a'), 0, "same char");
+ torture_assert_int_equal(tctx, codepoint_cmpi('A', 'a'), 0, "upcase version");
+ torture_assert_int_equal(tctx, codepoint_cmpi('b', 'a'), 1, "right diff");
+ torture_assert_int_equal(tctx, codepoint_cmpi('a', 'b'), -1, "right diff");
+ return true;
+}
+
+static bool test_strcasecmp(struct torture_context *tctx)
+{
+ torture_assert_int_equal(tctx, strcasecmp("foo", "bar"), 4, "different strings both lower");
+ torture_assert_int_equal(tctx, strcasecmp("foo", "Bar"), 4, "different strings lower/upper");
+ torture_assert_int_equal(tctx, strcasecmp("Foo", "bar"), 4, "different strings upper/lower");
+ torture_assert_int_equal(tctx, strcasecmp("AFoo", "_bar"), 2, "different strings upper/lower");
+ torture_assert_int_equal(tctx, strcasecmp("foo", "foo"), 0, "same case strings");
+ torture_assert_int_equal(tctx, strcasecmp("foo", "Foo"), 0, "different case strings");
+
+ /*
+ * Note that strcasecmp() doesn't allow NULL arguments
+ */
+ return true;
+}
+
+static bool test_strcasecmp_m(struct torture_context *tctx)
+{
+ /* file.{accented e} in iso8859-1 */
+ const char file_iso8859_1[7] = { 0x66, 0x69, 0x6c, 0x65, 0x2d, 0xe9, 0 };
+ /* file.{accented e} in utf8 */
+ const char file_utf8[8] = { 0x66, 0x69, 0x6c, 0x65, 0x2d, 0xc3, 0xa9, 0 };
+ torture_assert_int_equal(tctx, strcasecmp_m("foo", "bar"), 4, "different strings both lower");
+ torture_assert_int_equal(tctx, strcasecmp_m("foo", "Bar"), 4, "different strings lower/upper");
+ torture_assert_int_equal(tctx, strcasecmp_m("Foo", "bar"), 4, "different strings upper/lower");
+ torture_assert_int_equal(tctx, strcasecmp_m("AFoo", "_bar"), 2, "different strings upper/lower");
+ torture_assert_int_equal(tctx, strcasecmp_m("foo", "foo"), 0, "same case strings");
+ torture_assert_int_equal(tctx, strcasecmp_m("foo", "Foo"), 0, "different case strings");
+ torture_assert_int_equal(tctx, strcasecmp_m(NULL, "Foo"), -1, "one NULL");
+ torture_assert_int_equal(tctx, strcasecmp_m("foo", NULL), 1, "other NULL");
+ torture_assert_int_equal(tctx, strcasecmp_m(NULL, NULL), 0, "both NULL");
+ torture_assert_int_equal(tctx, strcasecmp_m(file_iso8859_1, file_utf8), 38,
+ "file.{accented e} should differ");
+ return true;
+}
+
+
+static bool test_strequal_m(struct torture_context *tctx)
+{
+ torture_assert(tctx, !strequal_m("foo", "bar"), "different strings");
+ torture_assert(tctx, strequal_m("foo", "foo"), "same case strings");
+ torture_assert(tctx, strequal_m("foo", "Foo"), "different case strings");
+ torture_assert(tctx, !strequal_m(NULL, "Foo"), "one NULL");
+ torture_assert(tctx, !strequal_m("foo", NULL), "other NULL");
+ torture_assert(tctx, strequal_m(NULL, NULL), "both NULL");
+ return true;
+}
+
+static bool test_strcsequal(struct torture_context *tctx)
+{
+ torture_assert(tctx, !strcsequal("foo", "bar"), "different strings");
+ torture_assert(tctx, strcsequal("foo", "foo"), "same case strings");
+ torture_assert(tctx, !strcsequal("foo", "Foo"), "different case strings");
+ torture_assert(tctx, !strcsequal(NULL, "Foo"), "one NULL");
+ torture_assert(tctx, !strcsequal("foo", NULL), "other NULL");
+ torture_assert(tctx, strcsequal(NULL, NULL), "both NULL");
+ return true;
+}
+
+static bool test_string_replace_m(struct torture_context *tctx)
+{
+ char data[6] = "bla";
+ string_replace_m(data, 'b', 'c');
+ torture_assert_str_equal(tctx, data, "cla", "first char replaced");
+ memcpy(data, "bab", 4);
+ string_replace_m(data, 'b', 'c');
+ torture_assert_str_equal(tctx, data, "cac", "other chars replaced");
+ memcpy(data, "bba", 4);
+ string_replace_m(data, 'b', 'c');
+ torture_assert_str_equal(tctx, data, "cca", "other chars replaced");
+ memcpy(data, "blala", 6);
+ string_replace_m(data, 'o', 'c');
+ torture_assert_str_equal(tctx, data, "blala", "no chars replaced");
+ string_replace_m(NULL, 'b', 'c');
+ return true;
+}
+
+static bool test_strncasecmp(struct torture_context *tctx)
+{
+ torture_assert_int_equal(tctx, strncasecmp("foo", "bar", 3), 4, "different strings both lower");
+ torture_assert_int_equal(tctx, strncasecmp("foo", "Bar", 3), 4, "different strings lower/upper");
+ torture_assert_int_equal(tctx, strncasecmp("Foo", "bar", 3), 4, "different strings upper/lower");
+ torture_assert_int_equal(tctx, strncasecmp("AFoo", "_bar", 4), 2, "different strings upper/lower");
+ torture_assert_int_equal(tctx, strncasecmp("foo", "foo", 3), 0, "same case strings");
+ torture_assert_int_equal(tctx, strncasecmp("foo", "Foo", 3), 0, "different case strings");
+ torture_assert_int_equal(tctx, strncasecmp("fool", "Foo", 3),0, "different case strings");
+ torture_assert_int_equal(tctx, strncasecmp("fool", "Fool", 40), 0, "over size");
+ torture_assert_int_equal(tctx, strncasecmp("BLA", "Fool", 0),0, "empty");
+
+ /*
+ * Note that strncasecmp() doesn't allow NULL arguments
+ */
+ return true;
+}
+
+static bool test_strncasecmp_m(struct torture_context *tctx)
+{
+ /* file.{accented e} in iso8859-1 */
+ const char file_iso8859_1[7] = { 0x66, 0x69, 0x6c, 0x65, 0x2d, 0xe9, 0 };
+ /* file.{accented e} in utf8 */
+ const char file_utf8[8] = { 0x66, 0x69, 0x6c, 0x65, 0x2d, 0xc3, 0xa9, 0 };
+ torture_assert_int_equal(tctx, strncasecmp_m("foo", "bar", 3), 4, "different strings both lower");
+ torture_assert_int_equal(tctx, strncasecmp_m("foo", "Bar", 3), 4, "different strings lower/upper");
+ torture_assert_int_equal(tctx, strncasecmp_m("Foo", "bar", 3), 4, "different strings upper/lower");
+ torture_assert_int_equal(tctx, strncasecmp_m("AFoo", "_bar", 4), 2, "different strings upper/lower");
+ torture_assert_int_equal(tctx, strncasecmp_m("foo", "foo", 3), 0, "same case strings");
+ torture_assert_int_equal(tctx, strncasecmp_m("foo", "Foo", 3), 0, "different case strings");
+ torture_assert_int_equal(tctx, strncasecmp_m("fool", "Foo", 3),0, "different case strings");
+ torture_assert_int_equal(tctx, strncasecmp_m("fool", "Fool", 40), 0, "over size");
+ torture_assert_int_equal(tctx, strncasecmp_m("BLA", "Fool", 0),0, "empty");
+ torture_assert_int_equal(tctx, strncasecmp_m(NULL, "Foo", 3), -1, "one NULL");
+ torture_assert_int_equal(tctx, strncasecmp_m("foo", NULL, 3), 1, "other NULL");
+ torture_assert_int_equal(tctx, strncasecmp_m(NULL, NULL, 3), 0, "both NULL");
+ torture_assert_int_equal(tctx, strncasecmp_m(file_iso8859_1, file_utf8, 6), 38,
+ "file.{accented e} should differ");
+ return true;
+}
+
+static bool test_next_token_null(struct torture_context *tctx)
+{
+ char buf[20];
+ torture_assert(tctx, !next_token(NULL, buf, " ", 20), "null ptr works");
+ return true;
+}
+
+static bool test_next_token(struct torture_context *tctx)
+{
+ const char *teststr = "foo bar bla";
+ char buf[20];
+ torture_assert(tctx, next_token(&teststr, buf, " ", 20), "finding token works");
+ torture_assert_str_equal(tctx, buf, "foo", "token matches");
+ torture_assert_str_equal(tctx, teststr, "bar bla", "ptr modified correctly");
+
+ torture_assert(tctx, next_token(&teststr, buf, " ", 20), "finding token works");
+ torture_assert_str_equal(tctx, buf, "bar", "token matches");
+ torture_assert_str_equal(tctx, teststr, "bla", "ptr modified correctly");
+
+ torture_assert(tctx, next_token(&teststr, buf, " ", 20), "finding token works");
+ torture_assert_str_equal(tctx, buf, "bla", "token matches");
+ torture_assert_str_equal(tctx, teststr, "", "ptr modified correctly");
+
+ torture_assert(tctx, !next_token(&teststr, buf, " ", 20), "finding token doesn't work");
+ return true;
+}
+
+static bool test_next_token_implicit_sep(struct torture_context *tctx)
+{
+ const char *teststr = "foo\tbar\n bla";
+ char buf[20];
+ torture_assert(tctx, next_token(&teststr, buf, NULL, 20), "finding token works");
+ torture_assert_str_equal(tctx, buf, "foo", "token matches");
+ torture_assert_str_equal(tctx, teststr, "bar\n bla", "ptr modified correctly");
+
+ torture_assert(tctx, next_token(&teststr, buf, NULL, 20), "finding token works");
+ torture_assert_str_equal(tctx, buf, "bar", "token matches");
+ torture_assert_str_equal(tctx, teststr, " bla", "ptr modified correctly");
+
+ torture_assert(tctx, next_token(&teststr, buf, NULL, 20), "finding token works");
+ torture_assert_str_equal(tctx, buf, "bla", "token matches");
+ torture_assert_str_equal(tctx, teststr, "", "ptr modified correctly");
+
+ torture_assert(tctx, !next_token(&teststr, buf, NULL, 20), "finding token doesn't work");
+ return true;
+}
+
+static bool test_next_token_seps(struct torture_context *tctx)
+{
+ const char *teststr = ",foo bla";
+ char buf[20];
+ torture_assert(tctx, next_token(&teststr, buf, ",", 20), "finding token works");
+ torture_assert_str_equal(tctx, buf, "foo bla", "token matches");
+ torture_assert_str_equal(tctx, teststr, "", "ptr modified correctly");
+
+ torture_assert(tctx, !next_token(&teststr, buf, ",", 20), "finding token doesn't work");
+ return true;
+}
+
+static bool test_next_token_quotes(struct torture_context *tctx)
+{
+ const char *teststr = "\"foo bar\" bla";
+ char buf[20];
+ torture_assert(tctx, next_token(&teststr, buf, " ", 20), "finding token works");
+ torture_assert_str_equal(tctx, buf, "foo bar", "token matches");
+ torture_assert_str_equal(tctx, teststr, "bla", "ptr modified correctly");
+
+ torture_assert(tctx, next_token(&teststr, buf, " ", 20), "finding token works");
+ torture_assert_str_equal(tctx, buf, "bla", "token matches");
+ torture_assert_str_equal(tctx, teststr, "", "ptr modified correctly");
+
+ torture_assert(tctx, !next_token(&teststr, buf, " ", 20), "finding token doesn't work");
+ return true;
+}
+
+static bool test_next_token_quote_wrong(struct torture_context *tctx)
+{
+ const char *teststr = "\"foo bar bla";
+ char buf[20];
+ torture_assert(tctx, next_token(&teststr, buf, " ", 20), "finding token works");
+ torture_assert_str_equal(tctx, buf, "foo bar bla", "token matches");
+ torture_assert_str_equal(tctx, teststr, "", "ptr modified correctly");
+
+ torture_assert(tctx, !next_token(&teststr, buf, " ", 20), "finding token doesn't work");
+ return true;
+}
+
+static bool test_strlen_m(struct torture_context *tctx)
+{
+ torture_assert_int_equal(tctx, strlen_m("foo"), 3, "simple len");
+ torture_assert_int_equal(tctx, strlen_m("foo\x83l"), 6, "extended len");
+ torture_assert_int_equal(tctx, strlen_m(""), 0, "empty");
+ torture_assert_int_equal(tctx, strlen_m(NULL), 0, "NULL");
+ return true;
+}
+
+static bool test_strlen_m_term(struct torture_context *tctx)
+{
+ torture_assert_int_equal(tctx, strlen_m_term("foo"), 4, "simple len");
+ torture_assert_int_equal(tctx, strlen_m_term("foo\x83l"), 7, "extended len");
+ torture_assert_int_equal(tctx, strlen_m_term(""), 1, "empty");
+ torture_assert_int_equal(tctx, strlen_m_term(NULL), 0, "NULL");
+ return true;
+}
+
+static bool test_strlen_m_term_null(struct torture_context *tctx)
+{
+ torture_assert_int_equal(tctx, strlen_m_term_null("foo"), 4, "simple len");
+ torture_assert_int_equal(tctx, strlen_m_term_null("foo\x83l"), 7, "extended len");
+ torture_assert_int_equal(tctx, strlen_m_term_null(""), 0, "empty");
+ torture_assert_int_equal(tctx, strlen_m_term_null(NULL), 0, "NULL");
+ return true;
+}
+
+static bool test_strhaslower(struct torture_context *tctx)
+{
+ torture_assert(tctx, strhaslower("a"), "one low char");
+ torture_assert(tctx, strhaslower("aB"), "one low, one up char");
+ torture_assert(tctx, !strhaslower("B"), "one up char");
+ torture_assert(tctx, !strhaslower(""), "empty string");
+ torture_assert(tctx, !strhaslower("3"), "one digit");
+ return true;
+}
+
+static bool test_strhasupper(struct torture_context *tctx)
+{
+ torture_assert(tctx, strhasupper("B"), "one up char");
+ torture_assert(tctx, strhasupper("aB"), "one low, one up char");
+ torture_assert(tctx, !strhasupper("a"), "one low char");
+ torture_assert(tctx, !strhasupper(""), "empty string");
+ torture_assert(tctx, !strhasupper("3"), "one digit");
+ return true;
+}
+
+static bool test_count_chars_m(struct torture_context *tctx)
+{
+ torture_assert_int_equal(tctx, count_chars_m("foo", 'o'), 2, "simple");
+ torture_assert_int_equal(tctx, count_chars_m("", 'o'), 0, "empty");
+ torture_assert_int_equal(tctx, count_chars_m("bla", 'o'), 0, "none");
+ torture_assert_int_equal(tctx, count_chars_m("bla", '\0'), 0, "null");
+ return true;
+}
+
+struct torture_suite *torture_local_charset(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "charset");
+
+ torture_suite_add_simple_test(suite, "toupper_m", test_toupper_m);
+ torture_suite_add_simple_test(suite, "tolower_m", test_tolower_m);
+ torture_suite_add_simple_test(suite, "codepoint_cmpi", test_codepoint_cmpi);
+ torture_suite_add_simple_test(suite, "strcasecmp", test_strcasecmp);
+ torture_suite_add_simple_test(suite, "strcasecmp_m", test_strcasecmp_m);
+ torture_suite_add_simple_test(suite, "strequal_m", test_strequal_m);
+ torture_suite_add_simple_test(suite, "strcsequal", test_strcsequal);
+ torture_suite_add_simple_test(suite, "string_replace_m", test_string_replace_m);
+ torture_suite_add_simple_test(suite, "strncasecmp", test_strncasecmp);
+ torture_suite_add_simple_test(suite, "strncasecmp_m", test_strncasecmp_m);
+ torture_suite_add_simple_test(suite, "next_token", test_next_token);
+ torture_suite_add_simple_test(suite, "next_token_null", test_next_token_null);
+ torture_suite_add_simple_test(suite, "next_token_implicit_sep", test_next_token_implicit_sep);
+ torture_suite_add_simple_test(suite, "next_token_quotes", test_next_token_quotes);
+ torture_suite_add_simple_test(suite, "next_token_seps", test_next_token_seps);
+ torture_suite_add_simple_test(suite, "next_token_quote_wrong", test_next_token_quote_wrong);
+ torture_suite_add_simple_test(suite, "strlen_m", test_strlen_m);
+ torture_suite_add_simple_test(suite, "strlen_m_term", test_strlen_m_term);
+ torture_suite_add_simple_test(suite, "strlen_m_term_null", test_strlen_m_term_null);
+ torture_suite_add_simple_test(suite, "strhaslower", test_strhaslower);
+ torture_suite_add_simple_test(suite, "strhasupper", test_strhasupper);
+ torture_suite_add_simple_test(suite, "count_chars_m", test_count_chars_m);
+
+ return suite;
+}
diff --git a/lib/util/charset/tests/convert_string.c b/lib/util/charset/tests/convert_string.c
new file mode 100644
index 0000000..6400ce1
--- /dev/null
+++ b/lib/util/charset/tests/convert_string.c
@@ -0,0 +1,2196 @@
+/*
+ Unix SMB/CIFS implementation.
+ test suite for the charcnv functions
+
+ Copyright (C) Andrew Bartlett 2011
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "lib/util/charset/charset.h"
+#include "param/param.h"
+#include "lib/util/base64.h"
+
+struct torture_suite *torture_local_convert_string_handle(TALLOC_CTX *mem_ctx);
+struct torture_suite *torture_local_string_case_handle(TALLOC_CTX *mem_ctx);
+struct torture_suite *torture_local_convert_string(TALLOC_CTX *mem_ctx);
+struct torture_suite *torture_local_string_case(TALLOC_CTX *mem_ctx);
+
+/* The text below is in ancient and a latin charset transliteration of
+ * greek, and an english translation. It from Apology by Plato and sourced from
+ * http://en.wikipedia.org/w/index.php?title=Ancient_Greek&oldid=421361065#Example_text
+ */
+
+const char *plato_english_ascii =
+ "What you, men of Athens, have learned from my accusers, I do not"
+ " know: but I, for my part, nearly forgot who I was thanks to them since"
+ " they spoke so persuasively. And yet, of the truth, they have spoken,"
+ " one might say, nothing at all.";
+
+const char *plato_english_utf16le_base64 =
+ "VwBoAGEAdAAgAHkAbwB1ACwAIABtAGUAbgAgAG8AZgAgAEEAdABoAGUAbgBzACwAIABoAGEAdgBl"
+ "ACAAbABlAGEAcgBuAGUAZAAgAGYAcgBvAG0AIABtAHkAIABhAGMAYwB1AHMAZQByAHMALAAgAEkA"
+ "IABkAG8AIABuAG8AdAAgAGsAbgBvAHcAOgAgAGIAdQB0ACAASQAsACAAZgBvAHIAIABtAHkAIABw"
+ "AGEAcgB0ACwAIABuAGUAYQByAGwAeQAgAGYAbwByAGcAbwB0ACAAdwBoAG8AIABJACAAdwBhAHMA"
+ "IAB0AGgAYQBuAGsAcwAgAHQAbwAgAHQAaABlAG0AIABzAGkAbgBjAGUAIAB0AGgAZQB5ACAAcwBw"
+ "AG8AawBlACAAcwBvACAAcABlAHIAcwB1AGEAcwBpAHYAZQBsAHkALgAgAEEAbgBkACAAeQBlAHQA"
+ "LAAgAG8AZgAgAHQAaABlACAAdAByAHUAdABoACwAIAB0AGgAZQB5ACAAaABhAHYAZQAgAHMAcABv"
+ "AGsAZQBuACwAIABvAG4AZQAgAG0AaQBnAGgAdAAgAHMAYQB5ACwAIABuAG8AdABoAGkAbgBnACAA"
+ "YQB0ACAAYQBsAGwALgA=";
+
+static const char *plato_utf8_base64 =
+ "4b2Nz4TOuSDOvOG9ss69IOG9kc68zrXhv5bPgiwg4b2mIOG8hM69zrTPgc61z4IgzobOuM63zr3O"
+ "seG/ls6/zrksIM+AzrXPgM+Mzr3OuM6xz4TOtSDhvZHPgOG9uCDPhOG/ts69IOG8kM684b+2zr0g"
+ "zrrOsc+EzrfOs8+Mz4HPic69LCDOv+G9kM66IM6/4by2zrTOsTog4byQzrPhvbwgzrQnIM6/4b2W"
+ "zr0gzrrOseG9tiDOseG9kM+E4b24z4Ig4b2Rz4AnIM6x4b2Qz4Thv7bOvSDhvYDOu86vzrPOv8+F"
+ "IOG8kM68zrHPhc+Ezr/hv6Yg4byQz4DOtc67zrHOuM+MzrzOt869LCDOv+G9lc+Ez4kgz4DOuc64"
+ "zrHOveG/ts+CIOG8lM67zrXOs86/zr0uIM6azrHOr8+Ezr/OuSDhvIDOu863zrjOrc+CIM6zzrUg"
+ "4b2hz4Ig4byUz4DOv8+CIM614bywz4DOteG/ls69IM6/4b2QzrThvbLOvSDOteG8sM+Bzq7Ous6x"
+ "z4POuc69Lg==";
+
+static const char *plato_utf16le_base64 =
+ "TR/EA7kDIAC8A3IfvQMgAFEfvAO1A9YfwgMsACAAZh8gAAQfvQO0A8EDtQPCAyAAhgO4A7cDvQOx"
+ "A9YfvwO5AywAIADAA7UDwAPMA70DuAOxA8QDtQMgAFEfwAN4HyAAxAP2H70DIAAQH7wD9h+9AyAA"
+ "ugOxA8QDtwOzA8wDwQPJA70DLAAgAL8DUB+6AyAAvwM2H7QDsQM6ACAAEB+zA3wfIAC0AycAIAC/"
+ "A1YfvQMgALoDsQN2HyAAsQNQH8QDeB/CAyAAUR/AAycAIACxA1AfxAP2H70DIABAH7sDrwOzA78D"
+ "xQMgABAfvAOxA8UDxAO/A+YfIAAQH8ADtQO7A7EDuAPMA7wDtwO9AywAIAC/A1UfxAPJAyAAwAO5"
+ "A7gDsQO9A/YfwgMgABQfuwO1A7MDvwO9Ay4AIACaA7EDrwPEA78DuQMgAAAfuwO3A7gDrQPCAyAA"
+ "swO1AyAAYR/CAyAAFB/AA78DwgMgALUDMB/AA7UD1h+9AyAAvwNQH7QDch+9AyAAtQMwH8EDrgO6"
+ "A7EDwwO5A70DLgA=";
+
+static const char *plato_latin_utf8_base64 =
+ "SMOzdGkgbcOobiBodW1lw65zLCDDtCDDoW5kcmVzIEF0aMSTbmHDrm9pLCBwZXDDs250aGF0ZSBo"
+ "dXDDsiB0w7RuIGVtw7RuIGthdMSTZ8OzcsWNbiwgb3VrIG/DrmRhOiBlZ+G5kSBkJyBvw7tuIGth"
+ "w6wgYXV0w7JzIGh1cCcgYXV0xY1uIG9sw61nb3UgZW1hdXRvw7sgZXBlbGF0aMOzbcSTbiwgaG/D"
+ "unTFjSBwaXRoYW7DtHMgw6lsZWdvbi4gS2HDrXRvaSBhbMSTdGjDqXMgZ2UgaMWNcyDDqXBvcyBl"
+ "aXBlw65uIG91ZMOobiBlaXLhuJdrYXNpbi4=";
+
+static const char *plato_latin_utf16le_base64 =
+ "SADzAHQAaQAgAG0A6ABuACAAaAB1AG0AZQDuAHMALAAgAPQAIADhAG4AZAByAGUAcwAgAEEAdABo"
+ "ABMBbgBhAO4AbwBpACwAIABwAGUAcADzAG4AdABoAGEAdABlACAAaAB1AHAA8gAgAHQA9ABuACAA"
+ "ZQBtAPQAbgAgAGsAYQB0ABMBZwDzAHIATQFuACwAIABvAHUAawAgAG8A7gBkAGEAOgAgAGUAZwBR"
+ "HiAAZAAnACAAbwD7AG4AIABrAGEA7AAgAGEAdQB0APIAcwAgAGgAdQBwACcAIABhAHUAdABNAW4A"
+ "IABvAGwA7QBnAG8AdQAgAGUAbQBhAHUAdABvAPsAIABlAHAAZQBsAGEAdABoAPMAbQATAW4ALAAg"
+ "AGgAbwD6AHQATQEgAHAAaQB0AGgAYQBuAPQAcwAgAOkAbABlAGcAbwBuAC4AIABLAGEA7QB0AG8A"
+ "aQAgAGEAbAATAXQAaADpAHMAIABnAGUAIABoAE0BcwAgAOkAcABvAHMAIABlAGkAcABlAO4AbgAg"
+ "AG8AdQBkAOgAbgAgAGUAaQByABceawBhAHMAaQBuAC4A";
+
+static const char *gd_utf8_base64 = "R8O8bnRoZXIgRGVzY2huZXI=";
+static const char *gd_utf8_upper_base64 = "R8OcTlRIRVIgREVTQ0hORVI=";
+static const char *gd_utf8_lower_base64 = "Z8O8bnRoZXIgZGVzY2huZXI=";
+static const char *gd_cp850_base64 = "R4FudGhlciBEZXNjaG5lcg==";
+static const char *gd_cp850_upper_base64 = "R5pOVEhFUiBERVNDSE5FUg==";
+static const char *gd_cp850_lower_base64 = "Z4FudGhlciBkZXNjaG5lcg==";
+static const char *gd_iso8859_1_base64 = "R/xudGhlciBEZXNjaG5lcg==";
+static const char *gd_utf16le_base64 = "RwD8AG4AdABoAGUAcgAgAEQAZQBzAGMAaABuAGUAcgA=";
+/* täst */
+static const char *utf8_nfc_base64 = "dMOkc3QA";
+/* täst, where ä = a + combining diaeresis */
+static const char *utf8_nfd_base64 = "dGHMiHN0AA==";
+
+/*
+ * These cp850 bytes correspond to high Unicode codes, stretching out to
+ * 3-byte sequences in utf-8.
+ */
+static const char *cp850_high_points = "\xb9\xba\xbb\xbc\xcd\xce";
+static const char *utf8_high_points = "╣║╗╝═╬";
+
+static bool test_cp850_high_points(struct torture_context *tctx)
+{
+ struct smb_iconv_handle *iconv_handle = NULL;
+ DATA_BLOB cp850 = data_blob_string_const(cp850_high_points);
+ DATA_BLOB utf8;
+ DATA_BLOB cp850_return;
+
+ iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8",
+ lpcfg_parm_bool(tctx->lp_ctx,
+ NULL,
+ "iconv",
+ "use_builtin_handlers",
+ true));
+
+ torture_assert(tctx, iconv_handle, "creating iconv handle");
+
+ torture_assert(tctx,
+ convert_string_talloc_handle(tctx, iconv_handle,
+ CH_DOS, CH_UTF8,
+ cp850.data, cp850.length,
+ (void *)&utf8.data, &utf8.length),
+ "conversion from CP850 to UTF-8");
+
+ torture_assert(tctx, utf8.length == cp850.length * 3,
+ "CP850 high bytes expand to the right size");
+
+ torture_assert(tctx,
+ memcmp(utf8.data, utf8_high_points, utf8.length) == 0,
+ "cp850 converted to utf8 matches expected value");
+
+ torture_assert(tctx,
+ convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_DOS,
+ utf8.data, utf8.length,
+ (void *)&cp850_return.data,
+ &cp850_return.length),
+ "conversion from UTF-8 back to CP850");
+
+ torture_assert(tctx, data_blob_cmp(&cp850_return, &cp850) == 0,
+ "UTF-8 returned to CP850 matches the original");
+ return true;
+}
+
+
+static bool test_gd_iso8859_cp850_handle(struct torture_context *tctx)
+{
+ struct smb_iconv_handle *iconv_handle;
+ DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
+ DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
+ DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
+ DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
+ DATA_BLOB gd_output;
+ DATA_BLOB gd_output2;
+
+ talloc_steal(tctx, gd_utf8.data);
+ talloc_steal(tctx, gd_cp850.data);
+ talloc_steal(tctx, gd_iso8859_1.data);
+ talloc_steal(tctx, gd_utf16le.data);
+
+ iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
+ lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ torture_assert(tctx, iconv_handle, "getting iconv handle");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_DOS,
+ gd_utf8.data, gd_utf8.length,
+ (void *)&gd_output.data, &gd_output.length),
+ "conversion from UTF8 to (dos charset) ISO-8859-1");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_DOS,
+ gd_utf8.data, gd_utf8.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length),
+ "conversion from UTF8 to (dos charset) ISO-8859-1");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
+
+ /* Short output handling confirmation */
+ gd_output.length = 1;
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_DOS,
+ gd_utf8.data, gd_utf8.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF8 to (dos charset) ISO-8859-1 should fail due to too short");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail E2BIG");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
+ torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
+
+ /* Short output handling confirmation */
+ gd_output.length = 2;
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_DOS,
+ gd_utf8.data, gd_utf8.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF8 to (dos charset) ISO-8859-1 should fail due to too short");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail E2BIG");
+ torture_assert_int_equal(tctx, gd_output.length, 2, "Should only get 2 char of output");
+
+ /* Short input handling confirmation */
+ gd_output.length = gd_iso8859_1.length;
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_DOS,
+ gd_utf8.data, 2,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF8 to (dos charset) ISO-8859-1 should fail due to too short");
+ torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to (dos charset) ISO-8859-1 should fail EINVAL");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
+
+ /* Short output handling confirmation */
+ gd_output.length = 1;
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ gd_utf16le.data, gd_utf16le.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF16 to UTF8 should fail due to too short");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to (utf8 charset) ISO-8859-1 should fail E2BIG");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
+ torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF16 to UTF8 incorrect");
+
+ /* Short output handling confirmation */
+ gd_output.length = 3;
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ gd_utf16le.data, gd_utf16le.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF16 to UTF8 should fail due to too short");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to (utf8 charset) ISO-8859-1 should fail E2BIG");
+ torture_assert_int_equal(tctx, gd_output.length, 3, "Should get 3 bytes output for UTF8");
+
+ /* Short input handling confirmation */
+ gd_output.length = gd_utf8.length;
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ gd_utf16le.data, 3,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF16 to UTF8 should fail due to too short");
+ torture_assert_errno_equal(tctx, EINVAL, "conversion from short UTF16 to UTF8 should fail EINVAL");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UNIX,
+ gd_utf8.data, gd_utf8.length,
+ (void *)&gd_output.data, &gd_output.length),
+ "conversion from UTF8 to (unix charset) CP850");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UTF8,
+ gd_utf8.data, gd_utf8.length,
+ (void *)&gd_output.data, &gd_output.length),
+ "conversion from UTF8 to UTF8");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF8 to UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_DOS,
+ gd_utf16le.data, gd_utf16le.length,
+ (void *)&gd_output.data, &gd_output.length),
+ "conversion from UTF16LE to (dos charset) ISO-8859-1");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_DOS, CH_UTF16LE,
+ gd_output.data, gd_output.length,
+ (void *)&gd_output2.data, &gd_output2.length),
+ "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
+ torture_assert_data_blob_equal(tctx, gd_output2, gd_utf16le, "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_UNIX,
+ gd_utf16le.data, gd_utf16le.length,
+ (void *)&gd_output.data, &gd_output.length),
+ "conversion from UTF16LE to (unix charset) CP850");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ gd_utf16le.data, gd_utf16le.length,
+ (void *)&gd_output.data, &gd_output.length),
+ "conversion from UTF16LE to UTF8");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_DOS, CH_DOS,
+ gd_iso8859_1.data, gd_iso8859_1.length,
+ (void *)&gd_output.data, &gd_output.length),
+ "conversion from (dos charset) ISO-8859-1 to (dos charset) ISO-8859-1");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_DOS, CH_UNIX,
+ gd_iso8859_1.data, gd_iso8859_1.length,
+ (void *)&gd_output.data, &gd_output.length),
+ "conversion from (dos charset) ISO-8859-1 to (unix charset) CP850");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_DOS, CH_UTF8,
+ gd_iso8859_1.data, gd_iso8859_1.length,
+ (void *)&gd_output.data, &gd_output.length),
+ "conversion from (dos charset) ISO-8859-1 to UTF8");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_DOS, CH_UTF16LE,
+ gd_iso8859_1.data, gd_iso8859_1.length,
+ (void *)&gd_output.data, &gd_output.length),
+ "conversion from (dos charset) ISO-8859-1 to UTF16LE");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from (dos charset) ISO-8859-1 to UTF16LE");
+ torture_assert_int_equal(tctx,
+ strlen_m_ext_handle(iconv_handle,
+ (const char *)gd_iso8859_1.data,
+ CH_DOS, CH_UTF16LE),
+ gd_output.length / 2,
+ "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_DOS, CH_UTF8,
+ gd_iso8859_1.data, gd_iso8859_1.length,
+ (void *)&gd_output.data, &gd_output.length),
+ "conversion from (dos charset) ISO-8859-1 to UTF8");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from (dos charset) ISO-8859-1 to UTF8");
+ torture_assert_int_equal(tctx,
+ strlen_m_ext_handle(iconv_handle,
+ (const char *)gd_iso8859_1.data,
+ CH_DOS, CH_UTF8),
+ gd_output.length,
+ "checking strlen_m_ext of conversion from (dos charset) ISO-8859-1 to UTF8");
+ return true;
+}
+
+static bool test_gd_minus_1_handle(struct torture_context *tctx)
+{
+ struct smb_iconv_handle *iconv_handle;
+ DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
+ DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
+ DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
+ DATA_BLOB gd_output;
+ DATA_BLOB gd_utf8_terminated;
+ DATA_BLOB gd_cp850_terminated;
+ DATA_BLOB gd_utf16le_terminated;
+
+ talloc_steal(tctx, gd_utf8.data);
+ talloc_steal(tctx, gd_cp850.data);
+ talloc_steal(tctx, gd_utf16le.data);
+
+ iconv_handle = get_iconv_testing_handle(tctx, "CP850", "CP850",
+ lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ torture_assert(tctx, iconv_handle, "getting iconv handle");
+
+ gd_utf8_terminated = data_blob_talloc(tctx, NULL, gd_utf8.length + 1);
+ memcpy(gd_utf8_terminated.data, gd_utf8.data, gd_utf8.length);
+ gd_utf8_terminated.data[gd_utf8.length] = '\0';
+
+ gd_cp850_terminated = data_blob_talloc(tctx, NULL, gd_cp850.length + 1);
+ memcpy(gd_cp850_terminated.data, gd_cp850.data, gd_cp850.length);
+ gd_cp850_terminated.data[gd_cp850.length] = '\0';
+
+ gd_utf16le_terminated = data_blob_talloc(tctx, NULL, gd_utf16le.length + 2);
+ memcpy(gd_utf16le_terminated.data, gd_utf16le.data, gd_utf16le.length);
+ gd_utf16le_terminated.data[gd_utf16le.length] = '\0';
+ gd_utf16le_terminated.data[gd_utf16le.length + 1] = '\0';
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ gd_utf8_terminated.data, -1,
+ (void *)gd_output.data, gd_output.length, &gd_output.length),
+ "conversion from UTF8 to UTF16LE null terminated");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ gd_utf8_terminated.data, -1,
+ (void *)gd_output.data, gd_utf16le.length, &gd_output.length) == false,
+ "conversion from UTF8 to UTF16LE null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le, "conversion from UTF8 to UTF16LE null terminated");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ gd_utf8_terminated.data, -1,
+ (void *)gd_output.data, gd_utf16le.length - 1, &gd_output.length) == false,
+ "conversion from UTF8 to UTF16LE null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ gd_utf8_terminated.data, -1,
+ (void *)gd_output.data, gd_utf16le.length - 2, &gd_output.length) == false,
+ "conversion from UTF8 to UTF16LE null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ gd_utf16le_terminated.data, -1,
+ (void *)gd_output.data, gd_output.length, &gd_output.length),
+ "conversion from UTF16LE to UTF8 null terminated");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ gd_utf16le_terminated.data, -1,
+ (void *)gd_output.data, gd_utf8.length, &gd_output.length) == false,
+ "conversion from UTF16LE to UTF8 null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf8, "conversion from UTF16LE to UTF8 null terminated");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ gd_utf16le_terminated.data, -1,
+ (void *)gd_output.data, gd_utf8.length - 1, &gd_output.length) == false,
+ "conversion from UTF16LE to UTF8 null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ gd_utf16le_terminated.data, -1,
+ (void *)gd_output.data, gd_utf8.length - 2, &gd_output.length) == false,
+ "conversion from UTF16LE to UTF8 null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_DOS,
+ gd_utf16le_terminated.data, -1,
+ (void *)gd_output.data, gd_output.length, &gd_output.length),
+ "conversion from UTF16LE to CP850 (dos) null terminated");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to CP850 (dos) null terminated");
+
+ /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
+ gd_utf8_terminated.data[3] = '\0';
+ gd_utf8_terminated.length = 4; /* used for the comparison only */
+
+ gd_cp850_terminated.data[2] = '\0';
+ gd_cp850_terminated.length = 3; /* used for the comparison only */
+
+ gd_utf16le_terminated.data[4] = '\0';
+ gd_utf16le_terminated.data[5] = '\0';
+ gd_utf16le_terminated.length = 6; /* used for the comparison only */
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ gd_utf8_terminated.data, -1,
+ (void *)gd_output.data, gd_output.length, &gd_output.length),
+ "conversion from UTF8 to UTF16LE null terminated");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ gd_utf16le_terminated.data, -1,
+ (void *)gd_output.data, gd_output.length, &gd_output.length),
+ "conversion from UTF16LE to UTF8 null terminated");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_DOS, CH_UTF16LE,
+ gd_cp850_terminated.data, -1,
+ (void *)gd_output.data, gd_output.length, &gd_output.length),
+ "conversion from CP850 to UTF16LE null terminated");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_cp850.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_DOS,
+ gd_utf16le_terminated.data, -1,
+ (void *)gd_output.data, gd_output.length, &gd_output.length),
+ "conversion from UTF16LE to UTF8 null terminated");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_cp850_terminated, "conversion from UTF16LE to UTF8 null terminated early");
+
+ /* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */
+ gd_utf8_terminated.data[1] = '\0';
+ gd_utf8_terminated.length = 2; /* used for the comparison only */
+
+ gd_utf16le_terminated.data[2] = '\0';
+ gd_utf16le_terminated.data[3] = '\0';
+ gd_utf16le_terminated.length = 4; /* used for the comparison only */
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf16le.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle, CH_UTF8, CH_UTF16LE,
+ gd_utf8_terminated.data, -1,
+ (void *)gd_output.data, gd_output.length, &gd_output.length),
+ "conversion from UTF8 to UTF16LE null terminated");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ gd_utf16le_terminated.data, -1,
+ (void *)gd_output.data, gd_output.length, &gd_output.length),
+ "conversion from UTF16LE to UTF8 null terminated");
+ torture_assert_data_blob_equal(tctx, gd_output, gd_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early");
+
+ return true;
+}
+
+static bool test_gd_ascii_handle(struct torture_context *tctx)
+{
+ struct smb_iconv_handle *iconv_handle;
+ DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
+ DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
+ DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
+ DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
+ DATA_BLOB gd_output;
+
+ talloc_steal(tctx, gd_utf8.data);
+ talloc_steal(tctx, gd_cp850.data);
+ talloc_steal(tctx, gd_iso8859_1.data);
+ talloc_steal(tctx, gd_utf16le.data);
+
+ iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8",
+ lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ torture_assert(tctx, iconv_handle, "getting iconv handle");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_DOS,
+ gd_utf8.data, gd_utf8.length,
+ (void *)&gd_output.data, &gd_output.length) == false,
+ "conversion from UTF8 to (dos charset) ASCII should fail");
+
+ gd_output = data_blob_talloc(tctx, NULL, gd_utf8.length);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_DOS,
+ gd_utf8.data, gd_utf8.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF8 to (dos charset) ASCII should fail");
+ torture_assert_errno_equal(tctx, EILSEQ, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail E2BIG");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
+ torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "partial conversion from UTF8 to (dos charset) ASCII incorrect");
+
+ /* Short output handling confirmation */
+ gd_output.length = 1;
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_DOS,
+ gd_utf8.data, gd_utf8.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF8 to (dos charset) ASCII should fail due to too short");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to (dos charset) ASCII too short");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
+ torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to (dos charset) ASCII incorrect");
+
+ /* Short output handling confirmation */
+ gd_output.length = 2;
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_DOS,
+ gd_utf8.data, gd_utf8.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF8 to (dos charset) ASCII should fail due to illegal sequence");
+ torture_assert_errno_equal(tctx, EILSEQ, "conversion from UTF8 to (dos charset) ISO-8859-1 should fail EILSEQ");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 2 char of output");
+
+ /* Short input handling confirmation */
+ gd_output.length = gd_utf8.length;
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_DOS,
+ gd_utf8.data, 2,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF8 to (dos charset) ASCII should fail due to too short");
+ torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to (dos charset) ASCII should fail EILSEQ");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
+ return true;
+}
+
+static bool test_plato_english_iso8859_cp850_handle(struct torture_context *tctx)
+{
+ struct smb_iconv_handle *iconv_handle;
+ DATA_BLOB plato_english_utf8 = data_blob_string_const(plato_english_ascii);
+ DATA_BLOB plato_english_cp850 = plato_english_utf8;
+ DATA_BLOB plato_english_iso8859_1 = plato_english_utf8;
+ DATA_BLOB plato_english_utf16le = base64_decode_data_blob(plato_english_utf16le_base64);
+ DATA_BLOB plato_english_output;
+ DATA_BLOB plato_english_output2;
+
+ talloc_steal(tctx, plato_english_utf16le.data);
+
+ iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
+ lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ torture_assert(tctx, iconv_handle, "getting iconv handle");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_DOS,
+ plato_english_utf8.data, plato_english_utf8.length,
+ (void *)&plato_english_output.data, &plato_english_output.length),
+ "conversion from UTF8 to (dos charset) ISO-8859-1");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF8 to (dos charset) ISO-8859-1 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UNIX,
+ plato_english_utf8.data, plato_english_utf8.length,
+ (void *)&plato_english_output.data, &plato_english_output.length),
+ "conversion from UTF8 to (unix charset) CP850");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF8 to (unix charset) CP850 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UTF8,
+ plato_english_utf8.data, plato_english_utf8.length,
+ (void *)&plato_english_output.data, &plato_english_output.length),
+ "conversion from UTF8 to UTF8");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF8 to UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_DOS,
+ plato_english_utf16le.data, plato_english_utf16le.length,
+ (void *)&plato_english_output.data, &plato_english_output.length),
+ "conversion from UTF16LE to (dos charset) ISO-8859-1");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_DOS, CH_UTF16LE,
+ plato_english_output.data, plato_english_output.length,
+ (void *)&plato_english_output2.data, &plato_english_output2.length),
+ "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
+ torture_assert_data_blob_equal(tctx, plato_english_output2, plato_english_utf16le, "round trip conversion from (dos charset) ISO-8859-1 back to UTF16LE");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_english_utf16le.data, plato_english_utf16le.length,
+ (void *)&plato_english_output.data, &plato_english_output.length),
+ "conversion from UTF16LE to UTF8");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_english_utf16le.data, plato_english_utf16le.length,
+ (void *)plato_english_output.data, plato_english_output.length,
+ &plato_english_output.length),
+ "conversion from UTF16LE to UTF8");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
+
+ plato_english_output.length = 5;
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_english_utf16le.data, plato_english_utf16le.length,
+ (void *)plato_english_output.data, plato_english_output.length,
+ &plato_english_output.length) == false,
+ "conversion from UTF16LE to UTF8 should fail due to short output");
+ torture_assert_data_blob_equal(tctx, plato_english_output, data_blob_string_const("What "), "conversion from UTF16LE to UTF8 incorrect");
+ torture_assert_int_equal(tctx, plato_english_output.length, 5, "short conversion failed");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_UNIX,
+ plato_english_utf16le.data, plato_english_utf16le.length,
+ (void *)&plato_english_output.data, &plato_english_output.length),
+ "conversion from UTF16LE to (unix charset) CP850");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_english_utf16le.data, plato_english_utf16le.length,
+ (void *)&plato_english_output.data, &plato_english_output.length),
+ "conversion from UTF16LE to UTF8");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_DOS, CH_DOS,
+ plato_english_iso8859_1.data, plato_english_iso8859_1.length,
+ (void *)&plato_english_output.data, &plato_english_output.length),
+ "conversion from (dos charset) ISO-8859-1 to (dos charset) ISO-8859-1");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_iso8859_1, "conversion from UTF16LE to (dos charset) ISO-8859-1 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_DOS, CH_UNIX,
+ plato_english_iso8859_1.data, plato_english_iso8859_1.length,
+ (void *)&plato_english_output.data, &plato_english_output.length),
+ "conversion from (dos charset) ISO-8859-1 to (unix charset) CP850");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_cp850, "conversion from UTF16LE to (unix charset) CP850 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_DOS, CH_UTF8,
+ plato_english_iso8859_1.data, plato_english_iso8859_1.length,
+ (void *)&plato_english_output.data, &plato_english_output.length),
+ "conversion from (dos charset) ISO-8859-1 to UTF8");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_DOS, CH_UTF16LE,
+ plato_english_iso8859_1.data, plato_english_iso8859_1.length,
+ (void *)&plato_english_output.data, &plato_english_output.length),
+ "conversion from (dos charset) ISO-8859-1 to UTF16LE");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from (dos charset) ISO-8859-1 to UTF16LE");
+ return true;
+}
+
+static bool test_plato_english_minus_1_handle(struct torture_context *tctx)
+{
+ struct smb_iconv_handle *iconv_handle;
+ DATA_BLOB plato_english_utf8 = data_blob_string_const(plato_english_ascii);
+ DATA_BLOB plato_english_utf16le = base64_decode_data_blob(plato_english_utf16le_base64);
+ DATA_BLOB plato_english_output;
+ DATA_BLOB plato_english_utf8_terminated;
+ DATA_BLOB plato_english_utf16le_terminated;
+
+ talloc_steal(tctx, plato_english_utf16le.data);
+
+ iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
+ lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ torture_assert(tctx, iconv_handle, "getting iconv handle");
+
+ plato_english_utf8_terminated = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 1);
+ memcpy(plato_english_utf8_terminated.data, plato_english_utf8.data, plato_english_utf8.length);
+ plato_english_utf8_terminated.data[plato_english_utf8.length] = '\0';
+
+ plato_english_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 2);
+ memcpy(plato_english_utf16le_terminated.data, plato_english_utf16le.data, plato_english_utf16le.length);
+ plato_english_utf16le_terminated.data[plato_english_utf16le.length] = '\0';
+ plato_english_utf16le_terminated.data[plato_english_utf16le.length + 1] = '\0';
+
+ plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_english_utf8_terminated.data, -1,
+ (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
+ "conversion from UTF8 to UTF16LE null terminated");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_english_utf8_terminated.data, -1,
+ (void *)plato_english_output.data, plato_english_utf16le.length, &plato_english_output.length) == false,
+ "conversion from UTF8 to UTF16LE null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le, "conversion from UTF8 to UTF16LE null terminated");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_english_utf8_terminated.data, -1,
+ (void *)plato_english_output.data, plato_english_utf16le.length - 1, &plato_english_output.length) == false,
+ "conversion from UTF8 to UTF16LE null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_english_utf8_terminated.data, -1,
+ (void *)plato_english_output.data, plato_english_utf16le.length - 2, &plato_english_output.length) == false,
+ "conversion from UTF8 to UTF16LE null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+
+ plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_english_utf16le_terminated.data, -1,
+ (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
+ "conversion from UTF16LE to UTF8 null terminated");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_english_utf16le_terminated.data, -1,
+ (void *)plato_english_output.data, plato_english_utf8.length, &plato_english_output.length) == false,
+ "conversion from UTF16LE to UTF8 null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8, "conversion from UTF16LE to UTF8 null terminated");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_english_utf16le_terminated.data, -1,
+ (void *)plato_english_output.data, plato_english_utf8.length - 1, &plato_english_output.length) == false,
+ "conversion from UTF16LE to UTF8 null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_english_utf16le_terminated.data, -1,
+ (void *)plato_english_output.data, plato_english_utf8.length - 2, &plato_english_output.length) == false,
+ "conversion from UTF16LE to UTF8 null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
+
+ /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
+ plato_english_utf8_terminated.data[3] = '\0';
+ plato_english_utf8_terminated.length = 4; /* used for the comparison only */
+
+ plato_english_utf16le_terminated.data[6] = '\0';
+ plato_english_utf16le_terminated.data[7] = '\0';
+ plato_english_utf16le_terminated.length = 8; /* used for the comparison only */
+
+ plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_english_utf8_terminated.data, -1,
+ (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
+ "conversion from UTF8 to UTF16LE null terminated");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
+
+ plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_english_utf16le_terminated.data, -1,
+ (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
+ "conversion from UTF16LE to UTF8 null terminated");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
+
+
+ /* Now null terminate the string particularly early, the confirm we don't skip the NULL and convert any further */
+ plato_english_utf8_terminated.data[1] = '\0';
+ plato_english_utf8_terminated.length = 2; /* used for the comparison only */
+
+ plato_english_utf16le_terminated.data[2] = '\0';
+ plato_english_utf16le_terminated.data[3] = '\0';
+ plato_english_utf16le_terminated.length = 4; /* used for the comparison only */
+
+ plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf16le.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle, CH_UTF8, CH_UTF16LE,
+ plato_english_utf8_terminated.data, -1,
+ (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
+ "conversion from UTF8 to UTF16LE null terminated");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated very early");
+
+ plato_english_output = data_blob_talloc(tctx, NULL, plato_english_utf8.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_english_utf16le_terminated.data, -1,
+ (void *)plato_english_output.data, plato_english_output.length, &plato_english_output.length),
+ "conversion from UTF16LE to UTF8 null terminated");
+ torture_assert_data_blob_equal(tctx, plato_english_output, plato_english_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated very early");
+
+ return true;
+}
+
+static bool test_plato_minus_1_handle(struct torture_context *tctx)
+{
+ struct smb_iconv_handle *iconv_handle;
+ DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
+ DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
+ DATA_BLOB plato_output;
+ DATA_BLOB plato_utf8_terminated;
+ DATA_BLOB plato_utf16le_terminated;
+
+ talloc_steal(tctx, plato_utf8.data);
+ talloc_steal(tctx, plato_utf16le.data);
+
+ iconv_handle = get_iconv_testing_handle(tctx, "ISO-8859-1", "CP850",
+ lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ torture_assert(tctx, iconv_handle, "getting iconv handle");
+
+ plato_utf8_terminated = data_blob_talloc(tctx, NULL, plato_utf8.length + 1);
+ memcpy(plato_utf8_terminated.data, plato_utf8.data, plato_utf8.length);
+ plato_utf8_terminated.data[plato_utf8.length] = '\0';
+
+ plato_utf16le_terminated = data_blob_talloc(tctx, NULL, plato_utf16le.length + 2);
+ memcpy(plato_utf16le_terminated.data, plato_utf16le.data, plato_utf16le.length);
+ plato_utf16le_terminated.data[plato_utf16le.length] = '\0';
+ plato_utf16le_terminated.data[plato_utf16le.length + 1] = '\0';
+
+ plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_utf8_terminated.data, -1,
+ (void *)plato_output.data, plato_output.length, &plato_output.length),
+ "conversion from UTF8 to UTF16LE null terminated");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_utf8_terminated.data, -1,
+ (void *)plato_output.data, plato_utf16le.length, &plato_output.length) == false,
+ "conversion from UTF8 to UTF16LE null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE null terminated");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_utf8_terminated.data, -1,
+ (void *)plato_output.data, plato_utf16le.length - 1, &plato_output.length) == false,
+ "conversion from UTF8 to UTF16LE null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_utf8_terminated.data, -1,
+ (void *)plato_output.data, plato_utf16le.length - 2, &plato_output.length) == false,
+ "conversion from UTF8 to UTF16LE null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to UTF16LE should fail E2BIG");
+
+ plato_output = data_blob_talloc(tctx, NULL, plato_utf8.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_utf16le_terminated.data, -1,
+ (void *)plato_output.data, plato_output.length, &plato_output.length),
+ "conversion from UTF16LE to UTF8 null terminated");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_utf16le_terminated.data, -1,
+ (void *)plato_output.data, plato_utf8.length, &plato_output.length) == false,
+ "conversion from UTF16LE to UTF8 null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 null terminated");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_utf16le_terminated.data, -1,
+ (void *)plato_output.data, plato_utf8.length - 1, &plato_output.length) == false,
+ "conversion from UTF16LE to UTF8 null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_utf16le_terminated.data, -1,
+ (void *)plato_output.data, plato_utf8.length - 2, &plato_output.length) == false,
+ "conversion from UTF16LE to UTF8 null terminated should fail");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16LE to UTF8 should fail E2BIG");
+
+ /* Now null terminate the string early, the confirm we don't skip the NULL and convert any further */
+ plato_utf8_terminated.data[5] = '\0';
+ plato_utf8_terminated.length = 6; /* used for the comparison only */
+
+ plato_utf16le_terminated.data[4] = '\0';
+ plato_utf16le_terminated.data[5] = '\0';
+ plato_utf16le_terminated.length = 6; /* used for the comparison only */
+
+ plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_utf8_terminated.data, -1,
+ (void *)plato_output.data, plato_output.length, &plato_output.length),
+ "conversion from UTF8 to UTF16LE null terminated");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le_terminated, "conversion from UTF8 to UTF16LE null terminated early");
+
+ plato_output = data_blob_talloc(tctx, NULL, plato_utf8.length + 10);
+
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_utf16le_terminated.data, -1,
+ (void *)plato_output.data, plato_output.length, &plato_output.length),
+ "conversion from UTF16LE to UTF8 null terminated");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf8_terminated, "conversion from UTF16LE to UTF8 null terminated early");
+
+ return true;
+}
+
+static bool test_plato_cp850_utf8_handle(struct torture_context *tctx)
+{
+ struct smb_iconv_handle *iconv_handle;
+ DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
+ DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
+ DATA_BLOB plato_output;
+ DATA_BLOB plato_output2;
+
+ talloc_steal(tctx, plato_utf8.data);
+ talloc_steal(tctx, plato_utf16le.data);
+
+ iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8",
+ lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ torture_assert(tctx, iconv_handle, "creating iconv handle");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_utf8.data, plato_utf8.length,
+ (void *)&plato_output.data, &plato_output.length),
+ "conversion of UTF8 ancient greek to UTF16 failed");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
+
+ torture_assert_int_equal(tctx,
+ strlen_m_ext_handle(iconv_handle,
+ (const char *)plato_utf8.data,
+ CH_UTF8, CH_UTF16LE),
+ plato_output.length / 2,
+ "checking strlen_m_ext of conversion of UTF8 to UTF16LE");
+
+ memset(plato_output.data, '\0', plato_output.length);
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_utf8.data, plato_utf8.length,
+ (void *)plato_output.data, plato_output.length,
+ &plato_output.length),
+ "conversion of UTF8 ancient greek to UTF16 failed");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_output.data, plato_output.length,
+ (void *)&plato_output2.data, &plato_output2.length),
+ "conversion of UTF8 ancient greek to UTF16 failed");
+ torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
+
+ memset(plato_output2.data, '\0', plato_output2.length);
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_output.data, plato_output.length,
+ (void *)plato_output2.data, plato_output2.length, &plato_output2.length),
+ "conversion of UTF8 ancient greek to UTF16 failed");
+ torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UTF8,
+ plato_utf8.data, plato_utf8.length,
+ (void *)&plato_output.data, &plato_output.length),
+ "conversion of UTF8 to UTF8");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
+ "conversion of UTF8 to UTF8");
+ torture_assert_int_equal(tctx,
+ strlen_m_ext_handle(iconv_handle,
+ (const char *)plato_utf8.data,
+ CH_UTF8, CH_UTF8),
+ plato_output.length,
+ "checking strlen_m_ext of conversion of UTF8 to UTF8");
+ memset(plato_output.data, '\0', plato_output.length);
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UTF8,
+ plato_utf8.data, plato_utf8.length,
+ (void *)plato_output.data, plato_output.length,
+ &plato_output.length),
+ "conversion of UTF8 to UTF8");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_DOS,
+ plato_utf8.data, plato_utf8.length,
+ (void *)&plato_output.data, &plato_output.length) == false,
+ "conversion of UTF8 ancient greek to DOS charset CP850 should fail");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UNIX,
+ plato_utf8.data, plato_utf8.length,
+ (void *)&plato_output.data, &plato_output.length),
+ "conversion of UTF16 ancient greek to unix charset UTF8 failed");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
+
+ memset(plato_output.data, '\0', plato_output.length);
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF8, CH_UNIX,
+ plato_utf8.data, plato_utf8.length,
+ (void *)plato_output.data, plato_output.length,
+ &plato_output.length),
+ "conversion of UTF16 ancient greek to unix charset UTF8 failed");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UTF8,
+ plato_utf8.data, plato_utf8.length,
+ (void *)&plato_output.data, &plato_output.length),
+ "conversion of UTF16 ancient greek to unix charset UTF8 failed");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF8 to UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_DOS,
+ plato_utf16le.data, plato_utf16le.length,
+ (void *)&plato_output.data, &plato_output.length) == false,
+ "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
+
+ /* Allocate enough space, if it were possible do do the conversion */
+ plato_output = data_blob_talloc(tctx, NULL, plato_utf16le.length);
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_DOS,
+ plato_utf16le.data, plato_utf16le.length,
+ (void *)plato_output.data, plato_output.length,
+ &plato_output.length) == false,
+ "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
+ torture_assert_errno_equal(tctx, EILSEQ, "conversion of UTF16 ancient greek to DOS charset CP850 should fail");
+
+ /* Allocate only enough space for a partial conversion */
+ plato_output = data_blob_talloc(tctx, NULL, 9);
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_utf16le.data, plato_utf16le.length,
+ (void *)plato_output.data, plato_output.length,
+ &plato_output.length) == false,
+ "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
+ torture_assert_int_equal(tctx, plato_output.length, 8,
+ "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
+
+ plato_output = data_blob_talloc(tctx, NULL, 2);
+ torture_assert(tctx, convert_string_error_handle(iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_utf16le.data, plato_utf16le.length,
+ (void *)plato_output.data, plato_output.length,
+ &plato_output.length) == false,
+ "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
+ torture_assert_int_equal(tctx, plato_output.length, 0,
+ "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
+
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_UNIX,
+ plato_utf16le.data, plato_utf16le.length,
+ (void *)&plato_output.data, &plato_output.length),
+ "conversion of UTF16 ancient greek to unix charset UTF8 failed");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to (unix charset) UTF8 incorrect");
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_utf16le.data, plato_utf16le.length,
+ (void *)&plato_output.data, &plato_output.length),
+ "conversion of UTF16 ancient greek to UTF8 failed");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 incorrect");
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_utf16le.data, plato_utf16le.length,
+ (void *)&plato_output.data, &plato_output.length),
+ "conversion of UTF16 ancient greek to UTF8 failed");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf8, "conversion from UTF16LE to UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_output.data, plato_output.length,
+ (void *)&plato_output2.data, &plato_output2.length),
+ "round trip conversion of UTF16 ancient greek to UTF8 and back again failed");
+ torture_assert_data_blob_equal(tctx, plato_output2, plato_utf16le,
+ "round trip conversion of UTF16 ancient greek to UTF8 and back again failed");
+ torture_assert_int_equal(tctx,
+ strlen_m_ext_handle(iconv_handle,
+ (const char *)plato_output.data,
+ CH_UTF8, CH_UTF16LE),
+ plato_output2.length / 2,
+ "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UTF8,
+ plato_output.data, plato_output.length,
+ (void *)&plato_output2.data, &plato_output2.length),
+ "conversion of UTF8 to UTF8");
+ torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8,
+ "conversion of UTF8 to UTF8");
+ torture_assert_int_equal(tctx,
+ strlen_m_ext_handle(iconv_handle,
+ (const char *)plato_output.data,
+ CH_UTF8, CH_UTF8),
+ plato_output2.length,
+ "checking strlen_m_ext of conversion of UTF8 to UTF8");
+ return true;
+}
+
+static bool test_plato_latin_cp850_utf8_handle(struct torture_context *tctx)
+{
+ struct smb_iconv_handle *iconv_handle;
+ DATA_BLOB plato_latin_utf8 = base64_decode_data_blob(plato_latin_utf8_base64);
+ DATA_BLOB plato_latin_utf16le = base64_decode_data_blob(plato_latin_utf16le_base64);
+ DATA_BLOB plato_latin_output;
+ DATA_BLOB plato_latin_output2;
+
+ talloc_steal(tctx, plato_latin_utf8.data);
+ talloc_steal(tctx, plato_latin_utf16le.data);
+
+ iconv_handle = get_iconv_testing_handle(tctx, "CP850", "UTF8",
+ lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ torture_assert(tctx, iconv_handle, "creating iconv handle");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_DOS,
+ plato_latin_utf8.data, plato_latin_utf8.length,
+ (void *)&plato_latin_output.data, &plato_latin_output.length) == false,
+ "conversion of UTF8 latin charset greek to DOS charset CP850 should fail");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UNIX,
+ plato_latin_utf8.data, plato_latin_utf8.length,
+ (void *)&plato_latin_output.data, &plato_latin_output.length),
+ "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
+ torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to (unix charset) UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UTF8,
+ plato_latin_utf8.data, plato_latin_utf8.length,
+ (void *)&plato_latin_output.data, &plato_latin_output.length),
+ "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
+ torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF8 to UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_DOS,
+ plato_latin_utf16le.data, plato_latin_utf16le.length,
+ (void *)&plato_latin_output.data, &plato_latin_output.length) == false,
+ "conversion of UTF16 latin charset greek to DOS charset CP850 should fail");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_UNIX,
+ plato_latin_utf16le.data, plato_latin_utf16le.length,
+ (void *)&plato_latin_output.data, &plato_latin_output.length),
+ "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
+ torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to (unix charset) CP850 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF16LE, CH_UTF8,
+ plato_latin_utf16le.data, plato_latin_utf16le.length,
+ (void *)&plato_latin_output.data, &plato_latin_output.length),
+ "conversion of UTF16 latin charset greek to UTF8 failed");
+ torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16LE to UTF8 incorrect");
+
+ torture_assert(tctx, convert_string_talloc_handle(tctx, iconv_handle,
+ CH_UTF8, CH_UTF16LE,
+ plato_latin_output.data, plato_latin_output.length,
+ (void *)&plato_latin_output2.data, &plato_latin_output2.length),
+ "round trip conversion of UTF16 latin charset greek to UTF8 and back again failed");
+ torture_assert_data_blob_equal(tctx, plato_latin_output2, plato_latin_utf16le,
+ "round trip conversion of UTF16 latin charset greek to UTF8 and back again failed");
+ torture_assert_int_equal(tctx,
+ strlen_m_ext_handle(iconv_handle,
+ (const char *)plato_latin_output.data,
+ CH_UTF8, CH_UTF16LE),
+ plato_latin_output2.length / 2,
+ "checking strlen_m_ext of round trip conversion of UTF16 latin charset greek to UTF8 and back again");
+ return true;
+}
+
+static bool test_utf8_nfc_to_nfd_overflow(struct torture_context *tctx)
+{
+ smb_iconv_t ic;
+ DATA_BLOB utf8_nfc_blob;
+ DATA_BLOB utf8_nfd_blob;
+ DATA_BLOB src_blob;
+ DATA_BLOB blob;
+ size_t nconv;
+ const char *src = NULL;
+ char *dst = NULL;
+ size_t dst_left;
+ size_t srclen;
+ bool ret = true;
+
+ ic = smb_iconv_open("UTF8-NFD", "UTF8-NFC");
+ torture_assert_goto(tctx, ic != (smb_iconv_t)-1, ret, done,
+ "creating iconv handle\n");
+
+ utf8_nfc_blob = base64_decode_data_blob_talloc(tctx, utf8_nfc_base64);
+ torture_assert_not_null_goto(tctx, utf8_nfc_blob.data, ret, done,
+ "OOM\n");
+
+ utf8_nfd_blob = base64_decode_data_blob_talloc(tctx, utf8_nfd_base64);
+ torture_assert_not_null_goto(tctx, utf8_nfd_blob.data, ret, done,
+ "OOM\n");
+
+ blob = data_blob_talloc_zero(tctx, 255);
+ torture_assert_not_null_goto(tctx, blob.data, ret, done, "OOM\n");
+
+ /*
+ * Unfortunately the current implementation that performs the conversion
+ * (using libicu) returns EINVAL if the result buffer is too small, not
+ * E2BIG like iconv().
+ */
+
+ src = "foo";
+ srclen = 3;
+ dst = (char *)blob.data;
+ dst_left = 0;
+ nconv = smb_iconv(ic,
+ &src,
+ &srclen,
+ &dst,
+ &dst_left);
+ torture_assert_int_equal_goto(tctx, nconv, -1, ret, done,
+ "smb_iconv failed\n");
+ torture_assert_errno_equal_goto(tctx, EINVAL, ret, done,
+ "Wrong errno\n");
+
+ src = "foo";
+ srclen = 3;
+ dst = (char *)blob.data;
+ dst_left = 1;
+ nconv = smb_iconv(ic,
+ &src,
+ &srclen,
+ &dst,
+ &dst_left);
+ torture_assert_int_equal_goto(tctx, nconv, -1, ret, done,
+ "smb_iconv failed\n");
+ torture_assert_errno_equal_goto(tctx, EINVAL, ret, done,
+ "Wrong errno\n");
+
+ src = "foo";
+ srclen = 3;
+ dst = (char *)blob.data;
+ dst_left = 2;
+ nconv = smb_iconv(ic,
+ &src,
+ &srclen,
+ &dst,
+ &dst_left);
+ torture_assert_int_equal_goto(tctx, nconv, -1, ret, done,
+ "smb_iconv failed\n");
+ torture_assert_errno_equal_goto(tctx, EINVAL, ret, done,
+ "Wrong errno\n");
+
+ src_blob = data_blob_const("foo", 3);
+ src = (const char *)src_blob.data;
+ srclen = src_blob.length;
+ dst = (char *)blob.data;
+ dst_left = 3;
+ nconv = smb_iconv(ic,
+ &src,
+ &srclen,
+ &dst,
+ &dst_left);
+ torture_assert_int_equal_goto(tctx, nconv, 3, ret, done,
+ "smb_iconv failed\n");
+
+ blob.length = nconv;
+ torture_assert_data_blob_equal(tctx,
+ src_blob,
+ blob,
+ "Conversion failed\n");
+
+ src_blob = data_blob_const("foo", 4);
+ src = (const char *)src_blob.data;
+ srclen = src_blob.length;
+ dst = (char *)blob.data;
+ dst_left = 4;
+ nconv = smb_iconv(ic,
+ &src,
+ &srclen,
+ &dst,
+ &dst_left);
+ torture_assert_int_equal_goto(tctx, nconv, 4, ret, done,
+ "smb_iconv failed\n");
+
+ blob.length = nconv;
+ torture_assert_data_blob_equal(tctx,
+ src_blob,
+ blob,
+ "Conversion failed\n");
+
+done:
+ return ret;
+}
+
+static bool test_utf8_nfc_to_nfd(struct torture_context *tctx)
+{
+ smb_iconv_t ic;
+ DATA_BLOB utf8_nfc_blob;
+ DATA_BLOB utf8_nfd_blob;
+ DATA_BLOB blob;
+ size_t nconv;
+ const char *src = NULL;
+ char *dst = NULL;
+ size_t dst_left;
+ size_t srclen;
+ bool ret = true;
+
+ ic = smb_iconv_open("UTF8-NFD", "UTF8-NFC");
+ torture_assert_goto(tctx, ic != (smb_iconv_t)-1, ret, done,
+ "creating iconv handle\n");
+
+ utf8_nfc_blob = base64_decode_data_blob_talloc(tctx, utf8_nfc_base64);
+ torture_assert_not_null_goto(tctx, utf8_nfc_blob.data, ret, done,
+ "OOM\n");
+
+ utf8_nfd_blob = base64_decode_data_blob_talloc(tctx, utf8_nfd_base64);
+ torture_assert_not_null_goto(tctx, utf8_nfd_blob.data, ret, done,
+ "OOM\n");
+
+ blob = data_blob_talloc_zero(tctx, 255);
+ torture_assert_not_null_goto(tctx, blob.data, ret, done, "OOM\n");
+
+ dst = (char *)blob.data;
+ dst_left = blob.length;
+ src = (const char *)utf8_nfc_blob.data;
+ srclen = strlen(src);
+
+ nconv = smb_iconv(ic,
+ &src,
+ &srclen,
+ &dst,
+ &dst_left);
+ torture_assert_goto(tctx, nconv != (size_t)-1, ret, done,
+ "smb_iconv failed\n");
+
+ blob.length = nconv + 1; /* +1 for the trailing zero */
+ torture_assert_data_blob_equal(tctx,
+ blob,
+ utf8_nfd_blob,
+ "Conversion failed\n");
+
+done:
+ return ret;
+}
+
+static bool test_utf8_nfd_to_nfc(struct torture_context *tctx)
+{
+ smb_iconv_t ic;
+ DATA_BLOB utf8_nfc_blob;
+ DATA_BLOB utf8_nfd_blob;
+ DATA_BLOB blob;
+ size_t nconv;
+ const char *src = NULL;
+ char *dst = NULL;
+ size_t dst_left;
+ size_t srclen;
+ bool ret = true;
+
+ ic = smb_iconv_open("UTF8-NFC", "UTF8-NFD");
+ torture_assert_goto(tctx, ic != (smb_iconv_t)-1, ret, done,
+ "creating iconv handle\n");
+
+ utf8_nfc_blob = base64_decode_data_blob_talloc(tctx, utf8_nfc_base64);
+ torture_assert_not_null_goto(tctx, utf8_nfc_blob.data, ret, done,
+ "OOM\n");
+
+ utf8_nfd_blob = base64_decode_data_blob_talloc(tctx, utf8_nfd_base64);
+ torture_assert_not_null_goto(tctx, utf8_nfd_blob.data, ret, done,
+ "OOM\n");
+
+ blob = data_blob_talloc_zero(tctx, 255);
+ torture_assert_not_null_goto(tctx, blob.data, ret, done, "OOM\n");
+
+ dst = (char *)blob.data;
+ dst_left = blob.length;
+ src = (const char *)utf8_nfd_blob.data;
+ srclen = strlen(src);
+
+ nconv = smb_iconv(ic,
+ &src,
+ &srclen,
+ &dst,
+ &dst_left);
+ torture_assert_goto(tctx, nconv != (size_t)-1, ret, done,
+ "smb_iconv failed\n");
+
+ blob.length = nconv + 1; /* +1 for the trailing zero */
+ torture_assert_data_blob_equal(tctx,
+ blob,
+ utf8_nfc_blob,
+ "Conversion failed\n");
+
+done:
+ return ret;
+}
+
+static bool test_gd_case_utf8_handle(struct torture_context *tctx)
+{
+ struct smb_iconv_handle *iconv_handle;
+ DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
+ DATA_BLOB gd_utf8_upper = base64_decode_data_blob(gd_utf8_upper_base64);
+ DATA_BLOB gd_utf8_lower = base64_decode_data_blob(gd_utf8_lower_base64);
+ char *gd_lower, *gd_upper;
+ talloc_steal(tctx, gd_utf8.data);
+
+ iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8",
+ lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ torture_assert(tctx, iconv_handle, "getting utf8 iconv handle");
+
+ torture_assert(tctx,
+ strhasupper_handle(iconv_handle, (const char *)gd_utf8.data),
+ "GD's name has an upper case character");
+ torture_assert(tctx,
+ strhaslower_handle(iconv_handle, (const char *)gd_utf8.data),
+ "GD's name has an lower case character");
+ gd_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)gd_utf8.data);
+ torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
+ torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_lower), gd_utf8_lower,
+ "convert GD's name into lower case");
+ gd_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)gd_utf8.data, gd_utf8.length);
+ torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
+ torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_upper), gd_utf8_upper,
+ "convert GD's name into upper case");
+
+ torture_assert(tctx,
+ strhasupper_handle(iconv_handle, gd_upper),
+ "upper case name has an upper case character");
+ torture_assert(tctx,
+ strhaslower_handle(iconv_handle, gd_lower),
+ "lower case name has an lower case character");
+ torture_assert(tctx,
+ strhasupper_handle(iconv_handle, gd_lower) == false,
+ "lower case name has no upper case character");
+ torture_assert(tctx,
+ strhaslower_handle(iconv_handle, gd_upper) == false,
+ "upper case name has no lower case character");
+
+ torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
+ gd_upper) == 0,
+ "case insensitive comparison orig/upper");
+ torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
+ gd_lower) == 0,
+ "case insensitive comparison orig/lower");
+ torture_assert(tctx, strcasecmp_m_handle(iconv_handle, gd_upper,
+ gd_lower) == 0,
+ "case insensitive comparison upper/lower");
+
+ /* This string isn't different in length upper/lower */
+ torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
+ gd_upper, gd_utf8.length) == 0,
+ "case insensitive comparison orig/upper");
+ torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_utf8.data,
+ gd_lower, gd_utf8.length) == 0,
+ "case insensitive comparison orig/lower");
+ torture_assert(tctx, strncasecmp_m_handle(iconv_handle, gd_upper,
+ gd_lower, gd_utf8.length) == 0,
+ "case insensitive comparison upper/lower");
+
+ data_blob_free(&gd_utf8);
+ data_blob_free(&gd_utf8_upper);
+ data_blob_free(&gd_utf8_lower);
+
+ return true;
+}
+
+static bool test_gd_case_cp850_handle(struct torture_context *tctx)
+{
+ struct smb_iconv_handle *iconv_handle;
+ DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
+ DATA_BLOB gd_cp850_upper = base64_decode_data_blob(gd_cp850_upper_base64);
+ DATA_BLOB gd_cp850_lower = base64_decode_data_blob(gd_cp850_lower_base64);
+ char *gd_lower, *gd_upper;
+ talloc_steal(tctx, gd_cp850.data);
+
+ iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "CP850",
+ lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ torture_assert(tctx, iconv_handle, "getting cp850 iconv handle");
+
+ torture_assert(tctx,
+ strhasupper_handle(iconv_handle, (const char *)gd_cp850.data),
+ "GD's name has an upper case character");
+ torture_assert(tctx,
+ strhaslower_handle(iconv_handle, (const char *)gd_cp850.data),
+ "GD's name has an lower case character");
+ gd_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)gd_cp850.data);
+ torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
+ torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_lower), gd_cp850_lower,
+ "convert GD's name into lower case");
+ gd_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)gd_cp850.data, gd_cp850.length);
+ torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
+ torture_assert_data_blob_equal(tctx, data_blob_string_const(gd_upper), gd_cp850_upper,
+ "convert GD's name into upper case");
+
+ torture_assert(tctx,
+ strhasupper_handle(iconv_handle, gd_upper),
+ "upper case name has an upper case character");
+ torture_assert(tctx,
+ strhaslower_handle(iconv_handle, gd_lower),
+ "lower case name has an lower case character");
+ torture_assert(tctx,
+ strhasupper_handle(iconv_handle, gd_lower) == false,
+ "lower case name has no upper case character");
+ torture_assert(tctx,
+ strhaslower_handle(iconv_handle, gd_upper) == false,
+ "upper case name has no lower case character");
+
+ torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
+ gd_upper) == 0,
+ "case insensitive comparison orig/upper");
+ torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
+ gd_lower) == 0,
+ "case insensitive comparison orig/lower");
+ torture_assert(tctx, strcasecmp_m_handle(iconv_handle, gd_upper,
+ gd_lower) == 0,
+ "case insensitive comparison upper/lower");
+
+ /* This string isn't different in length upper/lower */
+ torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
+ gd_upper, gd_cp850.length) == 0,
+ "case insensitive comparison orig/upper");
+ torture_assert(tctx, strncasecmp_m_handle(iconv_handle, (const char *)gd_cp850.data,
+ gd_lower, gd_cp850.length) == 0,
+ "case insensitive comparison orig/lower");
+ torture_assert(tctx, strncasecmp_m_handle(iconv_handle, gd_upper,
+ gd_lower, gd_cp850.length) == 0,
+ "case insensitive comparison upper/lower");
+
+ data_blob_free(&gd_cp850);
+ data_blob_free(&gd_cp850_upper);
+ data_blob_free(&gd_cp850_lower);
+
+ return true;
+}
+
+static bool test_plato_case_utf8_handle(struct torture_context *tctx)
+{
+ struct smb_iconv_handle *iconv_handle;
+ DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
+ char *plato_lower, *plato_upper;
+ talloc_steal(tctx, plato_utf8.data);
+
+ iconv_handle = get_iconv_testing_handle(tctx, "ASCII", "UTF8",
+ lpcfg_parm_bool(tctx->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ torture_assert(tctx, iconv_handle, "getting utf8 iconv handle");
+
+ torture_assert(tctx,
+ strhasupper_handle(iconv_handle, (const char *)plato_utf8.data),
+ "PLATO's apology has an upper case character");
+ torture_assert(tctx,
+ strhaslower_handle(iconv_handle, (const char *)plato_utf8.data),
+ "PLATO's apology has an lower case character");
+ plato_lower = strlower_talloc_handle(iconv_handle, tctx, (const char *)plato_utf8.data);
+ torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into lower case");
+ plato_upper = strupper_talloc_n_handle(iconv_handle, tctx, (const char *)plato_utf8.data, plato_utf8.length);
+ torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into upper case");
+
+ torture_assert(tctx,
+ strhasupper_handle(iconv_handle, plato_upper),
+ "upper case string has an upper case character");
+ torture_assert(tctx,
+ strhaslower_handle(iconv_handle, plato_lower),
+ "lower case string has an lower case character");
+ torture_assert(tctx,
+ strhasupper_handle(iconv_handle, plato_lower) == false,
+ "lower case string has no upper case character");
+ torture_assert(tctx,
+ strhaslower_handle(iconv_handle, plato_upper) == false,
+ "upper case string has no lower case character");
+
+ torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)plato_utf8.data,
+ plato_upper) == 0,
+ "case insensitive comparison orig/upper");
+ torture_assert(tctx, strcasecmp_m_handle(iconv_handle, (const char *)plato_utf8.data,
+ plato_lower) == 0,
+ "case insensitive comparison orig/lower");
+ torture_assert(tctx, strcasecmp_m_handle(iconv_handle, plato_upper,
+ plato_lower) == 0,
+ "case insensitive comparison upper/lower");
+ return true;
+}
+
+static bool test_gd(struct torture_context *tctx)
+{
+ DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
+ DATA_BLOB gd_cp850 = base64_decode_data_blob(gd_cp850_base64);
+ DATA_BLOB gd_iso8859_1 = base64_decode_data_blob(gd_iso8859_1_base64);
+ DATA_BLOB gd_utf16le = base64_decode_data_blob(gd_utf16le_base64);
+ DATA_BLOB gd_output;
+ size_t saved_len;
+
+ talloc_steal(tctx, gd_utf8.data);
+ talloc_steal(tctx, gd_cp850.data);
+ talloc_steal(tctx, gd_iso8859_1.data);
+ talloc_steal(tctx, gd_utf16le.data);
+
+ torture_assert(tctx, convert_string_talloc(tctx, CH_UTF8, CH_UTF8,
+ gd_utf8.data, gd_utf8.length,
+ (void *)&gd_output.data, &gd_output.length),
+ "conversion from UTF8 to utf8 charset");
+ saved_len = gd_output.length;
+
+ torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
+ gd_utf8.data, gd_utf8.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length),
+ "conversion from UTF8 to utf8 charset");
+
+ /* Short output handling confirmation */
+ gd_output.length = 1;
+ torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
+ gd_utf8.data, gd_utf8.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF8 to any utf8 charset should fail due to too short");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to utf8 charset should fail E2BIG");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
+ torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF8 to utf8 charset incorrect");
+
+#if 0 /* This currently fails as we just copy like-for-like character conversions */
+ /* Short output handling confirmation */
+ gd_output.length = 2;
+ torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
+ gd_utf8.data, gd_utf8.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF8 to utf8 charset should fail due to too short");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF8 to utf8 charset should fail E2BIG");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
+
+ /* Short input handling confirmation */
+ gd_output.length = saved_len;
+ torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
+ gd_utf8.data, 2,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF8 to UTF8 should fail due to too short");
+ torture_assert_errno_equal(tctx, EILSEQ, "conversion from short UTF8 to UTF8 should fail EINVAL");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
+#endif
+
+ /* Short output handling confirmation */
+ gd_output.length = 1;
+ torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
+ gd_utf16le.data, gd_utf16le.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF16 to UTF8 should fail due to too short");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to UTF8 should fail E2BIG");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
+ torture_assert_data_blob_equal(tctx, gd_output, data_blob_string_const("G"), "conversion from UTF16 to UTF8 incorrect");
+
+ /* Short output handling confirmation */
+ gd_output.length = 3;
+ torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
+ gd_utf16le.data, gd_utf16le.length,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF16 to UTF8 should fail due to too short");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion from UTF16 to UTF8 should fail E2BIG");
+ torture_assert_int_equal(tctx, gd_output.length, 3, "Should get 3 bytes output for UTF8");
+
+ /* Short input handling confirmation */
+ gd_output.length = saved_len;
+ torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
+ gd_utf16le.data, 3,
+ (void *)gd_output.data, gd_output.length,
+ &gd_output.length) == false,
+ "conversion from UTF16 to UTF8 should fail due to too short");
+ torture_assert_errno_equal(tctx, EINVAL, "conversion from short UTF16 to UTF8 should fail EINVAL");
+ torture_assert_int_equal(tctx, gd_output.length, 1, "Should only get 1 char of output");
+
+ return true;
+}
+
+static bool test_plato(struct torture_context *tctx)
+{
+ DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
+ DATA_BLOB plato_utf16le = base64_decode_data_blob(plato_utf16le_base64);
+ DATA_BLOB plato_output;
+ DATA_BLOB plato_output2;
+
+ talloc_steal(tctx, plato_utf8.data);
+ talloc_steal(tctx, plato_utf16le.data);
+
+ torture_assert(tctx, convert_string_talloc(tctx,
+ CH_UTF8, CH_UTF16LE,
+ plato_utf8.data, plato_utf8.length,
+ (void *)&plato_output.data, &plato_output.length),
+ "conversion of UTF8 ancient greek to UTF16 failed");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
+
+ torture_assert_int_equal(tctx,
+ strlen_m_ext((const char *)plato_utf8.data,
+ CH_UTF8, CH_UTF16LE),
+ plato_output.length / 2,
+ "checking strlen_m_ext of conversion of UTF8 to UTF16LE");
+
+ memset(plato_output.data, '\0', plato_output.length);
+ torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF16LE,
+ plato_utf8.data, plato_utf8.length,
+ (void *)plato_output.data, plato_output.length,
+ &plato_output.length),
+ "conversion of UTF8 ancient greek to UTF16 failed");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf16le, "conversion from UTF8 to UTF16LE incorrect");
+
+ torture_assert(tctx, convert_string_talloc(tctx,
+ CH_UTF16LE, CH_UTF8,
+ plato_output.data, plato_output.length,
+ (void *)&plato_output2.data, &plato_output2.length),
+ "conversion of UTF8 ancient greek to UTF16 failed");
+ torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
+
+ memset(plato_output2.data, '\0', plato_output2.length);
+ torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
+ plato_output.data, plato_output.length,
+ (void *)plato_output2.data, plato_output2.length, &plato_output2.length),
+ "conversion of UTF8 ancient greek to UTF16 failed");
+ torture_assert_data_blob_equal(tctx, plato_output2, plato_utf8, "conversion from UTF8 to UTF16LE incorrect");
+
+ torture_assert(tctx, convert_string_talloc(tctx,
+ CH_UTF8, CH_UTF8,
+ plato_utf8.data, plato_utf8.length,
+ (void *)&plato_output.data, &plato_output.length),
+ "conversion of UTF8 to UTF8");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
+ "conversion of UTF8 to UTF8");
+ torture_assert_int_equal(tctx,
+ strlen_m_ext((const char *)plato_utf8.data,
+ CH_UTF8, CH_UTF8),
+ plato_output.length,
+ "checking strlen_m_ext of conversion of UTF8 to UTF8");
+ memset(plato_output.data, '\0', plato_output.length);
+ torture_assert(tctx, convert_string_error(CH_UTF8, CH_UTF8,
+ plato_utf8.data, plato_utf8.length,
+ (void *)plato_output.data, plato_output.length,
+ &plato_output.length),
+ "conversion of UTF8 to UTF8");
+ torture_assert_data_blob_equal(tctx, plato_output, plato_utf8,
+ "conversion of UTF8 to UTF8");
+
+ memset(plato_output.data, '\0', plato_output.length);
+ torture_assert(tctx, convert_string_error(CH_UTF8, CH_DOS,
+ plato_utf8.data, plato_utf8.length,
+ (void *)plato_output.data, plato_output.length,
+ &plato_output.length) == false,
+ "conversion of UTF8 to any dos charset should fail");
+ torture_assert_errno_equal(tctx, EILSEQ, "conversion of UTF16 ancient greek to any DOS charset should fail EILSEQ");
+
+ torture_assert(tctx, convert_string_talloc(tctx,
+ CH_UTF8, CH_DOS,
+ plato_utf8.data, plato_utf8.length,
+ (void *)&plato_output.data, &plato_output.length) == false,
+ "conversion of UTF8 ancient greek to any DOS charset should fail");
+
+ /* Allocate only enough space for a partial conversion */
+ plato_output = data_blob_talloc(tctx, NULL, 9);
+ torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
+ plato_utf16le.data, plato_utf16le.length,
+ (void *)plato_output.data, plato_output.length,
+ &plato_output.length) == false,
+ "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
+ torture_assert_int_equal(tctx, plato_output.length, 8,
+ "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
+
+ plato_output = data_blob_talloc(tctx, NULL, 2);
+ torture_assert(tctx, convert_string_error(CH_UTF16LE, CH_UTF8,
+ plato_utf16le.data, plato_utf16le.length,
+ (void *)plato_output.data, plato_output.length,
+ &plato_output.length) == false,
+ "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
+ torture_assert_errno_equal(tctx, E2BIG, "conversion of UTF16 ancient greek to UTF8 should fail, not enough space");
+ torture_assert_int_equal(tctx, plato_output.length, 0,
+ "conversion of UTF16 ancient greek to UTF8 should stop on multibyte boundary");
+
+
+ return true;
+}
+
+
+
+static bool test_short_strings(struct torture_context *tctx)
+{
+ char zeros[6] = {0};
+ char s[6] = {'s'};
+ bool ok;
+ char *out;
+ size_t out_len;
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF8, CH_UTF16LE,
+ zeros, 0,
+ &out, &out_len);
+ torture_assert(tctx, ok, "{\"\", 0} to utf16 failed");
+ torture_assert(tctx, out_len == 2, "{\"\", 0} length is two");
+ torture_assert(tctx, out[0] == 0 && out[1] == 0, "{\"\", 0} utf16 is zero");
+ TALLOC_FREE(out);
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF8, CH_UTF16LE,
+ zeros, 1,
+ &out, &out_len);
+ torture_assert(tctx, ok, "{\"\\0\", 1} to utf16 failed");
+ torture_assert(tctx, out_len == 2, "{\"\\0\", 1} length is two");
+ torture_assert(tctx, out[0] == 0 && out[1] == 0, "{\"\\0\", 1} utf16 is zero");
+ TALLOC_FREE(out);
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF8, CH_UTF16LE,
+ zeros, 2,
+ &out, &out_len);
+ torture_assert(tctx, ok, "{\"\\0\\0\", 2} to utf16 failed");
+ torture_assert(tctx, out_len == 4, "{\"\\0\\0\", 2} length is four");
+ torture_assert(tctx, out[0] == 0 && out[1] == 0, "{\"\\0\\0\", 2} utf16 is zero");
+ TALLOC_FREE(out);
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF8, CH_UTF16LE,
+ s, 0,
+ &out, &out_len);
+ torture_assert(tctx, ok, "{\"s\", 0} to utf16 failed");
+ torture_assert(tctx, out_len == 2, "{\"s\", 0} length is two");
+ torture_assert(tctx, out[0] == 0 && out[1] == 0,
+ "{\"s\", 0} utf16 is zero");
+ TALLOC_FREE(out);
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF8, CH_UTF16LE,
+ s, 1,
+ &out, &out_len);
+ torture_assert(tctx, ok, "{\"s\", 1} to utf16 failed");
+ torture_assert(tctx, out_len == 2, "{\"s\", 1} length is two");
+ torture_assert(tctx, out[0] == 's' && out[1] == 0,
+ "{\"s\", 1} utf16 is s");
+ TALLOC_FREE(out);
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF8, CH_UTF16LE,
+ s, 2,
+ &out, &out_len);
+ torture_assert(tctx, ok, "{\"s\\0\", 2} to utf16 failed");
+ torture_assert(tctx, out_len == 4, "{\"s\\0\", 2} length is four");
+ torture_assert(tctx, out[0] == 's' && out[1] == 0,
+ "{\"s\\0\", 0} utf16 is s");
+ TALLOC_FREE(out);
+
+
+ /* going to utf8 */
+ ok = convert_string_talloc(tctx,
+ CH_UTF16LE, CH_UTF8,
+ zeros, 0,
+ &out, &out_len);
+ torture_assert(tctx, ok, "{\"\", 0} to utf8 failed");
+ torture_assert(tctx, out_len == 1, "{\"\", 0} length is one");
+ torture_assert(tctx, out[0] == 0, "{\"\", 0} utf8[0] is zero");
+ TALLOC_FREE(out);
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF16LE, CH_UTF8,
+ zeros, 2,
+ &out, &out_len);
+ torture_assert(tctx, ok, "{\"\\0\", 1} to utf8 failed");
+ torture_assert(tctx, out_len == 1, "{\"\\0\", 1} length is one");
+ torture_assert(tctx, out[0] == 0 && out[1] == 0,
+ "{\"\\0\", 1} utf8 is zero");
+ TALLOC_FREE(out);
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF16LE, CH_UTF8,
+ zeros, 4,
+ &out, &out_len);
+ torture_assert(tctx, ok, "{\"\\0\\0\\0\\0\", 4} to utf8 failed");
+ torture_assert(tctx, out_len == 2, "{\"\\0\\0\\0\\0\", 4} length is two");
+ torture_assert(tctx, out[0] == 0 && out[1] == 0,
+ "{\"\\0\\0\\0\\0\", 4} utf8 is zero");
+ TALLOC_FREE(out);
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF16LE, CH_UTF8,
+ s, 0,
+ &out, &out_len);
+ torture_assert(tctx, ok, "{\"s\", 0} to utf8 failed");
+ torture_assert(tctx, out_len == 1, "{\"s\", 0} length is one");
+ torture_assert(tctx, out[0] == 0, "{\"s\", 0} utf8 is zero");
+ TALLOC_FREE(out);
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF16LE, CH_UTF8,
+ s, 2,
+ &out, &out_len);
+ torture_assert(tctx, ok, "{\"s\\0\", 2} to utf8 failed");
+ torture_assert(tctx, out_len == 1, "{\"s\\0\", 2} length is one");
+ torture_assert(tctx, out[0] == 's' && out[1] == 0,
+ "{\"s\\0\", 2} utf8 is s");
+ TALLOC_FREE(out);
+
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF16LE, CH_UTF8,
+ s, 4,
+ &out, &out_len);
+ torture_assert(tctx, ok, "{\"s\\0\\0\\0\", 4} utf8 failed");
+ torture_assert(tctx, out_len == 2, "\"s\\0\\0\\0\", 4} utf8 length is two");
+ torture_assert(tctx, out[0] == 's' && out[1] == 0,
+ "{\"s\\0\\0\\0\", 4} utf8 is s");
+ TALLOC_FREE(out);
+
+ /* odd numbers of bytes from UTF-16 should fail */
+ ok = convert_string_talloc(tctx,
+ CH_UTF16LE, CH_UTF8,
+ s, 1,
+ &out, &out_len);
+ torture_assert(tctx, ! ok, "{\"s\", 1} to utf8 should have failed");
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF16LE, CH_UTF8,
+ s, 3,
+ &out, &out_len);
+ torture_assert(tctx, ! ok, "{\"s\\0\\0\", 3} to utf8 should have failed");
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF16LE, CH_UTF8,
+ zeros, 1,
+ &out, &out_len);
+ torture_assert(tctx, ! ok,
+ "{\"\\0\", 1} to utf8 should have failed");
+
+ ok = convert_string_talloc(tctx,
+ CH_UTF16LE, CH_UTF8,
+ zeros, 5,
+ &out, &out_len);
+ torture_assert(tctx, ! ok,
+ "{\"\\0\\0\\0\\0\", 5} to utf8 should have failed");
+
+ return true;
+}
+
+
+static bool test_plato_latin(struct torture_context *tctx)
+{
+ DATA_BLOB plato_latin_utf8 = base64_decode_data_blob(plato_latin_utf8_base64);
+ DATA_BLOB plato_latin_utf16le = base64_decode_data_blob(plato_latin_utf16le_base64);
+ DATA_BLOB plato_latin_output;
+
+ talloc_steal(tctx, plato_latin_utf8.data);
+ talloc_steal(tctx, plato_latin_utf16le.data);
+
+ torture_assert(tctx, convert_string_talloc(tctx,
+ CH_UTF16LE, CH_UTF8,
+ plato_latin_utf16le.data, plato_latin_utf16le.length,
+ (void *)&plato_latin_output.data, &plato_latin_output.length),
+ "conversion of UTF16 latin charset greek to unix charset UTF8 failed");
+ torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf8, "conversion from UTF16 to UTF8 incorrect");
+
+ torture_assert_int_equal(tctx,
+ strlen_m_ext((const char *)plato_latin_output.data,
+ CH_UTF8, CH_UTF16LE),
+ plato_latin_utf16le.length / 2,
+ "checking strlen_m_ext UTF16 latin charset greek to UTF8");
+ torture_assert(tctx, convert_string_talloc(tctx,
+ CH_UTF8, CH_UTF16LE,
+ plato_latin_utf8.data, plato_latin_utf8.length,
+ (void *)&plato_latin_output.data, &plato_latin_output.length),
+ "conversion of UTF16 latin charset greek to UTF16LE failed");
+ torture_assert_data_blob_equal(tctx, plato_latin_output, plato_latin_utf16le, "conversion from UTF8 to UTF16LE incorrect");
+
+ return true;
+}
+
+static bool test_gd_case(struct torture_context *tctx)
+{
+ DATA_BLOB gd_utf8 = base64_decode_data_blob(gd_utf8_base64);
+ char *gd_unix;
+ size_t gd_size;
+ char *gd_lower, *gd_upper;
+ talloc_steal(tctx, gd_utf8.data);
+
+ torture_assert(tctx, convert_string_talloc(tctx, CH_UTF8, CH_UNIX,
+ gd_utf8.data, gd_utf8.length,
+ (void *)&gd_unix, &gd_size),
+ "conversion of unix charset to UTF8");
+
+ gd_lower = strlower_talloc(tctx, gd_unix);
+ torture_assert(tctx, gd_lower, "failed to convert GD's name into lower case");
+ gd_upper = strupper_talloc_n(tctx, gd_unix, gd_size);
+ torture_assert(tctx, gd_lower, "failed to convert GD's name into upper case");
+
+ torture_assert(tctx,
+ strhasupper(gd_unix),
+ "GD's name has an upper case character");
+ torture_assert(tctx,
+ strhaslower(gd_unix),
+ "GD's name has an lower case character");
+ torture_assert(tctx,
+ strhasupper(gd_upper),
+ "upper case name has an upper case character");
+ torture_assert(tctx,
+ strhaslower(gd_lower),
+ "lower case name has an lower case character");
+ torture_assert(tctx,
+ strhasupper(gd_lower) == false,
+ "lower case name has no upper case character");
+ torture_assert(tctx,
+ strhaslower(gd_upper) == false,
+ "upper case name has no lower case character");
+
+ torture_assert(tctx, strcasecmp_m(gd_unix,
+ gd_upper) == 0,
+ "case insensitive comparison orig/upper");
+ torture_assert(tctx, strcasecmp_m(gd_unix,
+ gd_lower) == 0,
+ "case insensitive comparison orig/lower");
+ torture_assert(tctx, strcasecmp_m(gd_upper,
+ gd_lower) == 0,
+ "case insensitive comparison upper/lower");
+
+ /* This string isn't different in length upper/lower, but just check the first 5 chars */
+ torture_assert(tctx, strncasecmp_m(gd_unix,
+ gd_upper, 5) == 0,
+ "case insensitive comparison orig/upper");
+ torture_assert(tctx, strncasecmp_m(gd_unix,
+ gd_lower, 5) == 0,
+ "case insensitive comparison orig/lower");
+ torture_assert(tctx, strncasecmp_m(gd_upper,
+ gd_lower, 5) == 0,
+ "case insensitive comparison upper/lower");
+ return true;
+}
+
+static bool test_plato_case(struct torture_context *tctx)
+{
+ DATA_BLOB plato_utf8 = base64_decode_data_blob(plato_utf8_base64);
+ char *plato_unix;
+ size_t plato_length;
+ char *plato_lower, *plato_upper;
+ talloc_steal(tctx, plato_utf8.data);
+
+ torture_assert(tctx, convert_string_talloc(tctx, CH_UTF8, CH_UNIX,
+ plato_utf8.data, plato_utf8.length,
+ (void *)&plato_unix, &plato_length),
+ "conversion of unix charset to UTF8");
+
+ torture_assert(tctx,
+ strhasupper(plato_unix),
+ "PLATO's apology has an upper case character");
+ torture_assert(tctx,
+ strhaslower(plato_unix),
+ "PLATO's apology has an lower case character");
+ plato_lower = strlower_talloc(tctx, plato_unix);
+ torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into lower case");
+ plato_upper = strupper_talloc_n(tctx, plato_unix, plato_utf8.length);
+ torture_assert(tctx, plato_lower, "failed to convert PLATO's apology into upper case");
+
+ torture_assert(tctx,
+ strhasupper(plato_upper),
+ "upper case string has an upper case character");
+ torture_assert(tctx,
+ strhaslower(plato_lower),
+ "lower case string has an lower case character");
+ torture_assert(tctx,
+ strhasupper(plato_lower) == false,
+ "lower case string has no upper case character");
+ torture_assert(tctx,
+ strhaslower(plato_upper) == false,
+ "upper case string has no lower case character");
+
+ torture_assert(tctx, strcasecmp_m(plato_unix,
+ plato_upper) == 0,
+ "case insensitive comparison orig/upper");
+ torture_assert(tctx, strcasecmp_m(plato_unix,
+ plato_lower) == 0,
+ "case insensitive comparison orig/lower");
+ torture_assert(tctx, strcasecmp_m(plato_upper,
+ plato_lower) == 0,
+ "case insensitive comparison upper/lower");
+ return true;
+}
+
+struct torture_suite *torture_local_convert_string_handle(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "convert_string_handle");
+ torture_suite_add_simple_test(suite, "cp850 high points", test_cp850_high_points);
+
+ torture_suite_add_simple_test(suite, "gd_ascii", test_gd_ascii_handle);
+ torture_suite_add_simple_test(suite, "gd_minus_1", test_gd_minus_1_handle);
+ torture_suite_add_simple_test(suite, "gd_iso8859_cp850", test_gd_iso8859_cp850_handle);
+ torture_suite_add_simple_test(suite, "plato_english_iso8859_cp850", test_plato_english_iso8859_cp850_handle);
+ torture_suite_add_simple_test(suite, "plato_english_minus_1", test_plato_english_minus_1_handle);
+ torture_suite_add_simple_test(suite, "plato_cp850_utf8", test_plato_cp850_utf8_handle);
+ torture_suite_add_simple_test(suite, "plato_minus_1", test_plato_minus_1_handle);
+ torture_suite_add_simple_test(suite, "plato_latin_cp850_utf8", test_plato_latin_cp850_utf8_handle);
+ torture_suite_add_simple_test(suite, "utf8-nfc-to-nfd", test_utf8_nfc_to_nfd);
+ torture_suite_add_simple_test(suite, "utf8-nfc-to-nfd-overflow", test_utf8_nfc_to_nfd_overflow);
+ torture_suite_add_simple_test(suite, "utf8-nfd-to-nfc", test_utf8_nfd_to_nfc);
+ return suite;
+}
+
+struct torture_suite *torture_local_string_case_handle(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "string_case_handle");
+
+ torture_suite_add_simple_test(suite, "gd_case_utf8", test_gd_case_utf8_handle);
+ torture_suite_add_simple_test(suite, "gd_case_cp850", test_gd_case_cp850_handle);
+ torture_suite_add_simple_test(suite, "plato_case_utf8", test_plato_case_utf8_handle);
+ return suite;
+}
+
+struct torture_suite *torture_local_convert_string(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "convert_string");
+
+ torture_suite_add_simple_test(suite, "short_strings", test_short_strings);
+ torture_suite_add_simple_test(suite, "gd", test_gd);
+ torture_suite_add_simple_test(suite, "plato", test_plato);
+ torture_suite_add_simple_test(suite, "plato_latin", test_plato_latin);
+ return suite;
+}
+
+struct torture_suite *torture_local_string_case(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "string_case_handle");
+
+ torture_suite_add_simple_test(suite, "gd_case", test_gd_case);
+ torture_suite_add_simple_test(suite, "plato_case", test_plato_case);
+ return suite;
+}
diff --git a/lib/util/charset/tests/iconv.c b/lib/util/charset/tests/iconv.c
new file mode 100644
index 0000000..3733c3c
--- /dev/null
+++ b/lib/util/charset/tests/iconv.c
@@ -0,0 +1,495 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ local testing of iconv routines. This tests the system iconv code against
+ the built-in iconv code
+
+ Copyright (C) Andrew Tridgell 2004
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "system/iconv.h"
+#include "system/time.h"
+#include "libcli/raw/libcliraw.h"
+#include "param/param.h"
+#include "torture/util.h"
+#include "torture/local/proto.h"
+#include "talloc.h"
+
+#ifdef HAVE_NATIVE_ICONV
+
+static bool iconv_untestable(struct torture_context *tctx)
+{
+ iconv_t cd;
+
+ cd = iconv_open("UTF-16LE", "UCS-4LE");
+ if (cd == (iconv_t)-1)
+ torture_skip(tctx, "unable to test - system iconv library does not support UTF-16LE -> UCS-4LE");
+ iconv_close(cd);
+
+ cd = iconv_open("UTF-16LE", "CP850");
+ if (cd == (iconv_t)-1)
+ torture_skip(tctx, "unable to test - system iconv library does not support UTF-16LE -> CP850\n");
+ iconv_close(cd);
+
+ return false;
+}
+
+/*
+ generate a UTF-16LE buffer for a given unicode codepoint
+*/
+static int gen_codepoint_utf16(unsigned int codepoint,
+ char *buf, size_t *size)
+{
+ static iconv_t cd;
+ uint8_t in[4];
+ char *ptr_in;
+ size_t size_in, size_out, ret;
+ if (!cd) {
+ cd = iconv_open("UTF-16LE", "UCS-4LE");
+ if (cd == (iconv_t)-1) {
+ cd = NULL;
+ return -1;
+ }
+ }
+
+ in[0] = codepoint & 0xFF;
+ in[1] = (codepoint>>8) & 0xFF;
+ in[2] = (codepoint>>16) & 0xFF;
+ in[3] = (codepoint>>24) & 0xFF;
+
+ ptr_in = (char *)in;
+ size_in = 4;
+ size_out = 8;
+
+ ret = iconv(cd, &ptr_in, &size_in, &buf, &size_out);
+
+ *size = 8 - size_out;
+
+ return ret;
+}
+
+
+/*
+ work out the unicode codepoint of the first UTF-8 character in the buffer
+*/
+static unsigned int get_codepoint(char *buf, size_t size, const char *charset)
+{
+ iconv_t cd;
+ uint8_t out[4];
+ char *ptr_out;
+ size_t size_out, size_in, ret;
+
+ cd = iconv_open("UCS-4LE", charset);
+
+ size_in = size;
+ ptr_out = (char *)out;
+ size_out = sizeof(out);
+ memset(out, 0, sizeof(out));
+
+ ret = iconv(cd, &buf, &size_in, &ptr_out, &size_out);
+ iconv_close(cd);
+ if (ret == (size_t) -1) {
+ return (unsigned int)-1;
+ }
+
+ return out[0] | (out[1]<<8) | (out[2]<<16) | (out[3]<<24);
+}
+
+/*
+ display a buffer with name prefix
+*/
+static void show_buf(const char *name, uint8_t *buf, size_t size)
+{
+ int i;
+ printf("%s ", name);
+ for (i=0;i<size;i++) {
+ printf("%02x ", buf[i]);
+ }
+ printf("\n");
+}
+
+/*
+ given a UTF-16LE buffer, test the system and built-in iconv code to
+ make sure they do exactly the same thing in converting the buffer to
+ "charset", then convert it back again and ensure we get the same
+ buffer back
+*/
+static bool test_buffer(struct torture_context *test,
+ uint8_t *inbuf, size_t size, const char *charset)
+{
+ uint8_t buf1[1000], buf2[1000], buf3[1000];
+ size_t outsize1, outsize2, outsize3;
+ const char *ptr_in1;
+ char *ptr_in2;
+ char *ptr_out;
+ size_t size_in1, size_in2, size_in3;
+ size_t ret1, ret2, ret3, len1, len2;
+ int errno1, errno2;
+ static iconv_t cd;
+ static smb_iconv_t cd2, cd3;
+ static const char *last_charset;
+
+ if (cd && last_charset) {
+ iconv_close(cd);
+ smb_iconv_close(cd2);
+ smb_iconv_close(cd3);
+ cd = NULL;
+ }
+
+ if (!cd) {
+ cd = iconv_open(charset, "UTF-16LE");
+ if (cd == (iconv_t)-1) {
+ torture_fail(test,
+ talloc_asprintf(test,
+ "failed to open %s to UTF-16LE",
+ charset));
+ }
+ cd2 = smb_iconv_open_ex(test, charset, "UTF-16LE", lpcfg_parm_bool(test->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ if (cd2 == (iconv_t)-1) {
+ torture_fail(test,
+ talloc_asprintf(test,
+ "failed to open %s to UTF-16LE via smb_iconv_open_ex",
+ charset));
+ }
+ cd3 = smb_iconv_open_ex(test, "UTF-16LE", charset, lpcfg_parm_bool(test->lp_ctx, NULL, "iconv", "use_builtin_handlers", true));
+ if (cd3 == (iconv_t)-1) {
+ torture_fail(test,
+ talloc_asprintf(test,
+ "failed to open UTF-16LE to %s via smb_iconv_open_ex",
+ charset));
+ }
+ last_charset = charset;
+ }
+
+ /* internal convert to charset - placing result in buf1 */
+ ptr_in1 = (const char *)inbuf;
+ ptr_out = (char *)buf1;
+ size_in1 = size;
+ outsize1 = sizeof(buf1);
+
+ memset(ptr_out, 0, outsize1);
+ errno = 0;
+ ret1 = smb_iconv(cd2, &ptr_in1, &size_in1, &ptr_out, &outsize1);
+ errno1 = errno;
+
+ /* system convert to charset - placing result in buf2 */
+ ptr_in2 = (char *)inbuf;
+ ptr_out = (char *)buf2;
+ size_in2 = size;
+ outsize2 = sizeof(buf2);
+
+ memset(ptr_out, 0, outsize2);
+ errno = 0;
+ ret2 = iconv(cd, &ptr_in2, &size_in2, &ptr_out, &outsize2);
+ errno2 = errno;
+
+ len1 = sizeof(buf1) - outsize1;
+ len2 = sizeof(buf2) - outsize2;
+
+ /* codepoints above 1M are not interesting for now */
+ if (len2 > len1 &&
+ memcmp(buf1, buf2, len1) == 0 &&
+ get_codepoint((char *)(buf2+len1), len2-len1, charset) >= (1<<20)) {
+ return true;
+ }
+ if (len1 > len2 &&
+ memcmp(buf1, buf2, len2) == 0 &&
+ get_codepoint((char *)(buf1+len2), len1-len2, charset) >= (1<<20)) {
+ return true;
+ }
+
+ torture_assert_int_equal(test, ret1, ret2, "ret mismatch");
+
+ if (errno1 != errno2) {
+ show_buf(" rem1:", inbuf+(size-size_in1), size_in1);
+ show_buf(" rem2:", inbuf+(size-size_in2), size_in2);
+ torture_fail(test, talloc_asprintf(test,
+ "errno mismatch with %s internal=%d/%s system=%d/%s",
+ charset,
+ errno1, strerror(errno1),
+ errno2, strerror(errno2)));
+ }
+
+ torture_assert_int_equal(test, outsize1, outsize2, "outsize mismatch");
+
+ torture_assert_int_equal(test, size_in1, size_in2, "size_in mismatch");
+
+ if (len1 != len2 ||
+ memcmp(buf1, buf2, len1) != 0) {
+ torture_comment(test, "size=%d ret1=%d ret2=%d", (int)size, (int)ret1, (int)ret2);
+ show_buf(" IN1:", inbuf, size-size_in1);
+ show_buf(" IN2:", inbuf, size-size_in2);
+ show_buf("OUT1:", buf1, len1);
+ show_buf("OUT2:", buf2, len2);
+ if (len2 > len1 && memcmp(buf1, buf2, len1) == 0) {
+ torture_comment(test, "next codepoint is %u",
+ get_codepoint((char *)(buf2+len1), len2-len1, charset));
+ }
+ if (len1 > len2 && memcmp(buf1, buf2, len2) == 0) {
+ torture_comment(test, "next codepoint is %u",
+ get_codepoint((char *)(buf1+len2),len1-len2, charset));
+ }
+
+ torture_fail(test, "failed");
+ }
+
+ /* convert back to UTF-16, putting result in buf3 */
+ size = size - size_in1;
+ ptr_in1 = (const char *)buf1;
+ ptr_out = (char *)buf3;
+ size_in3 = len1;
+ outsize3 = sizeof(buf3);
+
+ memset(ptr_out, 0, outsize3);
+ ret3 = smb_iconv(cd3, &ptr_in1, &size_in3, &ptr_out, &outsize3);
+
+ /* we only internally support the first 1M codepoints */
+ if (outsize3 != sizeof(buf3) - size &&
+ get_codepoint((char *)(inbuf+sizeof(buf3) - outsize3),
+ size - (sizeof(buf3) - outsize3),
+ "UTF-16LE") >= (1<<20)) {
+ return true;
+ }
+
+ torture_assert_int_equal(test, ret3, 0, talloc_asprintf(test,
+ "pull failed - %s", strerror(errno)));
+
+ if (strncmp(charset, "UTF", 3) != 0) {
+ /* don't expect perfect mappings for non UTF charsets */
+ return true;
+ }
+
+
+ torture_assert_int_equal(test, outsize3, sizeof(buf3) - size,
+ "wrong outsize3");
+
+ if (memcmp(buf3, inbuf, size) != 0) {
+ torture_comment(test, "pull bytes mismatch:");
+ show_buf("inbuf", inbuf, size);
+ show_buf(" buf3", buf3, sizeof(buf3) - outsize3);
+ torture_comment(test, "next codepoint is %u\n",
+ get_codepoint((char *)(inbuf+sizeof(buf3) - outsize3),
+ size - (sizeof(buf3) - outsize3),
+ "UTF-16LE"));
+ torture_fail(test, "");
+ }
+
+ return true;
+}
+
+
+/*
+ test the push_codepoint() and next_codepoint() functions for a given
+ codepoint
+*/
+static bool test_codepoint(struct torture_context *tctx, unsigned int codepoint)
+{
+ uint8_t buf[10];
+ size_t size, size2;
+ codepoint_t c;
+
+ size = push_codepoint_handle(lpcfg_iconv_handle(tctx->lp_ctx), (char *)buf, codepoint);
+ torture_assert(tctx, size != -1 || (codepoint >= 0xd800 && codepoint <= 0x10000),
+ "Invalid Codepoint range");
+
+ if (size == -1) return true;
+
+ buf[size] = random();
+ buf[size+1] = random();
+ buf[size+2] = random();
+ buf[size+3] = random();
+
+ c = next_codepoint_handle(lpcfg_iconv_handle(tctx->lp_ctx), (char *)buf, &size2);
+
+ torture_assert(tctx, c == codepoint,
+ talloc_asprintf(tctx,
+ "next_codepoint(%u) failed - gave %u", codepoint, c));
+
+ torture_assert(tctx, size2 == size,
+ talloc_asprintf(tctx, "next_codepoint(%u) gave wrong size %d (should be %d)\n",
+ codepoint, (int)size2, (int)size));
+
+ return true;
+}
+
+static bool test_next_codepoint(struct torture_context *tctx)
+{
+ unsigned int codepoint;
+ if (iconv_untestable(tctx))
+ return true;
+
+ for (codepoint=0;codepoint<(1<<20);codepoint++) {
+ if (!test_codepoint(tctx, codepoint))
+ return false;
+ }
+ return true;
+}
+
+static bool test_first_1m(struct torture_context *tctx)
+{
+ unsigned int codepoint;
+ size_t size;
+ unsigned char inbuf[1000];
+
+ if (iconv_untestable(tctx))
+ return true;
+
+ for (codepoint=0;codepoint<(1<<20);codepoint++) {
+ if (gen_codepoint_utf16(codepoint, (char *)inbuf, &size) != 0) {
+ continue;
+ }
+
+ if (codepoint % 1000 == 0) {
+ if (torture_setting_bool(tctx, "progress", true)) {
+ torture_comment(tctx, "codepoint=%u \r", codepoint);
+ fflush(stdout);
+ }
+ }
+
+ if (!test_buffer(tctx, inbuf, size, "UTF-8"))
+ return false;
+ }
+ return true;
+}
+
+static bool test_random_5m(struct torture_context *tctx)
+{
+ unsigned char inbuf[1000];
+ unsigned int i;
+
+ if (iconv_untestable(tctx))
+ return true;
+
+ for (i=0;i<500000;i++) {
+ size_t size;
+ unsigned int c;
+
+ if (i % 1000 == 0) {
+ if (torture_setting_bool(tctx, "progress", true)) {
+ torture_comment(tctx, "i=%u \r", i);
+ fflush(stdout);
+ }
+ }
+
+ size = random() % 100;
+ for (c=0;c<size;c++) {
+ if (random() % 100 < 80) {
+ inbuf[c] = random() % 128;
+ } else {
+ inbuf[c] = random();
+ }
+ if (random() % 10 == 0) {
+ inbuf[c] |= 0xd8;
+ }
+ if (random() % 10 == 0) {
+ inbuf[c] |= 0xdc;
+ }
+ }
+ if (!test_buffer(tctx, inbuf, size, "UTF-8")) {
+ printf("i=%d failed UTF-8\n", i);
+ return false;
+ }
+
+ if (!test_buffer(tctx, inbuf, size, "CP850")) {
+ printf("i=%d failed CP850\n", i);
+ return false;
+ }
+ }
+ return true;
+}
+
+
+static bool test_string2key(struct torture_context *tctx)
+{
+ uint16_t *buf;
+ char *dest = NULL;
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ size_t len = (random()%1000)+1;
+ const uint16_t in1[10] = { 'a', 0xd805, 'b', 0xdcf0, 'c', 0, 'd', 'e', 'f', 'g' };
+ uint8_t le1[20];
+ uint8_t *munged1;
+ uint8_t *out1;
+ size_t ret;
+ int i;
+ const char *correct = "a\357\277\275b\357\277\275c\001defg";
+
+ buf = talloc_size(mem_ctx, len*2);
+ generate_random_buffer((uint8_t *)buf, len*2);
+
+ torture_comment(tctx, "converting random buffer\n");
+
+ if (!convert_string_talloc(mem_ctx, CH_UTF16MUNGED, CH_UTF8, (void *)buf, len*2, (void**)&dest, &ret)) {
+ torture_fail(tctx, "Failed to convert random buffer\n");
+ }
+
+ for (i=0;i<10;i++) {
+ SSVAL(&le1[2*i], 0, in1[i]);
+ }
+
+ torture_comment(tctx, "converting fixed buffer to UTF16\n");
+
+ if (!convert_string_talloc(mem_ctx, CH_UTF16MUNGED, CH_UTF16, (void *)le1, 20, (void**)&munged1, &ret)) {
+ torture_fail(tctx, "Failed to convert fixed buffer to UTF16_MUNGED\n");
+ }
+
+ torture_assert(tctx, ret == 20, "conversion should give 20 bytes\n");
+
+ torture_comment(tctx, "converting fixed buffer to UTF8\n");
+
+ if (!convert_string_talloc(mem_ctx, CH_UTF16MUNGED, CH_UTF8, (void *)le1, 20, (void**)&out1, &ret)) {
+ torture_fail(tctx, "Failed to convert fixed buffer to UTF8\n");
+ }
+
+ torture_assert(tctx, strcmp(correct, (const char *) out1) == 0,
+ "conversion gave incorrect result\n");
+
+ talloc_free(mem_ctx);
+
+ return true;
+}
+
+struct torture_suite *torture_local_iconv(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "iconv");
+
+ torture_suite_add_simple_test(suite, "string2key",
+ test_string2key);
+
+ torture_suite_add_simple_test(suite, "next_codepoint()",
+ test_next_codepoint);
+
+ torture_suite_add_simple_test(suite, "first 1M codepoints",
+ test_first_1m);
+
+ torture_suite_add_simple_test(suite, "5M random UTF-16LE sequences",
+ test_random_5m);
+
+ torture_suite_add_simple_test(suite, "string2key",
+ test_string2key);
+ return suite;
+}
+
+#else
+
+struct torture_suite *torture_local_iconv(TALLOC_CTX *mem_ctx)
+{
+ printf("No native iconv library - can't run iconv test\n");
+ return NULL;
+}
+
+#endif
diff --git a/lib/util/charset/tests/util_unistr.c b/lib/util/charset/tests/util_unistr.c
new file mode 100644
index 0000000..1a9fcaa
--- /dev/null
+++ b/lib/util/charset/tests/util_unistr.c
@@ -0,0 +1,166 @@
+/*
+ Unix SMB/CIFS implementation.
+ test suite for the util_unistr utility functions
+
+ Copyright (C) Catalyst.Net Ltd. 2023
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+
+#undef strcasecmp
+#undef strncasecmp
+
+struct torture_suite *torture_local_util_unistr(TALLOC_CTX *mem_ctx);
+
+static bool test_utf16_len(struct torture_context *tctx)
+{
+ static const uint16_t empty_string[] = {'\0'};
+ static const uint16_t foo_bar[] = {
+ 'f', 'o', 'o', ' ', 'b', 'a', 'r', '\0'};
+ static const uint16_t foo_bar_alternative[] = {0xd83c,
+ 0xdd75,
+ 0xd83c,
+ 0xdd7e,
+ 0xd83c,
+ 0xdd7e,
+ ' ',
+ 0xd83c,
+ 0xdd31,
+ 0xd83c,
+ 0xdd30,
+ 0xd83c,
+ 0xdd41,
+ '\0'};
+
+ torture_assert_size_equal(tctx,
+ utf16_len(empty_string),
+ 0,
+ "length of empty string");
+ torture_assert_size_equal(tctx,
+ utf16_null_terminated_len(empty_string),
+ 2,
+ "null‐terminated length of empty string");
+ torture_assert_size_equal(tctx,
+ utf16_len(foo_bar),
+ 14,
+ "length of “foo bar”");
+ torture_assert_size_equal(tctx,
+ utf16_null_terminated_len(foo_bar),
+ 16,
+ "null‐terminated length of “foo bar”");
+ torture_assert_size_equal(tctx,
+ utf16_len(foo_bar_alternative),
+ 26,
+ "length of “🅵🅾🅾 🄱🄰🅁”");
+ torture_assert_size_equal(tctx,
+ utf16_null_terminated_len(
+ foo_bar_alternative),
+ 28,
+ "null‐terminated length of “🅵🅾🅾 🄱🄰🅁”");
+
+ return true;
+}
+
+static bool test_utf16_len_n(struct torture_context *tctx)
+{
+ static const uint16_t empty_string[] = {'\0'};
+ static const uint16_t foo_bar[] = {'f', 'o', 'o', ' ', 'b', 'a', 'r'};
+ static const uint16_t null_terminated_foo_bar[] = {
+ 'f', 'o', 'o', ' ', 'b', 'a', 'r', '\0'};
+ static const uint16_t twice_null_terminated_abc[] = {
+ 'a', 'b', 'c', '\0', '\0'};
+
+ torture_assert_size_equal(tctx,
+ utf16_len_n(empty_string, 0),
+ 0,
+ "length of empty string");
+ torture_assert_size_equal(tctx,
+ utf16_null_terminated_len_n(empty_string, 0),
+ 0,
+ "null‐terminated length of empty string");
+
+ torture_assert_size_equal(tctx,
+ utf16_len_n(empty_string,
+ sizeof empty_string),
+ 0,
+ "length of null‐terminated empty string");
+ torture_assert_size_equal(
+ tctx,
+ utf16_null_terminated_len_n(empty_string, sizeof empty_string),
+ 2,
+ "null‐terminated length of null‐terminated empty string");
+
+ torture_assert_size_equal(tctx,
+ utf16_len_n(foo_bar, sizeof foo_bar),
+ 14,
+ "length of “foo bar”");
+ torture_assert_size_equal(tctx,
+ utf16_null_terminated_len_n(foo_bar,
+ sizeof foo_bar),
+ 14,
+ "null‐terminated length of “foo bar”");
+
+ torture_assert_size_equal(tctx,
+ utf16_len_n(null_terminated_foo_bar,
+ sizeof null_terminated_foo_bar),
+ 14,
+ "length of null‐terminated “foo bar”");
+ torture_assert_size_equal(
+ tctx,
+ utf16_null_terminated_len_n(null_terminated_foo_bar,
+ sizeof null_terminated_foo_bar),
+ 16,
+ "null‐terminated length of null‐terminated “foo bar”");
+
+ torture_assert_size_equal(tctx,
+ utf16_len_n(null_terminated_foo_bar,
+ sizeof null_terminated_foo_bar -
+ 1),
+ 14,
+ "length of “foo bar” minus one byte");
+ torture_assert_size_equal(
+ tctx,
+ utf16_null_terminated_len_n(null_terminated_foo_bar,
+ sizeof null_terminated_foo_bar - 1),
+ 14,
+ "null‐terminated length of “foo bar” minus one byte");
+
+ torture_assert_size_equal(tctx,
+ utf16_len_n(twice_null_terminated_abc,
+ sizeof twice_null_terminated_abc),
+ 6,
+ "length of twice–null‐terminated “abc”");
+ torture_assert_size_equal(
+ tctx,
+ utf16_null_terminated_len_n(twice_null_terminated_abc,
+ sizeof twice_null_terminated_abc),
+ 8,
+ "null‐terminated length of twice–null‐terminated “abc”");
+
+ return true;
+}
+
+struct torture_suite *torture_local_util_unistr(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx,
+ "util_unistr");
+
+ torture_suite_add_simple_test(suite, "utf16_len", test_utf16_len);
+ torture_suite_add_simple_test(suite, "utf16_len_n", test_utf16_len_n);
+
+ return suite;
+}
diff --git a/lib/util/charset/util_str.c b/lib/util/charset/util_str.c
new file mode 100644
index 0000000..1650c9b
--- /dev/null
+++ b/lib/util/charset/util_str.c
@@ -0,0 +1,608 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Andrew Bartlett 2011
+ Copyright (C) Jeremy Allison 1992-2007
+ Copyright (C) Martin Pool 2003
+ Copyright (C) James Peach 2006
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/locale.h"
+#include "charset.h"
+#include "lib/util/fault.h"
+
+#ifdef strcasecmp
+#undef strcasecmp
+#endif
+#ifdef strncasecmp
+#undef strncasecmp
+#endif
+
+
+/**
+ Case insensitive string comparison, handle specified for testing
+**/
+_PUBLIC_ int strcasecmp_m_handle(struct smb_iconv_handle *iconv_handle,
+ const char *s1, const char *s2)
+{
+ codepoint_t c1=0, c2=0;
+ codepoint_t u1=0, u2=0;
+ codepoint_t l1=0, l2=0;
+ size_t size1, size2;
+
+ /* handle null ptr comparisons to simplify the use in qsort */
+ if (s1 == s2) return 0;
+ if (s1 == NULL) return -1;
+ if (s2 == NULL) return 1;
+
+ while (*s1 && *s2) {
+ c1 = next_codepoint_handle(iconv_handle, s1, &size1);
+ c2 = next_codepoint_handle(iconv_handle, s2, &size2);
+
+ if (c1 == INVALID_CODEPOINT ||
+ c2 == INVALID_CODEPOINT) {
+ return strcasecmp(s1, s2);
+ }
+
+ s1 += size1;
+ s2 += size2;
+
+ if (c1 == c2) {
+ continue;
+ }
+
+ u1 = toupper_m(c1);
+ u2 = toupper_m(c2);
+ if (u1 == u2) {
+ continue;
+ }
+
+ l1 = tolower_m(c1);
+ l2 = tolower_m(c2);
+ if (l1 == l2) {
+ continue;
+ }
+
+ return l1 - l2;
+ }
+
+ return *s1 - *s2;
+}
+
+/**
+ Case insensitive string comparison
+**/
+_PUBLIC_ int strcasecmp_m(const char *s1, const char *s2)
+{
+ struct smb_iconv_handle *iconv_handle = get_iconv_handle();
+ return strcasecmp_m_handle(iconv_handle, s1, s2);
+}
+
+/**
+ Case insensitive string comparison, length limited, handle specified for
+ testing
+**/
+_PUBLIC_ int strncasecmp_m_handle(struct smb_iconv_handle *iconv_handle,
+ const char *s1, const char *s2, size_t n)
+{
+ codepoint_t c1=0, c2=0;
+ codepoint_t u1=0, u2=0;
+ codepoint_t l1=0, l2=0;
+ size_t size1, size2;
+
+ /* handle null ptr comparisons to simplify the use in qsort */
+ if (s1 == s2) return 0;
+ if (s1 == NULL) return -1;
+ if (s2 == NULL) return 1;
+
+ while (*s1 && *s2 && n) {
+ n--;
+
+ c1 = next_codepoint_handle(iconv_handle, s1, &size1);
+ c2 = next_codepoint_handle(iconv_handle, s2, &size2);
+
+ if (c1 == INVALID_CODEPOINT ||
+ c2 == INVALID_CODEPOINT) {
+ /*
+ * n was specified in characters,
+ * now we must convert it to bytes.
+ * As bytes are the smallest
+ * character unit, the following
+ * increment and strncasecmp is always
+ * safe.
+ *
+ * The source string was already known
+ * to be n characters long, so we are
+ * guaranteed to be able to look at the
+ * (n remaining + size1) bytes from the
+ * s1 position).
+ */
+ n += size1;
+ return strncasecmp(s1, s2, n);
+ }
+
+ s1 += size1;
+ s2 += size2;
+
+ if (c1 == c2) {
+ continue;
+ }
+
+ u1 = toupper_m(c1);
+ u2 = toupper_m(c2);
+ if (u1 == u2) {
+ continue;
+ }
+
+ l1 = tolower_m(c1);
+ l2 = tolower_m(c2);
+ if (l1 == l2) {
+ continue;
+ }
+
+ return l1 - l2;
+ }
+
+ if (n == 0) {
+ return 0;
+ }
+
+ return *s1 - *s2;
+}
+
+/**
+ Case insensitive string comparison, length limited
+**/
+_PUBLIC_ int strncasecmp_m(const char *s1, const char *s2, size_t n)
+{
+ struct smb_iconv_handle *iconv_handle = get_iconv_handle();
+ return strncasecmp_m_handle(iconv_handle, s1, s2, n);
+}
+
+/**
+ * Compare 2 strings.
+ *
+ * @note The comparison is case-insensitive.
+ **/
+_PUBLIC_ bool strequal_m(const char *s1, const char *s2)
+{
+ return strcasecmp_m(s1,s2) == 0;
+}
+
+/**
+ Compare 2 strings (case sensitive).
+**/
+_PUBLIC_ bool strcsequal(const char *s1,const char *s2)
+{
+ if (s1 == s2)
+ return true;
+ if (!s1 || !s2)
+ return false;
+
+ return strcmp(s1,s2) == 0;
+}
+
+/**
+ * Calculate the number of units (8 or 16-bit, depending on the
+ * destination charset) that would be needed to convert the input
+ * string, which is expected to be in src_charset encoding, to the
+ * destination charset (which should be a unicode charset).
+ */
+_PUBLIC_ size_t strlen_m_ext_handle(struct smb_iconv_handle *ic,
+ const char *s, charset_t src_charset, charset_t dst_charset)
+{
+ size_t count = 0;
+
+#ifdef DEVELOPER
+ switch (dst_charset) {
+ case CH_DOS:
+ case CH_UNIX:
+ smb_panic("cannot call strlen_m_ext() with a variable dest charset (must be UTF16* or UTF8)");
+ default:
+ break;
+ }
+
+ switch (src_charset) {
+ case CH_UTF16LE:
+ case CH_UTF16BE:
+ smb_panic("cannot call strlen_m_ext() with a UTF16 src charset (must be DOS, UNIX, DISPLAY or UTF8)");
+ default:
+ break;
+ }
+#endif
+ if (!s) {
+ return 0;
+ }
+
+ while (*s && !(((uint8_t)*s) & 0x80)) {
+ s++;
+ count++;
+ }
+
+ if (!*s) {
+ return count;
+ }
+
+ while (*s) {
+ size_t c_size;
+ codepoint_t c = next_codepoint_handle_ext(ic, s, strnlen(s, 5),
+ src_charset, &c_size);
+ s += c_size;
+
+ switch (dst_charset) {
+ case CH_UTF16LE:
+ case CH_UTF16BE:
+ case CH_UTF16MUNGED:
+ if (c < 0x10000) {
+ /* Unicode char fits into 16 bits. */
+ count += 1;
+ } else {
+ /* Double-width unicode char - 32 bits. */
+ count += 2;
+ }
+ break;
+ case CH_UTF8:
+ /*
+ * this only checks ranges, and does not
+ * check for invalid codepoints
+ */
+ if (c < 0x80) {
+ count += 1;
+ } else if (c < 0x800) {
+ count += 2;
+ } else if (c < 0x10000) {
+ count += 3;
+ } else {
+ count += 4;
+ }
+ break;
+ default:
+ /*
+ * non-unicode encoding:
+ * assume that each codepoint fits into
+ * one unit in the destination encoding.
+ */
+ count += 1;
+ }
+ }
+
+ return count;
+}
+
+/**
+ * Calculate the number of units (8 or 16-bit, depending on the
+ * destination charset) that would be needed to convert the input
+ * string, which is expected to be in src_charset encoding, to the
+ * destination charset (which should be a unicode charset).
+ */
+_PUBLIC_ size_t strlen_m_ext(const char *s, charset_t src_charset, charset_t dst_charset)
+{
+ struct smb_iconv_handle *ic = get_iconv_handle();
+ return strlen_m_ext_handle(ic, s, src_charset, dst_charset);
+}
+
+_PUBLIC_ size_t strlen_m_ext_term(const char *s, const charset_t src_charset,
+ const charset_t dst_charset)
+{
+ if (!s) {
+ return 0;
+ }
+ return strlen_m_ext(s, src_charset, dst_charset) + 1;
+}
+
+_PUBLIC_ size_t strlen_m_ext_term_null(const char *s,
+ const charset_t src_charset,
+ const charset_t dst_charset)
+{
+ size_t len;
+ if (!s) {
+ return 0;
+ }
+ len = strlen_m_ext(s, src_charset, dst_charset);
+ if (len == 0) {
+ return 0;
+ }
+
+ return len+1;
+}
+
+/**
+ * Calculate the number of 16-bit units that would be needed to convert
+ * the input string, which is expected to be in CH_UNIX encoding, to UTF16.
+ *
+ * This will be the same as the number of bytes in a string for single
+ * byte strings, but will be different for multibyte.
+ */
+_PUBLIC_ size_t strlen_m(const char *s)
+{
+ return strlen_m_ext(s, CH_UNIX, CH_UTF16LE);
+}
+
+/**
+ Work out the number of multibyte chars in a string, including the NULL
+ terminator.
+**/
+_PUBLIC_ size_t strlen_m_term(const char *s)
+{
+ return strlen_m_ext_term(s, CH_UNIX, CH_UTF16LE);
+}
+
+/*
+ * Weird helper routine for the winreg pipe: If nothing is around, return 0,
+ * if a string is there, include the terminator.
+ */
+
+_PUBLIC_ size_t strlen_m_term_null(const char *s)
+{
+ return strlen_m_ext_term_null(s, CH_UNIX, CH_UTF16LE);
+}
+
+/**
+ Strchr and strrchr_m are a bit complex on general multi-byte strings.
+**/
+_PUBLIC_ char *strchr_m(const char *src, char c)
+{
+ const char *s;
+ struct smb_iconv_handle *ic = get_iconv_handle();
+ if (src == NULL) {
+ return NULL;
+ }
+ /* characters below 0x3F are guaranteed to not appear in
+ non-initial position in multi-byte charsets */
+ if ((c & 0xC0) == 0) {
+ return strchr(src, c);
+ }
+
+ /* this is quite a common operation, so we want it to be
+ fast. We optimise for the ascii case, knowing that all our
+ supported multi-byte character sets are ascii-compatible
+ (ie. they match for the first 128 chars) */
+
+ for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
+ if (*s == c)
+ return discard_const_p(char, s);
+ }
+
+ if (!*s)
+ return NULL;
+
+#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
+ /* With compose characters we must restart from the beginning. JRA. */
+ s = src;
+#endif
+
+ while (*s) {
+ size_t size;
+ codepoint_t c2 = next_codepoint_handle(ic, s, &size);
+ if (c2 == c) {
+ return discard_const_p(char, s);
+ }
+ s += size;
+ }
+
+ return NULL;
+}
+
+/**
+ * Multibyte-character version of strrchr
+ */
+_PUBLIC_ char *strrchr_m(const char *s, char c)
+{
+ struct smb_iconv_handle *ic;
+ char *ret = NULL;
+
+ if (s == NULL) {
+ return NULL;
+ }
+
+ /* characters below 0x3F are guaranteed to not appear in
+ non-initial position in multi-byte charsets */
+ if ((c & 0xC0) == 0) {
+ return strrchr(s, c);
+ }
+
+ /* this is quite a common operation, so we want it to be
+ fast. We optimise for the ascii case, knowing that all our
+ supported multi-byte character sets are ascii-compatible
+ (ie. they match for the first 128 chars). Also, in Samba
+ we only search for ascii characters in 'c' and that
+ in all mb character sets with a compound character
+ containing c, if 'c' is not a match at position
+ p, then p[-1] > 0x7f. JRA. */
+
+ {
+ size_t len = strlen(s);
+ const char *cp = s;
+ bool got_mb = false;
+
+ if (len == 0)
+ return NULL;
+ cp += (len - 1);
+ do {
+ if (c == *cp) {
+ /* Could be a match. Part of a multibyte ? */
+ if ((cp > s) &&
+ (((unsigned char)cp[-1]) & 0x80)) {
+ /* Yep - go slow :-( */
+ got_mb = true;
+ break;
+ }
+ /* No - we have a match ! */
+ return discard_const_p(char , cp);
+ }
+ } while (cp-- != s);
+ if (!got_mb)
+ return NULL;
+ }
+
+ ic = get_iconv_handle();
+
+ while (*s) {
+ size_t size;
+ codepoint_t c2 = next_codepoint_handle(ic, s, &size);
+ if (c2 == c) {
+ ret = discard_const_p(char, s);
+ }
+ s += size;
+ }
+
+ return ret;
+}
+
+/**
+ return True if any (multi-byte) character is lower case
+*/
+_PUBLIC_ bool strhaslower_handle(struct smb_iconv_handle *ic,
+ const char *string)
+{
+ while (*string) {
+ size_t c_size;
+ codepoint_t s;
+ codepoint_t t;
+
+ s = next_codepoint_handle(ic, string, &c_size);
+ string += c_size;
+
+ t = toupper_m(s);
+
+ if (s != t) {
+ return true; /* that means it has lower case chars */
+ }
+ }
+
+ return false;
+}
+
+_PUBLIC_ bool strhaslower(const char *string)
+{
+ struct smb_iconv_handle *ic = get_iconv_handle();
+ return strhaslower_handle(ic, string);
+}
+
+/**
+ return True if any (multi-byte) character is upper case
+*/
+_PUBLIC_ bool strhasupper_handle(struct smb_iconv_handle *ic,
+ const char *string)
+{
+ while (*string) {
+ size_t c_size;
+ codepoint_t s;
+ codepoint_t t;
+
+ s = next_codepoint_handle(ic, string, &c_size);
+ string += c_size;
+
+ t = tolower_m(s);
+
+ if (s != t) {
+ return true; /* that means it has upper case chars */
+ }
+ }
+
+ return false;
+}
+
+_PUBLIC_ bool strhasupper(const char *string)
+{
+ struct smb_iconv_handle *ic = get_iconv_handle();
+ return strhasupper_handle(ic, string);
+}
+
+/***********************************************************************
+ strstr_m - We convert via ucs2 for now.
+***********************************************************************/
+
+char *strstr_m(const char *src, const char *findstr)
+{
+ TALLOC_CTX *mem_ctx = NULL;
+ smb_ucs2_t *p;
+ smb_ucs2_t *src_w, *find_w;
+ const char *s;
+ char *s2;
+ char *retp = NULL;
+ size_t converted_size, findstr_len = 0;
+
+ /* for correctness */
+ if (!findstr[0]) {
+ return discard_const_p(char, src);
+ }
+
+ /* Samba does single character findstr calls a *lot*. */
+ if (findstr[1] == '\0')
+ return strchr_m(src, *findstr);
+
+ /* We optimise for the ascii case, knowing that all our
+ supported multi-byte character sets are ascii-compatible
+ (ie. they match for the first 128 chars) */
+
+ for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
+ if (*s == *findstr) {
+ if (!findstr_len)
+ findstr_len = strlen(findstr);
+
+ if (strncmp(s, findstr, findstr_len) == 0) {
+ return discard_const_p(char, s);
+ }
+ }
+ }
+
+ if (!*s)
+ return NULL;
+
+#if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
+ /* 'make check' fails unless we do this */
+
+ /* With compose characters we must restart from the beginning. JRA. */
+ s = src;
+#endif
+
+ /*
+ * Use get_iconv_handle() just as a non-NULL talloc ctx. In
+ * case we leak memory, this should then be more obvious in
+ * the talloc report.
+ */
+ mem_ctx = talloc_new(get_iconv_handle());
+ if (mem_ctx == NULL) {
+ return NULL;
+ }
+
+ if (!push_ucs2_talloc(mem_ctx, &src_w, src, &converted_size)) {
+ goto done;
+ }
+
+ if (!push_ucs2_talloc(mem_ctx, &find_w, findstr, &converted_size)) {
+ goto done;
+ }
+
+ p = strstr_w(src_w, find_w);
+
+ if (!p) {
+ goto done;
+ }
+
+ *p = 0;
+ if (!pull_ucs2_talloc(mem_ctx, &s2, src_w, &converted_size)) {
+ goto done;
+ }
+ retp = discard_const_p(char, (s+strlen(s2)));
+done:
+ TALLOC_FREE(mem_ctx);
+ return retp;
+}
diff --git a/lib/util/charset/util_unistr.c b/lib/util/charset/util_unistr.c
new file mode 100644
index 0000000..830b480
--- /dev/null
+++ b/lib/util/charset/util_unistr.c
@@ -0,0 +1,644 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) Simo Sorce 2001
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/locale.h"
+#include "charset.h"
+#include "lib/util/byteorder.h"
+#include "lib/util/fault.h"
+
+/**
+ String replace.
+ NOTE: oldc and newc must be 7 bit characters
+**/
+_PUBLIC_ void string_replace_m(char *s, char oldc, char newc)
+{
+ struct smb_iconv_handle *ic = get_iconv_handle();
+ while (s && *s) {
+ size_t size;
+ codepoint_t c = next_codepoint_handle(ic, s, &size);
+ if (c == oldc) {
+ *s = newc;
+ }
+ s += size;
+ }
+}
+
+/**
+ Convert a string to lower case, allocated with talloc
+**/
+_PUBLIC_ char *strlower_talloc_handle(struct smb_iconv_handle *iconv_handle,
+ TALLOC_CTX *ctx, const char *src)
+{
+ size_t size=0;
+ char *dest;
+
+ if(src == NULL) {
+ return NULL;
+ }
+
+ /* this takes advantage of the fact that upper/lower can't
+ change the length of a character by more than 1 byte */
+ dest = talloc_array(ctx, char, 2*(strlen(src))+1);
+ if (dest == NULL) {
+ return NULL;
+ }
+
+ while (*src) {
+ size_t c_size;
+ codepoint_t c = next_codepoint_handle(iconv_handle, src, &c_size);
+ src += c_size;
+
+ c = tolower_m(c);
+
+ c_size = push_codepoint_handle(iconv_handle, dest+size, c);
+ if (c_size == -1) {
+ talloc_free(dest);
+ return NULL;
+ }
+ size += c_size;
+ }
+
+ dest[size] = 0;
+
+ /* trim it so talloc_append_string() works */
+ dest = talloc_realloc(ctx, dest, char, size+1);
+
+ talloc_set_name_const(dest, dest);
+
+ return dest;
+}
+
+_PUBLIC_ char *strlower_talloc(TALLOC_CTX *ctx, const char *src)
+{
+ struct smb_iconv_handle *iconv_handle = get_iconv_handle();
+ return strlower_talloc_handle(iconv_handle, ctx, src);
+}
+
+/**
+ Convert a string to UPPER case, allocated with talloc
+ source length limited to n bytes, iconv handle supplied
+**/
+_PUBLIC_ char *strupper_talloc_n_handle(struct smb_iconv_handle *iconv_handle,
+ TALLOC_CTX *ctx, const char *src, size_t n)
+{
+ size_t size=0;
+ char *dest;
+
+ if (!src) {
+ return NULL;
+ }
+
+ /* this takes advantage of the fact that upper/lower can't
+ change the length of a character by more than 1 byte */
+ dest = talloc_array(ctx, char, 2*(n+1));
+ if (dest == NULL) {
+ return NULL;
+ }
+
+ while (n && *src) {
+ size_t c_size;
+ codepoint_t c = next_codepoint_handle_ext(iconv_handle, src, n,
+ CH_UNIX, &c_size);
+ src += c_size;
+ n -= c_size;
+
+ c = toupper_m(c);
+
+ c_size = push_codepoint_handle(iconv_handle, dest+size, c);
+ if (c_size == -1) {
+ talloc_free(dest);
+ return NULL;
+ }
+ size += c_size;
+ }
+
+ dest[size] = 0;
+
+ /* trim it so talloc_append_string() works */
+ dest = talloc_realloc(ctx, dest, char, size+1);
+
+ talloc_set_name_const(dest, dest);
+
+ return dest;
+}
+
+/**
+ Convert a string to UPPER case, allocated with talloc
+ source length limited to n bytes
+**/
+_PUBLIC_ char *strupper_talloc_n(TALLOC_CTX *ctx, const char *src, size_t n)
+{
+ struct smb_iconv_handle *iconv_handle = get_iconv_handle();
+ return strupper_talloc_n_handle(iconv_handle, ctx, src, n);
+}
+/**
+ Convert a string to UPPER case, allocated with talloc
+**/
+_PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src)
+{
+ return strupper_talloc_n(ctx, src, src?strlen(src):0);
+}
+
+/**
+ talloc_strdup() a unix string to upper case.
+**/
+_PUBLIC_ char *talloc_strdup_upper(TALLOC_CTX *ctx, const char *src)
+{
+ return strupper_talloc(ctx, src);
+}
+
+/**
+ Find the number of 'c' chars in a string
+**/
+_PUBLIC_ size_t count_chars_m(const char *s, char c)
+{
+ struct smb_iconv_handle *ic = get_iconv_handle();
+ size_t count = 0;
+
+ while (*s) {
+ size_t size;
+ codepoint_t c2 = next_codepoint_handle(ic, s, &size);
+ if (c2 == c) count++;
+ s += size;
+ }
+
+ return count;
+}
+
+size_t ucs2_align(const void *base_ptr, const void *p, int flags)
+{
+ if (flags & (STR_NOALIGN|STR_ASCII)) {
+ return 0;
+ }
+ return PTR_DIFF(p, base_ptr) & 1;
+}
+
+/**
+return the number of bytes occupied by a buffer in CH_UTF16 format
+**/
+size_t utf16_len(const void *buf)
+{
+ size_t len;
+
+ for (len = 0; PULL_LE_U16(buf,len); len += 2) ;
+
+ return len;
+}
+
+/**
+return the number of bytes occupied by a buffer in CH_UTF16 format
+the result includes the null termination
+**/
+size_t utf16_null_terminated_len(const void *buf)
+{
+ return utf16_len(buf) + 2;
+}
+
+/**
+return the number of bytes occupied by a buffer in CH_UTF16 format
+limited by 'n' bytes
+**/
+size_t utf16_len_n(const void *src, size_t n)
+{
+ size_t len;
+
+ for (len = 0; (len+2 <= n) && PULL_LE_U16(src, len); len += 2) ;
+
+ return len;
+}
+
+/**
+return the number of bytes occupied by a buffer in CH_UTF16 format
+the result includes the null termination
+limited by 'n' bytes
+**/
+size_t utf16_null_terminated_len_n(const void *src, size_t n)
+{
+ size_t len;
+
+ len = utf16_len_n(src, n);
+
+ if (len+2 <= n) {
+ len += 2;
+ }
+
+ return len;
+}
+
+unsigned char *talloc_utf16_strlendup(TALLOC_CTX *mem_ctx, const char *str, size_t len)
+{
+ unsigned char *new_str = NULL;
+
+ /* Check for overflow. */
+ if (len > SIZE_MAX - 2) {
+ return NULL;
+ }
+
+ /*
+ * Allocate the new string, including space for the
+ * UTF‐16 null terminator.
+ */
+ new_str = talloc_size(mem_ctx, len + 2);
+ if (new_str == NULL) {
+ return NULL;
+ }
+
+ memcpy(new_str, str, len);
+
+ /*
+ * Ensure that the UTF‐16 string is
+ * null‐terminated.
+ */
+ new_str[len] = '\0';
+ new_str[len + 1] = '\0';
+
+ return new_str;
+}
+
+unsigned char *talloc_utf16_strdup(TALLOC_CTX *mem_ctx, const char *str)
+{
+ if (str == NULL) {
+ return NULL;
+ }
+ return talloc_utf16_strlendup(mem_ctx, str, utf16_len(str));
+}
+
+unsigned char *talloc_utf16_strndup(TALLOC_CTX *mem_ctx, const char *str, size_t n)
+{
+ if (str == NULL) {
+ return NULL;
+ }
+ return talloc_utf16_strlendup(mem_ctx, str, utf16_len_n(str, n));
+}
+
+/**
+ * Determine the length and validity of a utf-8 string.
+ *
+ * @param input the string pointer
+ * @param maxlen maximum size of the string
+ * @param byte_len receives the length of the valid section
+ * @param char_len receives the number of unicode characters in the valid section
+ * @param utf16_len receives the number of bytes the string would need in UTF16 encoding.
+ *
+ * @return true if the input is valid up to maxlen, or a '\0' byte, otherwise false.
+ */
+bool utf8_check(const char *input, size_t maxlen,
+ size_t *byte_len,
+ size_t *char_len,
+ size_t *utf16_len)
+{
+ const uint8_t *s = (const uint8_t *)input;
+ size_t i;
+ size_t chars = 0;
+ size_t long_chars = 0;
+ uint32_t codepoint;
+ uint8_t a, b, c, d;
+ for (i = 0; i < maxlen; i++, chars++) {
+ if (s[i] == 0) {
+ break;
+ }
+ if (s[i] < 0x80) {
+ continue;
+ }
+ if ((s[i] & 0xe0) == 0xc0) {
+ /* 110xxxxx 10xxxxxx */
+ a = s[i];
+ if (maxlen - i < 2) {
+ goto error;
+ }
+ b = s[i + 1];
+ if ((b & 0xc0) != 0x80) {
+ goto error;
+ }
+ codepoint = (a & 31) << 6 | (b & 63);
+ if (codepoint < 0x80) {
+ goto error;
+ }
+ i++;
+ continue;
+ }
+ if ((s[i] & 0xf0) == 0xe0) {
+ /* 1110xxxx 10xxxxxx 10xxxxxx */
+ if (maxlen - i < 3) {
+ goto error;
+ }
+ a = s[i];
+ b = s[i + 1];
+ c = s[i + 2];
+ if ((b & 0xc0) != 0x80 || (c & 0xc0) != 0x80) {
+ goto error;
+ }
+ codepoint = (c & 63) | (b & 63) << 6 | (a & 15) << 12;
+
+ if (codepoint < 0x800) {
+ goto error;
+ }
+ if (codepoint >= 0xd800 && codepoint <= 0xdfff) {
+ /*
+ * This is an invalid codepoint, per
+ * RFC3629, as it encodes part of a
+ * UTF-16 surrogate pair for a
+ * character over U+10000, which ought
+ * to have been encoded as a four byte
+ * utf-8 sequence.
+ */
+ goto error;
+ }
+ i += 2;
+ continue;
+ }
+
+ if ((s[i] & 0xf8) == 0xf0) {
+ /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+ if (maxlen - i < 4) {
+ goto error;
+ }
+ a = s[i];
+ b = s[i + 1];
+ c = s[i + 2];
+ d = s[i + 3];
+
+ if ((b & 0xc0) != 0x80 ||
+ (c & 0xc0) != 0x80 ||
+ (d & 0xc0) != 0x80) {
+ goto error;
+ }
+ codepoint = (d & 63) | (c & 63) << 6 | (b & 63) << 12 | (a & 7) << 18;
+
+ if (codepoint < 0x10000 || codepoint > 0x10ffff) {
+ goto error;
+ }
+ /* this one will need two UTF16 characters */
+ long_chars++;
+ i += 3;
+ continue;
+ }
+ /*
+ * If it wasn't handled yet, it's wrong.
+ */
+ goto error;
+ }
+ *byte_len = i;
+ *char_len = chars;
+ *utf16_len = chars + long_chars;
+ return true;
+
+error:
+ *byte_len = i;
+ *char_len = chars;
+ *utf16_len = chars + long_chars;
+ return false;
+}
+
+
+/**
+ * Copy a string from a char* unix src to a dos codepage string destination.
+ *
+ * @converted_size the number of bytes occupied by the string in the destination.
+ * @return bool true if success.
+ *
+ * @param flags can include
+ * <dl>
+ * <dt>STR_TERMINATE</dt> <dd>means include the null termination</dd>
+ * <dt>STR_UPPER</dt> <dd>means uppercase in the destination</dd>
+ * </dl>
+ *
+ * @param dest_len the maximum length in bytes allowed in the
+ * destination. If @p dest_len is -1 then no maximum is used.
+ **/
+static bool push_ascii_string(void *dest, const char *src, size_t dest_len, int flags, size_t *converted_size)
+{
+ size_t src_len;
+ bool ret;
+
+ if (flags & STR_UPPER) {
+ char *tmpbuf = strupper_talloc(NULL, src);
+ if (tmpbuf == NULL) {
+ return false;
+ }
+ ret = push_ascii_string(dest, tmpbuf, dest_len, flags & ~STR_UPPER, converted_size);
+ talloc_free(tmpbuf);
+ return ret;
+ }
+
+ src_len = strlen(src);
+
+ if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
+ src_len++;
+
+ return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len, converted_size);
+}
+
+/**
+ * Copy a string from a dos codepage source to a unix char* destination.
+ *
+ * The resulting string in "dest" is always null terminated.
+ *
+ * @param flags can have:
+ * <dl>
+ * <dt>STR_TERMINATE</dt>
+ * <dd>STR_TERMINATE means the string in @p src
+ * is null terminated, and src_len is ignored.</dd>
+ * </dl>
+ *
+ * @param src_len is the length of the source area in bytes.
+ * @returns the number of bytes occupied by the string in @p src.
+ **/
+static ssize_t pull_ascii_string(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
+{
+ size_t size = 0;
+
+ if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) {
+ if (src_len == (size_t)-1) {
+ src_len = strlen((const char *)src) + 1;
+ } else {
+ size_t len = strnlen((const char *)src, src_len);
+ if (len < src_len)
+ len++;
+ src_len = len;
+ }
+ }
+
+ /* We're ignoring the return here.. */
+ (void)convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len, &size);
+
+ if (dest_len)
+ dest[MIN(size, dest_len-1)] = 0;
+
+ return src_len;
+}
+
+/**
+ * Copy a string from a char* src to a unicode destination.
+ *
+ * @returns the number of bytes occupied by the string in the destination.
+ *
+ * @param flags can have:
+ *
+ * <dl>
+ * <dt>STR_TERMINATE <dd>means include the null termination.
+ * <dt>STR_UPPER <dd>means uppercase in the destination.
+ * <dt>STR_NOALIGN <dd>means don't do alignment.
+ * </dl>
+ *
+ * @param dest_len is the maximum length allowed in the
+ * destination. If dest_len is -1 then no maximum is used.
+ **/
+static ssize_t push_ucs2(void *dest, const char *src, size_t dest_len, int flags)
+{
+ size_t len=0;
+ size_t src_len = strlen(src);
+ size_t size = 0;
+ bool ret;
+
+ if (flags & STR_UPPER) {
+ char *tmpbuf = strupper_talloc(NULL, src);
+ ssize_t retval;
+ if (tmpbuf == NULL) {
+ return -1;
+ }
+ retval = push_ucs2(dest, tmpbuf, dest_len, flags & ~STR_UPPER);
+ talloc_free(tmpbuf);
+ return retval;
+ }
+
+ if (flags & STR_TERMINATE)
+ src_len++;
+
+ if (ucs2_align(NULL, dest, flags)) {
+ *(char *)dest = 0;
+ dest = (void *)((char *)dest + 1);
+ if (dest_len) dest_len--;
+ len++;
+ }
+
+ /* ucs2 is always a multiple of 2 bytes */
+ dest_len &= ~1;
+
+ ret = convert_string(CH_UNIX, CH_UTF16, src, src_len, dest, dest_len, &size);
+ if (ret == false) {
+ return 0;
+ }
+
+ len += size;
+
+ return (ssize_t)len;
+}
+
+
+/**
+ Copy a string from a ucs2 source to a unix char* destination.
+ Flags can have:
+ STR_TERMINATE means the string in src is null terminated.
+ STR_NOALIGN means don't try to align.
+ if STR_TERMINATE is set then src_len is ignored if it is -1.
+ src_len is the length of the source area in bytes
+ Return the number of bytes occupied by the string in src.
+ The resulting string in "dest" is always null terminated.
+**/
+
+static size_t pull_ucs2(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
+{
+ size_t size = 0;
+
+ if (ucs2_align(NULL, src, flags)) {
+ src = (const void *)((const char *)src + 1);
+ if (src_len > 0)
+ src_len--;
+ }
+
+ if (flags & STR_TERMINATE) {
+ if (src_len == (size_t)-1) {
+ src_len = utf16_null_terminated_len(src);
+ } else {
+ src_len = utf16_null_terminated_len_n(src, src_len);
+ }
+ }
+
+ /* ucs2 is always a multiple of 2 bytes */
+ if (src_len != (size_t)-1)
+ src_len &= ~1;
+
+ /* We're ignoring the return here.. */
+ (void)convert_string(CH_UTF16, CH_UNIX, src, src_len, dest, dest_len, &size);
+ if (dest_len)
+ dest[MIN(size, dest_len-1)] = 0;
+
+ return src_len;
+}
+
+/**
+ Copy a string from a char* src to a unicode or ascii
+ dos codepage destination choosing unicode or ascii based on the
+ flags in the SMB buffer starting at base_ptr.
+ Return the number of bytes occupied by the string in the destination.
+ flags can have:
+ STR_TERMINATE means include the null termination.
+ STR_UPPER means uppercase in the destination.
+ STR_ASCII use ascii even with unicode packet.
+ STR_NOALIGN means don't do alignment.
+ dest_len is the maximum length allowed in the destination. If dest_len
+ is -1 then no maximum is used.
+**/
+
+_PUBLIC_ ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
+{
+ if (flags & STR_ASCII) {
+ size_t size = 0;
+ if (push_ascii_string(dest, src, dest_len, flags, &size)) {
+ return (ssize_t)size;
+ } else {
+ return (ssize_t)-1;
+ }
+ } else if (flags & STR_UNICODE) {
+ return push_ucs2(dest, src, dest_len, flags);
+ } else {
+ smb_panic("push_string requires either STR_ASCII or STR_UNICODE flag to be set");
+ return -1;
+ }
+}
+
+
+/**
+ Copy a string from a unicode or ascii source (depending on
+ the packet flags) to a char* destination.
+ Flags can have:
+ STR_TERMINATE means the string in src is null terminated.
+ STR_UNICODE means to force as unicode.
+ STR_ASCII use ascii even with unicode packet.
+ STR_NOALIGN means don't do alignment.
+ if STR_TERMINATE is set then src_len is ignored is it is -1
+ src_len is the length of the source area in bytes.
+ Return the number of bytes occupied by the string in src.
+ The resulting string in "dest" is always null terminated.
+**/
+
+_PUBLIC_ ssize_t pull_string(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
+{
+ if (flags & STR_ASCII) {
+ return pull_ascii_string(dest, src, dest_len, src_len, flags);
+ } else if (flags & STR_UNICODE) {
+ return pull_ucs2(dest, src, dest_len, src_len, flags);
+ } else {
+ smb_panic("pull_string requires either STR_ASCII or STR_UNICODE flag to be set");
+ return -1;
+ }
+}
diff --git a/lib/util/charset/util_unistr_w.c b/lib/util/charset/util_unistr_w.c
new file mode 100644
index 0000000..88d5531
--- /dev/null
+++ b/lib/util/charset/util_unistr_w.c
@@ -0,0 +1,255 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Jeremy Allison 2005
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "charset.h"
+#include "lib/util/byteorder.h"
+#include "lib/util/debug.h"
+#include "lib/util/fault.h"
+
+/* Copy into a smb_ucs2_t from a possibly unaligned buffer. Return the copied smb_ucs2_t */
+#define COPY_UCS2_CHAR(dest,src) (((unsigned char *)(dest))[0] = ((const unsigned char *)(src))[0],\
+ ((unsigned char *)(dest))[1] = ((const unsigned char *)(src))[1], (dest))
+
+
+/* return an ascii version of a ucs2 character */
+#define UCS2_TO_CHAR(c) (((c) >> UCS2_SHIFT) & 0xff)
+
+static int strncmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b, size_t len);
+
+/*******************************************************************
+ Count the number of two-byte pairs in a UTF16 string.
+********************************************************************/
+
+size_t strlen_w(const smb_ucs2_t *src)
+{
+ size_t len;
+ smb_ucs2_t c;
+
+ for(len = 0; *(COPY_UCS2_CHAR(&c,src)); src++, len++) {
+ ;
+ }
+
+ return len;
+}
+
+/*******************************************************************
+ Count up to max number of characters in a smb_ucs2_t string.
+********************************************************************/
+
+size_t strnlen_w(const smb_ucs2_t *src, size_t max)
+{
+ size_t len;
+ smb_ucs2_t c;
+
+ for(len = 0; (len < max) && *(COPY_UCS2_CHAR(&c,src)); src++, len++) {
+ ;
+ }
+
+ return len;
+}
+
+/*******************************************************************
+ Wide strchr().
+********************************************************************/
+
+smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
+{
+ smb_ucs2_t cp;
+ while (*(COPY_UCS2_CHAR(&cp,s))) {
+ if (c == cp) {
+ return discard_const_p(smb_ucs2_t, s);
+ }
+ s++;
+ }
+ if (c == cp) {
+ return discard_const_p(smb_ucs2_t, s);
+ }
+
+ return NULL;
+}
+
+smb_ucs2_t *strchr_wa(const smb_ucs2_t *s, char c)
+{
+ return strchr_w(s, UCS2_CHAR(c));
+}
+
+/*******************************************************************
+ Wide strrchr().
+********************************************************************/
+
+smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
+{
+ smb_ucs2_t cp;
+ const smb_ucs2_t *p = s;
+ int len = strlen_w(s);
+
+ if (len == 0) {
+ return NULL;
+ }
+ p += (len - 1);
+ do {
+ if (c == *(COPY_UCS2_CHAR(&cp,p))) {
+ return discard_const_p(smb_ucs2_t, p);
+ }
+ } while (p-- != s);
+ return NULL;
+}
+
+/*******************************************************************
+ Wide version of strrchr that returns after doing strrchr 'n' times.
+********************************************************************/
+
+smb_ucs2_t *strnrchr_w(const smb_ucs2_t *s, smb_ucs2_t c, unsigned int n)
+{
+ smb_ucs2_t cp;
+ const smb_ucs2_t *p = s;
+ int len = strlen_w(s);
+
+ if (len == 0 || !n) {
+ return NULL;
+ }
+ p += (len - 1);
+ do {
+ if (c == *(COPY_UCS2_CHAR(&cp,p))) {
+ n--;
+ }
+
+ if (!n) {
+ return discard_const_p(smb_ucs2_t, p);
+ }
+ } while (p-- != s);
+ return NULL;
+}
+
+/*******************************************************************
+ Wide strstr().
+********************************************************************/
+
+smb_ucs2_t *strstr_w(const smb_ucs2_t *s, const smb_ucs2_t *ins)
+{
+ const smb_ucs2_t *r;
+ size_t inslen;
+
+ if (!s || !*s || !ins || !*ins) {
+ return NULL;
+ }
+
+ inslen = strlen_w(ins);
+ r = s;
+
+ while ((r = strchr_w(r, *ins))) {
+ if (strncmp_w(r, ins, inslen) == 0) {
+ return discard_const_p(smb_ucs2_t, r);
+ }
+ r++;
+ }
+
+ return NULL;
+}
+
+/*******************************************************************
+ Convert a string to lower case.
+ return True if any char is converted
+
+ This is unsafe for any string involving a UTF16 character
+********************************************************************/
+
+bool strlower_w(smb_ucs2_t *s)
+{
+ smb_ucs2_t cp;
+ bool ret = false;
+
+ while (*(COPY_UCS2_CHAR(&cp,s))) {
+ smb_ucs2_t v = tolower_m(cp);
+ if (v != cp) {
+ (void)COPY_UCS2_CHAR(s,&v);
+ ret = true;
+ }
+ s++;
+ }
+ return ret;
+}
+
+/*******************************************************************
+ Convert a string to upper case.
+ return True if any char is converted
+
+ This is unsafe for any string involving a UTF16 character
+********************************************************************/
+
+bool strupper_w(smb_ucs2_t *s)
+{
+ smb_ucs2_t cp;
+ bool ret = false;
+ while (*(COPY_UCS2_CHAR(&cp,s))) {
+ smb_ucs2_t v = toupper_m(cp);
+ if (v != cp) {
+ (void)COPY_UCS2_CHAR(s,&v);
+ ret = true;
+ }
+ s++;
+ }
+ return ret;
+}
+
+static int strncmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b, size_t len)
+{
+ smb_ucs2_t cpa, cpb;
+ size_t n = 0;
+
+ while ((n < len) && (*(COPY_UCS2_CHAR(&cpb,b))) && (*(COPY_UCS2_CHAR(&cpa,a)) == cpb)) {
+ a++;
+ b++;
+ n++;
+ }
+ return (len - n)?(*(COPY_UCS2_CHAR(&cpa,a)) - *(COPY_UCS2_CHAR(&cpb,b))):0;
+}
+
+/*
+ The *_wa() functions take a combination of 7 bit ascii
+ and wide characters They are used so that you can use string
+ functions combining C string constants with ucs2 strings
+
+ The char* arguments must NOT be multibyte - to be completely sure
+ of this only pass string constants */
+
+int strcmp_wa(const smb_ucs2_t *a, const char *b)
+{
+ smb_ucs2_t cp = 0;
+
+ while (*b && *(COPY_UCS2_CHAR(&cp,a)) == UCS2_CHAR(*b)) {
+ a++;
+ b++;
+ }
+ return (*(COPY_UCS2_CHAR(&cp,a)) - UCS2_CHAR(*b));
+}
+
+smb_ucs2_t toupper_w(smb_ucs2_t v)
+{
+ smb_ucs2_t ret;
+ /* LE to native. */
+ codepoint_t cp = SVAL(&v,0);
+ cp = toupper_m(cp);
+ /* native to LE. */
+ SSVAL(&ret,0,cp);
+ return ret;
+}
diff --git a/lib/util/charset/weird.c b/lib/util/charset/weird.c
new file mode 100644
index 0000000..9752e01
--- /dev/null
+++ b/lib/util/charset/weird.c
@@ -0,0 +1,142 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba module with developer tools
+ Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Jelmer Vernooij 2002
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "charset_proto.h"
+
+#ifdef DEVELOPER
+
+static struct {
+ char from;
+ const char *to;
+ int len;
+} weird_table[] = {
+ {
+ .from = 'q',
+ .to = "^q^",
+ .len = 3,
+ },
+ {
+ .from = 'Q',
+ .to = "^Q^",
+ .len = 3,
+ },
+ {
+ .len = 0,
+ }
+};
+
+size_t weird_pull(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ while (*inbytesleft >= 1 && *outbytesleft >= 2) {
+ int i;
+ int done = 0;
+ for (i=0;weird_table[i].from;i++) {
+ if (strncmp((*inbuf),
+ weird_table[i].to,
+ weird_table[i].len) == 0) {
+ if (*inbytesleft < weird_table[i].len) {
+ abort();
+ }
+
+ (*outbuf)[0] = weird_table[i].from;
+ (*outbuf)[1] = 0;
+ (*inbytesleft) -= weird_table[i].len;
+ (*outbytesleft) -= 2;
+ (*inbuf) += weird_table[i].len;
+ (*outbuf) += 2;
+ done = 1;
+ break;
+ }
+ }
+ if (done) continue;
+ (*outbuf)[0] = (*inbuf)[0];
+ (*outbuf)[1] = 0;
+ (*inbytesleft) -= 1;
+ (*outbytesleft) -= 2;
+ (*inbuf) += 1;
+ (*outbuf) += 2;
+ }
+
+ if (*inbytesleft > 0) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return 0;
+}
+
+size_t weird_push(void *cd, const char **inbuf, size_t *inbytesleft,
+ char **outbuf, size_t *outbytesleft)
+{
+ int ir_count=0;
+
+ while (*inbytesleft >= 2 && *outbytesleft >= 1) {
+ int i;
+ int done=0;
+ for (i=0;weird_table[i].from;i++) {
+ if ((*inbuf)[0] == weird_table[i].from &&
+ (*inbuf)[1] == 0) {
+ if (*outbytesleft < weird_table[i].len) {
+ abort();
+ }
+ memcpy(*outbuf,
+ weird_table[i].to,
+ weird_table[i].len);
+ (*inbytesleft) -= 2;
+ (*outbytesleft) -= weird_table[i].len;
+ (*inbuf) += 2;
+ (*outbuf) += weird_table[i].len;
+ done = 1;
+ break;
+ }
+ }
+ if (done) continue;
+
+ (*outbuf)[0] = (*inbuf)[0];
+ if ((*inbuf)[1]) ir_count++;
+ (*inbytesleft) -= 2;
+ (*outbytesleft) -= 1;
+ (*inbuf) += 2;
+ (*outbuf) += 1;
+ }
+
+ if (*inbytesleft == 1) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (*inbytesleft > 1) {
+ errno = E2BIG;
+ return -1;
+ }
+
+ return ir_count;
+}
+
+#else
+void charset_weird_dummy(void);
+void charset_weird_dummy(void)
+{
+ return;
+}
+
+#endif
diff --git a/lib/util/charset/wscript_build b/lib/util/charset/wscript_build
new file mode 100644
index 0000000..c69a171
--- /dev/null
+++ b/lib/util/charset/wscript_build
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+bld.SAMBA_SUBSYSTEM('ICONV_WRAPPER',
+ source='''
+ iconv.c
+ weird.c
+ charset_macosxfs.c
+ ''',
+ public_deps='iconv replace talloc ' + bld.env['icu-libs'])
+
+bld.SAMBA_SUBSYSTEM('charset',
+ public_headers='charset.h',
+ source='''
+ codepoints.c
+ convert_string.c
+ util_str.c
+ util_unistr_w.c
+ pull_push.c
+ util_unistr.c
+ ''',
+ deps='DYNCONFIG ICONV_WRAPPER smb-panic samba-debug',
+ public_deps='talloc')
diff --git a/lib/util/charset/wscript_configure b/lib/util/charset/wscript_configure
new file mode 100644
index 0000000..9c27fc6
--- /dev/null
+++ b/lib/util/charset/wscript_configure
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+# rather strangely, we need to look for libiconv before checking libc
+# as the external libiconv can use a macro to override iconv_open to libiconv_open
+# and then we may find the wrong iconv.h later due to other packages looking
+# in /usr/local
+# We check for the lib iconv when building a shared lib has some compiler/linker
+# managed to link when specifying -liconv a executable even if there is no
+# libiconv.so or libiconv.a
+
+conf.CHECK_LIB(libs="iconv", shlib=True)
+
+#HP-UX can use libiconv as an add-on package, which has #define iconv_open libiconv_open
+if (conf.CHECK_FUNCS_IN('iconv_open', 'iconv', checklibc=False, headers='iconv.h') or
+ conf.CHECK_FUNCS_IN('libiconv_open', 'iconv', checklibc=False, headers='iconv.h') or
+ conf.CHECK_FUNCS('iconv_open', headers='iconv.h')):
+
+ conf.DEFINE('HAVE_NATIVE_ICONV', 1)
+
+conf.CHECK_CODE('''
+ uint8_t inbuf[2] = { 0x30, 0xdf };
+ uint8_t outbuf[4] = { 0 };
+ char *ptr_in = (char *)inbuf;
+ char *ptr_out = (char *)outbuf;
+ size_t size_in = sizeof(inbuf);
+ size_t size_out = sizeof(outbuf);
+ size_t ret;
+ iconv_t cd;
+ cd = iconv_open("UTF-8", "UTF-16LE");
+ if (cd == 0 || cd == (iconv_t)-1) return -1;
+ ret = iconv(cd, &ptr_in, &size_in, &ptr_out, &size_out);
+ if (ret != (size_t)-1 || errno != EILSEQ) return -1;
+ ''',
+ define='HAVE_ICONV_ERRNO_ILLEGAL_MULTIBYTE',
+ execute=True,
+ msg='Checking errno of iconv for illegal multibyte sequence',
+ lib='iconv',
+ headers='errno.h iconv.h')
+
+if conf.CHECK_CFG(package='icu-i18n',
+ args='--cflags --libs',
+ msg='Checking for icu-i18n',
+ uselib_store='ICU_I18N'):
+ for lib in conf.env['LIB_ICU_I18N']:
+ conf.CHECK_LIB(lib, shlib=True, mandatory=True)
+ conf.env['icu-libs'] = ' '.join(conf.env['LIB_ICU_I18N'])
+ if not conf.CHECK_HEADERS('unicode/ustring.h'):
+ conf.fatal('Found libicu, but unicode/ustring.h is missing')
+ conf.DEFINE('HAVE_UTF8_NORMALISATION', 1)
+else:
+ conf.env['icu-libs'] = ''
diff --git a/lib/util/charset_compat.h b/lib/util/charset_compat.h
new file mode 100644
index 0000000..cb3b625
--- /dev/null
+++ b/lib/util/charset_compat.h
@@ -0,0 +1,9 @@
+#ifndef _SAMBA_CHARSET_COMPAT_H_
+#define _SAMBA_CHARSET_COMPAT_H_
+
+#include <string.h>
+
+#define strchr_m(h, n) strchr(h, n)
+#define strstr_m(h, n) strstr(h, n)
+
+#endif /* _SAMBA_CHARSET_COMPAT_H_ */
diff --git a/lib/util/close_low_fd.c b/lib/util/close_low_fd.c
new file mode 100644
index 0000000..84a6906
--- /dev/null
+++ b/lib/util/close_low_fd.c
@@ -0,0 +1,75 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba utility functions
+ * Copyright (C) Volker Lendecke 2014
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "close_low_fd.h"
+
+#ifdef HAVE_VALGRIND_VALGRIND_H
+#include <valgrind/valgrind.h>
+#elif defined(HAVE_VALGRIND_H)
+#include <valgrind.h>
+#else
+#define RUNNING_ON_VALGRIND 0
+#endif
+
+_PUBLIC_ int close_low_fd(int fd)
+{
+ int ret, dev_null;
+
+ if (RUNNING_ON_VALGRIND) {
+ return 0;
+ }
+
+ dev_null = open("/dev/null", O_RDWR, 0);
+
+ if ((dev_null == -1) && (errno == ENFILE)) {
+ /*
+ * Try to free up an fd
+ */
+ ret = close(fd);
+ if (ret != 0) {
+ return errno;
+ }
+ }
+
+ dev_null = open("/dev/null", O_RDWR, 0);
+ if (dev_null == -1) {
+ dev_null = open("/dev/null", O_WRONLY, 0);
+ }
+ if (dev_null == -1) {
+ return errno;
+ }
+
+ if (dev_null == fd) {
+ /*
+ * This can happen in the ENFILE case above
+ */
+ return 0;
+ }
+
+ ret = dup2(dev_null, fd);
+ if (ret == -1) {
+ int err = errno;
+ close(dev_null);
+ return err;
+ }
+ close(dev_null);
+ return 0;
+}
diff --git a/lib/util/close_low_fd.h b/lib/util/close_low_fd.h
new file mode 100644
index 0000000..954d1d2
--- /dev/null
+++ b/lib/util/close_low_fd.h
@@ -0,0 +1,28 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba utility functions
+ * Copyright (C) Volker Lendecke 2014
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CLOSE_LOW_FD_H
+#define _CLOSE_LOW_FD_H
+
+/*
+ * Redirect "fd" to /dev/null
+ */
+int close_low_fd(int fd);
+
+#endif
diff --git a/lib/util/data_blob.c b/lib/util/data_blob.c
new file mode 100644
index 0000000..69a340c
--- /dev/null
+++ b/lib/util/data_blob.c
@@ -0,0 +1,298 @@
+/*
+ Unix SMB/CIFS implementation.
+ Easy management of byte-length data
+ Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Andrew Bartlett 2001
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "attr.h"
+#include "data_blob.h"
+#include "lib/util/samba_util.h"
+
+const DATA_BLOB data_blob_null = { NULL, 0 };
+
+/**
+ * @file
+ * @brief Manipulation of arbitrary data blobs
+ **/
+
+/**
+ construct a data blob, must be freed with data_blob_free()
+ you can pass NULL for p and get a blank data blob
+**/
+_PUBLIC_ DATA_BLOB data_blob_named(const void *p, size_t length, const char *name)
+{
+ return data_blob_talloc_named(NULL, p, length, name);
+}
+
+/**
+ construct a data blob, using supplied TALLOC_CTX
+**/
+_PUBLIC_ DATA_BLOB data_blob_talloc_named(TALLOC_CTX *mem_ctx, const void *p, size_t length, const char *name)
+{
+ DATA_BLOB ret;
+
+ if (p == NULL && length == 0) {
+ ZERO_STRUCT(ret);
+ return ret;
+ }
+
+ if (p) {
+ ret.data = (uint8_t *)talloc_memdup(mem_ctx, p, length);
+ } else {
+ ret.data = talloc_array(mem_ctx, uint8_t, length);
+ }
+ if (ret.data == NULL) {
+ ret.length = 0;
+ return ret;
+ }
+ talloc_set_name_const(ret.data, name);
+ ret.length = length;
+ return ret;
+}
+
+/**
+ construct a zero data blob, using supplied TALLOC_CTX.
+ use this sparingly as it initialises data - better to initialise
+ yourself if you want specific data in the blob
+**/
+_PUBLIC_ DATA_BLOB data_blob_talloc_zero(TALLOC_CTX *mem_ctx, size_t length)
+{
+ DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, length);
+ data_blob_clear(&blob);
+ return blob;
+}
+
+/**
+free a data blob
+**/
+_PUBLIC_ void data_blob_free(DATA_BLOB *d)
+{
+ if (d) {
+ TALLOC_FREE(d->data);
+ d->length = 0;
+ }
+}
+
+/**
+clear a DATA_BLOB's contents
+**/
+_PUBLIC_ void data_blob_clear(DATA_BLOB *d)
+{
+ if (d->data) {
+ memset_s(d->data, d->length, 0, d->length);
+ }
+}
+
+/**
+free a data blob and clear its contents
+**/
+_PUBLIC_ void data_blob_clear_free(DATA_BLOB *d)
+{
+ data_blob_clear(d);
+ data_blob_free(d);
+}
+
+
+/**
+check if two data blobs are equal
+**/
+_PUBLIC_ int data_blob_cmp(const DATA_BLOB *d1, const DATA_BLOB *d2)
+{
+ int ret;
+ if (d1->data == NULL && d2->data != NULL) {
+ return -1;
+ }
+ if (d1->data != NULL && d2->data == NULL) {
+ return 1;
+ }
+ if (d1->data == d2->data) {
+ return d1->length - d2->length;
+ }
+ ret = memcmp(d1->data, d2->data, MIN(d1->length, d2->length));
+ if (ret == 0) {
+ /* Note this ordering is used in conditional aces */
+ return d1->length - d2->length;
+ }
+ return ret;
+}
+
+/**
+check if two data blobs are equal, where the time taken should not depend on the
+contents of either blob.
+**/
+_PUBLIC_ bool data_blob_equal_const_time(const DATA_BLOB *d1, const DATA_BLOB *d2)
+{
+ bool ret;
+ if (d1->data == NULL && d2->data != NULL) {
+ return false;
+ }
+ if (d1->data != NULL && d2->data == NULL) {
+ return false;
+ }
+ if (d1->length != d2->length) {
+ return false;
+ }
+ if (d1->data == d2->data) {
+ return true;
+ }
+ ret = mem_equal_const_time(d1->data, d2->data, d1->length);
+ return ret;
+}
+
+/**
+print the data_blob as hex string
+**/
+_PUBLIC_ char *data_blob_hex_string_lower(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob)
+{
+ size_t i;
+ char *hex_string;
+
+ hex_string = talloc_array(mem_ctx, char, (blob->length*2)+1);
+ if (!hex_string) {
+ return NULL;
+ }
+
+ /* this must be lowercase or w2k8 cannot join a samba domain,
+ as this routine is used to encode extended DNs and windows
+ only accepts lowercase hexadecimal numbers */
+ for (i = 0; i < blob->length; i++)
+ slprintf(&hex_string[i*2], 3, "%02x", blob->data[i]);
+
+ hex_string[(blob->length*2)] = '\0';
+ return hex_string;
+}
+
+_PUBLIC_ char *data_blob_hex_string_upper(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob)
+{
+ size_t i;
+ char *hex_string;
+
+ hex_string = talloc_array(mem_ctx, char, (blob->length*2)+1);
+ if (!hex_string) {
+ return NULL;
+ }
+
+ for (i = 0; i < blob->length; i++)
+ slprintf(&hex_string[i*2], 3, "%02X", blob->data[i]);
+
+ hex_string[(blob->length*2)] = '\0';
+ return hex_string;
+}
+
+/**
+ useful for constructing data blobs in test suites, while
+ avoiding const warnings
+**/
+_PUBLIC_ DATA_BLOB data_blob_string_const(const char *str)
+{
+ DATA_BLOB blob;
+ blob.data = discard_const_p(uint8_t, str);
+ blob.length = str ? strlen(str) : 0;
+ return blob;
+}
+
+/**
+ useful for constructing data blobs in test suites, while
+ avoiding const warnings
+**/
+_PUBLIC_ DATA_BLOB data_blob_string_const_null(const char *str)
+{
+ DATA_BLOB blob;
+ blob.data = discard_const_p(uint8_t, str);
+ blob.length = str ? strlen(str)+1 : 0;
+ return blob;
+}
+
+/**
+ * Create a new data blob from const data
+ */
+
+_PUBLIC_ DATA_BLOB data_blob_const(const void *p, size_t length)
+{
+ DATA_BLOB blob;
+ blob.data = discard_const_p(uint8_t, p);
+ blob.length = length;
+ return blob;
+}
+
+
+/**
+ realloc a data_blob
+**/
+_PUBLIC_ bool data_blob_realloc(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, size_t length)
+{
+ uint8_t *tmp = talloc_realloc(mem_ctx, blob->data, uint8_t, length);
+ if (tmp == NULL) {
+ return false;
+ }
+ blob->data = tmp;
+ blob->length = length;
+ return true;
+}
+
+
+/**
+ append some data to a data blob
+**/
+_PUBLIC_ bool data_blob_append(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
+ const void *p, size_t length)
+{
+ size_t old_len = blob->length;
+ size_t new_len = old_len + length;
+
+ if (length == 0) {
+ return true;
+ }
+
+ if (new_len < length || new_len < old_len) {
+ return false;
+ }
+
+ if ((const uint8_t *)p + length < (const uint8_t *)p) {
+ return false;
+ }
+
+ if (!data_blob_realloc(mem_ctx, blob, new_len)) {
+ return false;
+ }
+
+ memcpy(blob->data + old_len, p, length);
+ return true;
+}
+
+/**
+ pad the length of a data blob to a multiple of
+ 'pad'. 'pad' must be a power of two.
+**/
+_PUBLIC_ bool data_blob_pad(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
+ size_t pad)
+{
+ size_t old_len = blob->length;
+ size_t new_len = (old_len + pad - 1) & ~(pad - 1);
+
+ if (new_len < old_len) {
+ return false;
+ }
+
+ if (!data_blob_realloc(mem_ctx, blob, new_len)) {
+ return false;
+ }
+
+ memset(blob->data + old_len, 0, new_len - old_len);
+ return true;
+}
diff --git a/lib/util/data_blob.h b/lib/util/data_blob.h
new file mode 100644
index 0000000..6577630
--- /dev/null
+++ b/lib/util/data_blob.h
@@ -0,0 +1,144 @@
+/*
+ Unix SMB/CIFS implementation.
+ DATA BLOB
+
+ Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Andrew Bartlett 2001
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/* This is a public header file that is installed as part of Samba.
+ * If you remove any functions or change their signature, update
+ * the so version number. */
+
+#ifndef _SAMBA_DATABLOB_H_
+#define _SAMBA_DATABLOB_H_
+
+#ifndef _PUBLIC_
+#define _PUBLIC_
+#endif
+
+#include <talloc.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+/* used to hold an arbitrary blob of data */
+typedef struct datablob {
+ uint8_t *data;
+ size_t length;
+} DATA_BLOB;
+
+/* by making struct ldb_val and DATA_BLOB the same, we can simplify
+ a fair bit of code */
+#define ldb_val datablob
+
+#define data_blob(ptr, size) data_blob_named(ptr, size, "DATA_BLOB: " __location__)
+#define data_blob_talloc(ctx, ptr, size) data_blob_talloc_named(ctx, ptr, size, "DATA_BLOB: " __location__)
+#define data_blob_dup_talloc(ctx, blob) data_blob_talloc_named(ctx, (blob).data, (blob).length, "DATA_BLOB: " __location__)
+
+/**
+ construct a data blob, must be freed with data_blob_free()
+ you can pass NULL for p and get a blank data blob
+**/
+_PUBLIC_ DATA_BLOB data_blob_named(const void *p, size_t length, const char *name);
+
+/**
+ construct a data blob, using supplied TALLOC_CTX
+**/
+_PUBLIC_ DATA_BLOB data_blob_talloc_named(TALLOC_CTX *mem_ctx, const void *p, size_t length, const char *name);
+
+/**
+ construct a zero data blob, using supplied TALLOC_CTX.
+ use this sparingly as it initialises data - better to initialise
+ yourself if you want specific data in the blob
+**/
+_PUBLIC_ DATA_BLOB data_blob_talloc_zero(TALLOC_CTX *mem_ctx, size_t length);
+
+/**
+free a data blob
+**/
+_PUBLIC_ void data_blob_free(DATA_BLOB *d);
+
+/**
+clear a DATA_BLOB's contents
+**/
+_PUBLIC_ void data_blob_clear(DATA_BLOB *d);
+
+/**
+free a data blob and clear its contents
+**/
+_PUBLIC_ void data_blob_clear_free(DATA_BLOB *d);
+
+/**
+check if two data blobs are equal
+**/
+_PUBLIC_ int data_blob_cmp(const DATA_BLOB *d1, const DATA_BLOB *d2);
+
+/**
+check if two data blobs are equal, where the time taken should not depend on the
+contents of either blob.
+**/
+_PUBLIC_ bool data_blob_equal_const_time(const DATA_BLOB *d1, const DATA_BLOB *d2);
+
+/**
+print the data_blob as hex string
+**/
+_PUBLIC_ char *data_blob_hex_string_upper(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob);
+
+/**
+print the data_blob as hex string
+**/
+_PUBLIC_ char *data_blob_hex_string_lower(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob);
+
+/**
+ useful for constructing data blobs in test suites, while
+ avoiding const warnings
+**/
+_PUBLIC_ DATA_BLOB data_blob_string_const(const char *str);
+
+/**
+ useful for constructing data blobs in test suites, while
+ avoiding const warnings
+
+ includes the terminating null character (as opposed to data_blob_string_const)
+**/
+_PUBLIC_ DATA_BLOB data_blob_string_const_null(const char *str);
+
+/**
+ * Create a new data blob from const data
+ */
+_PUBLIC_ DATA_BLOB data_blob_const(const void *p, size_t length);
+
+/**
+ realloc a data_blob
+**/
+_PUBLIC_ bool data_blob_realloc(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, size_t length);
+
+/**
+ append some data to a data blob
+**/
+_PUBLIC_ bool data_blob_append(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
+ const void *p, size_t length);
+
+/**
+ pad the length of a data blob to a multiple of
+ 'pad'. 'pad' must be a power of two.
+**/
+_PUBLIC_ bool data_blob_pad(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
+ size_t pad);
+
+extern const DATA_BLOB data_blob_null;
+
+#endif /* _SAMBA_DATABLOB_H_ */
diff --git a/lib/util/debug-classes/debug-classname-table.c b/lib/util/debug-classes/debug-classname-table.c
new file mode 100644
index 0000000..9062078
--- /dev/null
+++ b/lib/util/debug-classes/debug-classname-table.c
@@ -0,0 +1,62 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Elrond 2002
+ Copyright (C) Simo Sorce 2002
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+
+static const char *default_classname_table[] = {
+ [DBGC_ALL] = "all",
+ [DBGC_TDB] = "tdb",
+ [DBGC_PRINTDRIVERS] = "printdrivers",
+ [DBGC_LANMAN] = "lanman",
+ [DBGC_SMB] = "smb",
+ [DBGC_RPC_PARSE] = "rpc_parse",
+ [DBGC_RPC_SRV] = "rpc_srv",
+ [DBGC_RPC_CLI] = "rpc_cli",
+ [DBGC_PASSDB] = "passdb",
+ [DBGC_SAM] = "sam",
+ [DBGC_AUTH] = "auth",
+ [DBGC_WINBIND] = "winbind",
+ [DBGC_VFS] = "vfs",
+ [DBGC_IDMAP] = "idmap",
+ [DBGC_QUOTA] = "quota",
+ [DBGC_ACLS] = "acls",
+ [DBGC_LOCKING] = "locking",
+ [DBGC_MSDFS] = "msdfs",
+ [DBGC_DMAPI] = "dmapi",
+ [DBGC_REGISTRY] = "registry",
+ [DBGC_SCAVENGER] = "scavenger",
+ [DBGC_DNS] = "dns",
+ [DBGC_LDB] = "ldb",
+ [DBGC_TEVENT] = "tevent",
+ [DBGC_AUTH_AUDIT] = "auth_audit",
+ [DBGC_AUTH_AUDIT_JSON] = "auth_json_audit",
+ [DBGC_KERBEROS] = "kerberos",
+ [DBGC_DRS_REPL] = "drs_repl",
+ [DBGC_SMB2] = "smb2",
+ [DBGC_SMB2_CREDITS] = "smb2_credits",
+ [DBGC_DSDB_AUDIT] = "dsdb_audit",
+ [DBGC_DSDB_AUDIT_JSON] = "dsdb_json_audit",
+ [DBGC_DSDB_PWD_AUDIT] = "dsdb_password_audit",
+ [DBGC_DSDB_PWD_AUDIT_JSON] = "dsdb_password_json_audit",
+ [DBGC_DSDB_TXN_AUDIT] = "dsdb_transaction_audit",
+ [DBGC_DSDB_TXN_AUDIT_JSON] = "dsdb_transaction_json_audit",
+ [DBGC_DSDB_GROUP_AUDIT] = "dsdb_group_audit",
+ [DBGC_DSDB_GROUP_AUDIT_JSON] = "dsdb_group_json_audit",
+};
diff --git a/lib/util/debug.c b/lib/util/debug.c
new file mode 100644
index 0000000..86f13f1
--- /dev/null
+++ b/lib/util/debug.c
@@ -0,0 +1,1978 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Elrond 2002
+ Copyright (C) Simo Sorce 2002
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include <talloc.h>
+#include "system/filesys.h"
+#include "system/syslog.h"
+#include "system/locale.h"
+#include "system/network.h"
+#include "system/time.h"
+#include "time_basic.h"
+#include "close_low_fd.h"
+#include "memory.h"
+#include "util_strlist.h" /* LIST_SEP */
+#include "blocking.h"
+#include "debug.h"
+#include <assert.h>
+
+/* define what facility to use for syslog */
+#ifndef SYSLOG_FACILITY
+#define SYSLOG_FACILITY LOG_DAEMON
+#endif
+
+/* -------------------------------------------------------------------------- **
+ * Defines...
+ */
+
+/*
+ * format_bufr[FORMAT_BUFR_SIZE - 1] should always be reserved
+ * for a terminating null byte.
+ */
+#define FORMAT_BUFR_SIZE 4096
+
+/* -------------------------------------------------------------------------- **
+ * This module implements Samba's debugging utility.
+ *
+ * The syntax of a debugging log file is represented as:
+ *
+ * <debugfile> :== { <debugmsg> }
+ *
+ * <debugmsg> :== <debughdr> '\n' <debugtext>
+ *
+ * <debughdr> :== '[' TIME ',' LEVEL ']' [ [FILENAME ':'] [FUNCTION '()'] ]
+ *
+ * <debugtext> :== { <debugline> }
+ *
+ * <debugline> :== TEXT '\n'
+ *
+ * TEXT is a string of characters excluding the newline character.
+ * LEVEL is the DEBUG level of the message (an integer in the range 0..10).
+ * TIME is a timestamp.
+ * FILENAME is the name of the file from which the debug message was generated.
+ * FUNCTION is the function from which the debug message was generated.
+ *
+ * Basically, what that all means is:
+ *
+ * - A debugging log file is made up of debug messages.
+ *
+ * - Each debug message is made up of a header and text. The header is
+ * separated from the text by a newline.
+ *
+ * - The header begins with the timestamp and debug level of the message
+ * enclosed in brackets. The filename and function from which the
+ * message was generated may follow. The filename is terminated by a
+ * colon, and the function name is terminated by parenthesis.
+ *
+ * - The message text is made up of zero or more lines, each terminated by
+ * a newline.
+ */
+
+/* state variables for the debug system */
+static struct {
+ bool initialized;
+ enum debug_logtype logtype; /* The type of logging we are doing: eg stdout, file, stderr */
+ char prog_name[255];
+ char hostname[HOST_NAME_MAX+1];
+ bool reopening_logs;
+ bool schedule_reopen_logs;
+ int forced_log_priority;
+
+ struct debug_settings settings;
+ debug_callback_fn callback;
+ void *callback_private;
+ char header_str[300];
+ size_t hs_len;
+} state = {
+ .settings = {
+ .timestamp_logs = true
+ },
+};
+
+struct debug_class {
+ /*
+ * The debug loglevel of the class.
+ */
+ int loglevel;
+
+ /*
+ * An optional class specific logfile, may be NULL in which case the
+ * "global" logfile is used and fd is -1.
+ */
+ char *logfile;
+ int fd;
+ /* inode number of the logfile to detect logfile rotation */
+ ino_t ino;
+};
+
+/*
+ * default_classname_table[] is read in from debug-classname-table.c
+ * so that test_logging.c can use it too.
+ */
+#include "lib/util/debug-classes/debug-classname-table.c"
+
+/*
+ * This is to allow reading of dbgc_config before the debug
+ * system has been initialized.
+ */
+static struct debug_class debug_class_list_initial[ARRAY_SIZE(default_classname_table)] = {
+ [DBGC_ALL] = { .fd = 2 },
+};
+
+static size_t debug_num_classes = 0;
+static struct debug_class *dbgc_config = debug_class_list_initial;
+
+static int current_msg_level = 0;
+static int current_msg_class = 0;
+
+/*
+ * DBG_DEV(): when and how to user it.
+ *
+ * As a developer, you sometimes want verbose logging between point A and
+ * point B, where the relationship between these points is not easily defined
+ * in terms of the call stack.
+ *
+ * For example, you might be interested in what is going on in functions in
+ * lib/util/util_str.c in an ldap worker process after a particular query. If
+ * you use gdb, something will time out and you won't get the full
+ * conversation. If you add fprintf() or DBG_ERR()s to util_str.c, you'll get
+ * a massive flood, and there's a chance one will accidentally slip into a
+ * release and the whole world will flood. DBG_DEV is a solution.
+ *
+ * On start-up, DBG_DEV() is switched OFF. Nothing is printed.
+ *
+ * 1. Add `DBG_DEV("formatted msg %d, etc\n", i);` where needed.
+ *
+ * 2. At each point you want to start debugging, add `debug_developer_enable()`.
+ *
+ * 3. At each point you want debugging to stop, add `debug_developer_disable()`.
+ *
+ * In DEVELOPER builds, the message will be printed at level 0, as with
+ * DBG_ERR(). In production builds, the macro resolves to nothing.
+ *
+ * The messages are printed with a "<function_name>:DEV:<pid>:" prefix.
+ */
+
+static bool debug_developer_is_enabled = false;
+
+bool debug_developer_enabled(void)
+{
+ return debug_developer_is_enabled;
+}
+
+/*
+ * debug_developer_disable() will turn DBG_DEV() on in the current
+ * process and children.
+ */
+void debug_developer_enable(void)
+{
+ debug_developer_is_enabled = true;
+}
+
+/*
+ * debug_developer_disable() will make DBG_DEV() do nothing in the current
+ * process (and children).
+ */
+void debug_developer_disable(void)
+{
+ debug_developer_is_enabled = false;
+}
+
+/*
+ * Within debug.c, DBG_DEV() always writes to stderr, because some functions
+ * here will attempt infinite recursion with normal DEBUG macros.
+ */
+#ifdef DEVELOPER
+#undef DBG_DEV
+#define DBG_DEV(fmt, ...) \
+ (void)((debug_developer_enabled()) \
+ && (fprintf(stderr, "%s:DEV:%d: " fmt "%s", \
+ __func__, getpid(), ##__VA_ARGS__, "")) )
+#endif
+
+
+#if defined(WITH_SYSLOG) || defined(HAVE_LIBSYSTEMD_JOURNAL) || defined(HAVE_LIBSYSTEMD)
+static int debug_level_to_priority(int level)
+{
+ /*
+ * map debug levels to syslog() priorities
+ */
+ static const int priority_map[] = {
+ LOG_ERR, /* 0 */
+ LOG_WARNING, /* 1 */
+ LOG_NOTICE, /* 2 */
+ LOG_NOTICE, /* 3 */
+ LOG_NOTICE, /* 4 */
+ LOG_NOTICE, /* 5 */
+ LOG_INFO, /* 6 */
+ LOG_INFO, /* 7 */
+ LOG_INFO, /* 8 */
+ LOG_INFO, /* 9 */
+ };
+ int priority;
+
+ if (state.forced_log_priority != -1) {
+ level = state.forced_log_priority;
+ }
+
+ if (level < 0 || (size_t)level >= ARRAY_SIZE(priority_map))
+ priority = LOG_DEBUG;
+ else
+ priority = priority_map[level];
+
+ return priority;
+}
+#endif
+
+/* -------------------------------------------------------------------------- **
+ * Debug backends. When logging to DEBUG_FILE, send the log entries to
+ * all active backends.
+ */
+
+static void debug_file_log(int msg_level, const char *msg, size_t msg_len)
+{
+ struct iovec iov[] = {
+ {
+ .iov_base = discard_const(state.header_str),
+ .iov_len = state.hs_len,
+ },
+ {
+ .iov_base = discard_const(msg),
+ .iov_len = msg_len,
+ },
+ };
+ ssize_t ret;
+ int fd;
+
+ check_log_size();
+
+ if (dbgc_config[current_msg_class].fd != -1) {
+ fd = dbgc_config[current_msg_class].fd;
+ } else {
+ fd = dbgc_config[DBGC_ALL].fd;
+ }
+
+ do {
+ ret = writev(fd, iov, ARRAY_SIZE(iov));
+ } while (ret == -1 && errno == EINTR);
+}
+
+#ifdef WITH_SYSLOG
+static void debug_syslog_reload(bool enabled, bool previously_enabled,
+ const char *prog_name, char *option)
+{
+ if (enabled && !previously_enabled) {
+ const char *ident = NULL;
+ if ((prog_name != NULL) && (prog_name[0] != '\0')) {
+ ident = prog_name;
+ }
+#ifdef LOG_DAEMON
+ openlog(ident, LOG_PID, SYSLOG_FACILITY);
+#else
+ /* for old systems that have no facility codes. */
+ openlog(ident, LOG_PID);
+#endif
+ return;
+ }
+
+ if (!enabled && previously_enabled) {
+ closelog();
+ }
+}
+
+static void debug_syslog_log(int msg_level, const char *msg, size_t msg_len)
+{
+ int priority;
+
+ priority = debug_level_to_priority(msg_level);
+
+ /*
+ * Specify the facility to interoperate with other syslog
+ * callers (vfs_full_audit for example).
+ */
+ priority |= SYSLOG_FACILITY;
+
+ if (state.hs_len > 0) {
+ syslog(priority, "%s", state.header_str);
+ }
+ syslog(priority, "%s", msg);
+}
+#endif /* WITH_SYSLOG */
+
+#if defined(HAVE_LIBSYSTEMD_JOURNAL) || defined(HAVE_LIBSYSTEMD)
+#include <systemd/sd-journal.h>
+static void debug_systemd_log(int msg_level, const char *msg, size_t msg_len)
+{
+ if (state.hs_len > 0) {
+ size_t len = state.hs_len;
+
+ if (state.header_str[len - 1] == '\n') {
+ len -= 1;
+ }
+
+ sd_journal_send("MESSAGE=%.*s",
+ (int)len,
+ state.header_str,
+ "PRIORITY=%d",
+ debug_level_to_priority(msg_level),
+ "LEVEL=%d",
+ msg_level,
+ NULL);
+ }
+
+ if ((msg_len > 0) && (msg[msg_len - 1] == '\n')) {
+ msg_len -= 1;
+ }
+
+ sd_journal_send("MESSAGE=%.*s",
+ (int)msg_len,
+ msg,
+ "PRIORITY=%d",
+ debug_level_to_priority(msg_level),
+ "LEVEL=%d",
+ msg_level,
+ NULL);
+}
+#endif
+
+#ifdef HAVE_LTTNG_TRACEF
+#include <lttng/tracef.h>
+static void debug_lttng_log(int msg_level, const char *msg, size_t msg_len)
+{
+ if (state.hs_len > 0) {
+ size_t len = state.hs_len;
+
+ if (state.header_str[len - 1] == '\n') {
+ len -= 1;
+ }
+
+ tracef("%.*s", (int)len, state.header_str);
+ }
+
+ if ((msg_len > 0) && (msg[msg_len - 1] == '\n')) {
+ msg_len -= 1;
+ }
+ tracef("%.*s", (int)msg_len, msg);
+}
+#endif /* WITH_LTTNG_TRACEF */
+
+#ifdef HAVE_GPFS
+#include "gpfswrap.h"
+static void debug_gpfs_reload(bool enabled, bool previously_enabled,
+ const char *prog_name, char *option)
+{
+ if (enabled) {
+ gpfswrap_init();
+ }
+
+ if (enabled && !previously_enabled) {
+ gpfswrap_init_trace();
+ return;
+ }
+
+ if (!enabled && previously_enabled) {
+ gpfswrap_fini_trace();
+ return;
+ }
+
+ if (enabled) {
+ /*
+ * Trigger GPFS library to adjust state if necessary.
+ */
+ gpfswrap_query_trace();
+ }
+}
+
+static void copy_no_nl(char *out,
+ size_t out_size,
+ const char *in,
+ size_t in_len)
+{
+ size_t len;
+ /*
+ * Some backends already add an extra newline, so also provide
+ * a buffer without the newline character.
+ */
+ len = MIN(in_len, out_size - 1);
+ if ((len > 0) && (in[len - 1] == '\n')) {
+ len--;
+ }
+
+ memcpy(out, in, len);
+ out[len] = '\0';
+}
+
+static void debug_gpfs_log(int msg_level, const char *msg, size_t msg_len)
+{
+ char no_nl[FORMAT_BUFR_SIZE];
+
+ if (state.hs_len > 0) {
+ copy_no_nl(no_nl,
+ sizeof(no_nl),
+ state.header_str,
+ state.hs_len);
+ gpfswrap_add_trace(msg_level, no_nl);
+ }
+
+ copy_no_nl(no_nl, sizeof(no_nl), msg, msg_len);
+ gpfswrap_add_trace(msg_level, no_nl);
+}
+#endif /* HAVE_GPFS */
+
+#define DEBUG_RINGBUF_SIZE (1024 * 1024)
+#define DEBUG_RINGBUF_SIZE_OPT "size="
+
+static char *debug_ringbuf;
+static size_t debug_ringbuf_size;
+static size_t debug_ringbuf_ofs;
+
+/* We ensure in debug_ringbuf_log() that this is always \0 terminated */
+char *debug_get_ringbuf(void)
+{
+ return debug_ringbuf;
+}
+
+/* Return the size of the ringbuf (including a \0 terminator) */
+size_t debug_get_ringbuf_size(void)
+{
+ return debug_ringbuf_size;
+}
+
+static void debug_ringbuf_reload(bool enabled, bool previously_enabled,
+ const char *prog_name, char *option)
+{
+ bool cmp;
+ size_t optlen = strlen(DEBUG_RINGBUF_SIZE_OPT);
+
+ debug_ringbuf_size = DEBUG_RINGBUF_SIZE;
+ debug_ringbuf_ofs = 0;
+
+ SAFE_FREE(debug_ringbuf);
+
+ if (!enabled) {
+ return;
+ }
+
+ if (option != NULL) {
+ cmp = strncmp(option, DEBUG_RINGBUF_SIZE_OPT, optlen);
+ if (cmp == 0) {
+ debug_ringbuf_size = (size_t)strtoull(
+ option + optlen, NULL, 10);
+ }
+ }
+
+ debug_ringbuf = calloc(debug_ringbuf_size, sizeof(char));
+ if (debug_ringbuf == NULL) {
+ return;
+ }
+}
+
+static void _debug_ringbuf_log(int msg_level, const char *msg, size_t msg_len)
+{
+ size_t allowed_size;
+
+ if (debug_ringbuf == NULL) {
+ return;
+ }
+
+ /* Ensure the buffer is always \0 terminated */
+ allowed_size = debug_ringbuf_size - 1;
+
+ if (msg_len > allowed_size) {
+ return;
+ }
+
+ if ((debug_ringbuf_ofs + msg_len) < debug_ringbuf_ofs) {
+ return;
+ }
+
+ if ((debug_ringbuf_ofs + msg_len) > allowed_size) {
+ debug_ringbuf_ofs = 0;
+ }
+
+ memcpy(debug_ringbuf + debug_ringbuf_ofs, msg, msg_len);
+ debug_ringbuf_ofs += msg_len;
+}
+
+static void debug_ringbuf_log(int msg_level, const char *msg, size_t msg_len)
+{
+ if (state.hs_len > 0) {
+ _debug_ringbuf_log(msg_level, state.header_str, state.hs_len);
+ }
+ _debug_ringbuf_log(msg_level, msg, msg_len);
+}
+
+static struct debug_backend {
+ const char *name;
+ int log_level;
+ int new_log_level;
+ void (*reload)(bool enabled, bool prev_enabled,
+ const char *prog_name, char *option);
+ void (*log)(int msg_level,
+ const char *msg,
+ size_t len);
+ char *option;
+} debug_backends[] = {
+ {
+ .name = "file",
+ .log = debug_file_log,
+ },
+#ifdef WITH_SYSLOG
+ {
+ .name = "syslog",
+ .reload = debug_syslog_reload,
+ .log = debug_syslog_log,
+ },
+#endif
+
+#if defined(HAVE_LIBSYSTEMD_JOURNAL) || defined(HAVE_LIBSYSTEMD)
+ {
+ .name = "systemd",
+ .log = debug_systemd_log,
+ },
+#endif
+
+#ifdef HAVE_LTTNG_TRACEF
+ {
+ .name = "lttng",
+ .log = debug_lttng_log,
+ },
+#endif
+
+#ifdef HAVE_GPFS
+ {
+ .name = "gpfs",
+ .reload = debug_gpfs_reload,
+ .log = debug_gpfs_log,
+ },
+#endif
+ {
+ .name = "ringbuf",
+ .log = debug_ringbuf_log,
+ .reload = debug_ringbuf_reload,
+ },
+};
+
+static struct debug_backend *debug_find_backend(const char *name)
+{
+ unsigned i;
+
+ for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
+ if (strcmp(name, debug_backends[i].name) == 0) {
+ return &debug_backends[i];
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * parse "backend[:option][@loglevel]
+ */
+static void debug_backend_parse_token(char *tok)
+{
+ char *backend_name_option, *backend_name,*backend_level, *saveptr;
+ char *backend_option;
+ struct debug_backend *b;
+
+ /*
+ * First parse into backend[:option] and loglevel
+ */
+ backend_name_option = strtok_r(tok, "@\0", &saveptr);
+ if (backend_name_option == NULL) {
+ return;
+ }
+
+ backend_level = strtok_r(NULL, "\0", &saveptr);
+
+ /*
+ * Now parse backend[:option]
+ */
+ backend_name = strtok_r(backend_name_option, ":\0", &saveptr);
+ if (backend_name == NULL) {
+ return;
+ }
+
+ backend_option = strtok_r(NULL, "\0", &saveptr);
+
+ /*
+ * Find and update backend
+ */
+ b = debug_find_backend(backend_name);
+ if (b == NULL) {
+ return;
+ }
+
+ if (backend_level == NULL) {
+ b->new_log_level = MAX_DEBUG_LEVEL;
+ } else {
+ b->new_log_level = atoi(backend_level);
+ }
+
+ if (backend_option != NULL) {
+ b->option = strdup(backend_option);
+ if (b->option == NULL) {
+ return;
+ }
+ }
+}
+
+/*
+ * parse "backend1[:option1][@loglevel1] backend2[option2][@loglevel2] ... "
+ * and enable/disable backends accordingly
+ */
+static void debug_set_backends(const char *param)
+{
+ size_t str_len = strlen(param);
+ char str[str_len+1];
+ char *tok, *saveptr;
+ unsigned i;
+
+ /*
+ * initialize new_log_level to detect backends that have been
+ * disabled
+ */
+ for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
+ SAFE_FREE(debug_backends[i].option);
+ debug_backends[i].new_log_level = -1;
+ }
+
+ memcpy(str, param, str_len + 1);
+
+ tok = strtok_r(str, LIST_SEP, &saveptr);
+ if (tok == NULL) {
+ return;
+ }
+
+ while (tok != NULL) {
+ debug_backend_parse_token(tok);
+ tok = strtok_r(NULL, LIST_SEP, &saveptr);
+ }
+
+ /*
+ * Let backends react to config changes
+ */
+ for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
+ struct debug_backend *b = &debug_backends[i];
+
+ if (b->reload) {
+ bool enabled = b->new_log_level > -1;
+ bool previously_enabled = b->log_level > -1;
+
+ b->reload(enabled, previously_enabled, state.prog_name,
+ b->option);
+ }
+ b->log_level = b->new_log_level;
+ }
+}
+
+static void debug_backends_log(const char *msg, size_t msg_len, int msg_level)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
+ if (msg_level <= debug_backends[i].log_level) {
+ debug_backends[i].log(msg_level, msg, msg_len);
+ }
+ }
+
+ /* Only log the header once */
+ state.hs_len = 0;
+}
+
+int debuglevel_get_class(size_t idx)
+{
+ return dbgc_config[idx].loglevel;
+}
+
+void debuglevel_set_class(size_t idx, int level)
+{
+ dbgc_config[idx].loglevel = level;
+}
+
+
+/* -------------------------------------------------------------------------- **
+ * Internal variables.
+ *
+ * debug_count - Number of debug messages that have been output.
+ * Used to check log size.
+ *
+ * current_msg_level - Internal copy of the message debug level. Written by
+ * dbghdr() and read by Debug1().
+ *
+ * format_bufr - Used to format debug messages. The dbgtext() function
+ * prints debug messages to a string, and then passes the
+ * string to format_debug_text(), which uses format_bufr
+ * to build the formatted output.
+ *
+ * format_pos - Marks the first free byte of the format_bufr.
+ *
+ *
+ * log_overflow - When this variable is true, never attempt to check the
+ * size of the log. This is a hack, so that we can write
+ * a message using DEBUG, from open_logs() when we
+ * are unable to open a new log file for some reason.
+ */
+
+static int debug_count = 0;
+static char format_bufr[FORMAT_BUFR_SIZE];
+static size_t format_pos = 0;
+static bool log_overflow = false;
+
+/*
+ * Define all the debug class selection names here. Names *MUST NOT* contain
+ * white space. There must be one name for each DBGC_<class name>, and they
+ * must be in the table in the order of DBGC_<class name>..
+ */
+
+static char **classname_table = NULL;
+
+
+/* -------------------------------------------------------------------------- **
+ * Functions...
+ */
+
+static void debug_init(void);
+
+/***************************************************************************
+ Free memory pointed to by global pointers.
+****************************************************************************/
+
+void gfree_debugsyms(void)
+{
+ unsigned i;
+
+ TALLOC_FREE(classname_table);
+
+ if ( dbgc_config != debug_class_list_initial ) {
+ TALLOC_FREE( dbgc_config );
+ dbgc_config = discard_const_p(struct debug_class,
+ debug_class_list_initial);
+ }
+
+ debug_num_classes = 0;
+
+ state.initialized = false;
+
+ for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
+ SAFE_FREE(debug_backends[i].option);
+ }
+}
+
+/****************************************************************************
+utility lists registered debug class names's
+****************************************************************************/
+
+char *debug_list_class_names_and_levels(void)
+{
+ char *buf = talloc_strdup(NULL, "");
+ size_t i;
+ /* prepare strings */
+ for (i = 0; i < debug_num_classes; i++) {
+ talloc_asprintf_addbuf(&buf,
+ "%s:%d%s",
+ classname_table[i],
+ dbgc_config[i].loglevel,
+ i == (debug_num_classes - 1) ? "\n" : " ");
+ }
+ return buf;
+}
+
+/****************************************************************************
+ Utility to translate names to debug class index's (internal version).
+****************************************************************************/
+
+static int debug_lookup_classname_int(const char* classname)
+{
+ size_t i;
+
+ if (classname == NULL) {
+ return -1;
+ }
+
+ for (i=0; i < debug_num_classes; i++) {
+ char *entry = classname_table[i];
+ if (entry != NULL && strcmp(classname, entry)==0) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+/****************************************************************************
+ Add a new debug class to the system.
+****************************************************************************/
+
+int debug_add_class(const char *classname)
+{
+ int ndx;
+ struct debug_class *new_class_list = NULL;
+ char **new_name_list;
+ int default_level;
+
+ if (classname == NULL) {
+ return -1;
+ }
+
+ /* check the init has yet been called */
+ debug_init();
+
+ ndx = debug_lookup_classname_int(classname);
+ if (ndx >= 0) {
+ return ndx;
+ }
+ ndx = debug_num_classes;
+
+ if (dbgc_config == debug_class_list_initial) {
+ /* Initial loading... */
+ new_class_list = NULL;
+ } else {
+ new_class_list = dbgc_config;
+ }
+
+ default_level = dbgc_config[DBGC_ALL].loglevel;
+
+ new_class_list = talloc_realloc(NULL,
+ new_class_list,
+ struct debug_class,
+ ndx + 1);
+ if (new_class_list == NULL) {
+ return -1;
+ }
+
+ dbgc_config = new_class_list;
+
+ dbgc_config[ndx] = (struct debug_class) {
+ .loglevel = default_level,
+ .fd = -1,
+ };
+
+ new_name_list = talloc_realloc(NULL, classname_table, char *, ndx + 1);
+ if (new_name_list == NULL) {
+ return -1;
+ }
+ classname_table = new_name_list;
+
+ classname_table[ndx] = talloc_strdup(classname_table, classname);
+ if (classname_table[ndx] == NULL) {
+ return -1;
+ }
+
+ debug_num_classes = ndx + 1;
+
+ return ndx;
+}
+
+/****************************************************************************
+ Utility to translate names to debug class index's (public version).
+****************************************************************************/
+
+static int debug_lookup_classname(const char *classname)
+{
+ int ndx;
+
+ if (classname == NULL || !*classname)
+ return -1;
+
+ ndx = debug_lookup_classname_int(classname);
+
+ if (ndx != -1)
+ return ndx;
+
+ DBG_WARNING("Unknown classname[%s] -> adding it...\n", classname);
+ return debug_add_class(classname);
+}
+
+/****************************************************************************
+ Dump the current registered debug levels.
+****************************************************************************/
+
+static void debug_dump_status(int level)
+{
+ size_t q;
+
+ DEBUG(level, ("INFO: Current debug levels:\n"));
+ for (q = 0; q < debug_num_classes; q++) {
+ const char *classname = classname_table[q];
+ DEBUGADD(level, (" %s: %d\n",
+ classname,
+ dbgc_config[q].loglevel));
+ }
+}
+
+static bool debug_parse_param(char *param)
+{
+ char *class_name;
+ char *class_file = NULL;
+ char *class_level;
+ char *saveptr = NULL;
+ int ndx;
+
+ class_name = strtok_r(param, ":", &saveptr);
+ if (class_name == NULL) {
+ return false;
+ }
+
+ class_level = strtok_r(NULL, "@\0", &saveptr);
+ if (class_level == NULL) {
+ return false;
+ }
+
+ class_file = strtok_r(NULL, "\0", &saveptr);
+
+ ndx = debug_lookup_classname(class_name);
+ if (ndx == -1) {
+ return false;
+ }
+
+ dbgc_config[ndx].loglevel = atoi(class_level);
+
+ if (class_file == NULL) {
+ return true;
+ }
+
+ TALLOC_FREE(dbgc_config[ndx].logfile);
+
+ dbgc_config[ndx].logfile = talloc_strdup(NULL, class_file);
+ if (dbgc_config[ndx].logfile == NULL) {
+ return false;
+ }
+ return true;
+}
+
+/****************************************************************************
+ Parse the debug levels from smb.conf. Example debug level string:
+ 3 tdb:5 printdrivers:7
+ Note: the 1st param has no "name:" preceding it.
+****************************************************************************/
+
+bool debug_parse_levels(const char *params_str)
+{
+ size_t str_len = strlen(params_str);
+ char str[str_len+1];
+ char *tok, *saveptr;
+ size_t i;
+
+ /* Just in case */
+ debug_init();
+
+ memcpy(str, params_str, str_len+1);
+
+ tok = strtok_r(str, LIST_SEP, &saveptr);
+ if (tok == NULL) {
+ return true;
+ }
+
+ /* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10"
+ * v.s. "all:10", this is the traditional way to set DEBUGLEVEL
+ */
+ if (isdigit(tok[0])) {
+ dbgc_config[DBGC_ALL].loglevel = atoi(tok);
+ tok = strtok_r(NULL, LIST_SEP, &saveptr);
+ } else {
+ dbgc_config[DBGC_ALL].loglevel = 0;
+ }
+
+ /* Array is debug_num_classes long */
+ for (i = DBGC_ALL+1; i < debug_num_classes; i++) {
+ dbgc_config[i].loglevel = dbgc_config[DBGC_ALL].loglevel;
+ TALLOC_FREE(dbgc_config[i].logfile);
+ }
+
+ while (tok != NULL) {
+ bool ok;
+
+ ok = debug_parse_param(tok);
+ if (!ok) {
+ DEBUG(0,("debug_parse_params: unrecognized debug "
+ "class name or format [%s]\n", tok));
+ return false;
+ }
+
+ tok = strtok_r(NULL, LIST_SEP, &saveptr);
+ }
+
+ debug_dump_status(5);
+
+ return true;
+}
+
+/* setup for logging of talloc warnings */
+static void talloc_log_fn(const char *msg)
+{
+ DEBUG(0,("%s", msg));
+}
+
+void debug_setup_talloc_log(void)
+{
+ talloc_set_log_fn(talloc_log_fn);
+}
+
+
+/****************************************************************************
+Init debugging (one time stuff)
+****************************************************************************/
+
+static void debug_init(void)
+{
+ size_t i;
+
+ if (state.initialized)
+ return;
+
+ state.initialized = true;
+
+ debug_setup_talloc_log();
+
+ for (i = 0; i < ARRAY_SIZE(default_classname_table); i++) {
+ debug_add_class(default_classname_table[i]);
+ }
+ dbgc_config[DBGC_ALL].fd = 2;
+
+ for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
+ debug_backends[i].log_level = -1;
+ debug_backends[i].new_log_level = -1;
+ }
+}
+
+void debug_set_settings(struct debug_settings *settings,
+ const char *logging_param,
+ int syslog_level, bool syslog_only)
+{
+ char fake_param[256];
+ size_t len = 0;
+
+ /*
+ * This forces in some smb.conf derived values into the debug
+ * system. There are no pointers in this structure, so we can
+ * just structure-assign it in
+ */
+ state.settings = *settings;
+
+ /*
+ * If 'logging' is not set, create backend settings from
+ * deprecated 'syslog' and 'syslog only' parameters
+ */
+ if (logging_param != NULL) {
+ len = strlen(logging_param);
+ }
+ if (len == 0) {
+ if (syslog_only) {
+ snprintf(fake_param, sizeof(fake_param),
+ "syslog@%d", syslog_level - 1);
+ } else {
+ snprintf(fake_param, sizeof(fake_param),
+ "syslog@%d file@%d", syslog_level -1,
+ MAX_DEBUG_LEVEL);
+ }
+
+ logging_param = fake_param;
+ }
+
+ debug_set_backends(logging_param);
+}
+
+static void ensure_hostname(void)
+{
+ int ret;
+
+ if (state.hostname[0] != '\0') {
+ return;
+ }
+
+ ret = gethostname(state.hostname, sizeof(state.hostname));
+ if (ret != 0) {
+ strlcpy(state.hostname, "unknown", sizeof(state.hostname));
+ return;
+ }
+
+ /*
+ * Ensure NUL termination, since POSIX isn't clear about that.
+ *
+ * Don't worry about truncating at the first '.' or similar,
+ * since this is usually not fully qualified. Trying to
+ * truncate opens up the multibyte character gates of hell.
+ */
+ state.hostname[sizeof(state.hostname) - 1] = '\0';
+}
+
+void debug_set_hostname(const char *name)
+{
+ strlcpy(state.hostname, name, sizeof(state.hostname));
+}
+
+void debug_set_forced_log_priority(int forced_log_priority)
+{
+ state.forced_log_priority = forced_log_priority;
+}
+
+/**
+ * Ensure debug logs are initialised.
+ *
+ * setup_logging() is called to direct logging to the correct outputs, whether
+ * those be stderr, stdout, files, or syslog, and set the program name used in
+ * the logs. It can be called multiple times.
+ *
+ * There is an order of precedence to the log type. Once set to DEBUG_FILE, it
+ * cannot be reset DEFAULT_DEBUG_STDERR, but can be set to DEBUG_STDERR, after
+ * which DEBUG_FILE is unavailable). This makes it possible to override for
+ * debug to stderr on the command line, as the smb.conf cannot reset it back
+ * to file-based logging. See enum debug_logtype.
+ *
+ * @param prog_name the program name. Directory path component will be
+ * ignored.
+ *
+ * @param new_logtype the requested destination for the debug log,
+ * as an enum debug_logtype.
+ */
+void setup_logging(const char *prog_name, enum debug_logtype new_logtype)
+{
+ debug_init();
+ if (state.logtype < new_logtype) {
+ state.logtype = new_logtype;
+ }
+ if (prog_name) {
+ const char *p = strrchr(prog_name, '/');
+
+ if (p) {
+ prog_name = p + 1;
+ }
+
+ strlcpy(state.prog_name, prog_name, sizeof(state.prog_name));
+ }
+ reopen_logs_internal();
+}
+
+/***************************************************************************
+ Set the logfile name.
+**************************************************************************/
+
+void debug_set_logfile(const char *name)
+{
+ if (name == NULL || *name == 0) {
+ /* this copes with calls when smb.conf is not loaded yet */
+ return;
+ }
+ TALLOC_FREE(dbgc_config[DBGC_ALL].logfile);
+ dbgc_config[DBGC_ALL].logfile = talloc_strdup(NULL, name);
+
+ reopen_logs_internal();
+}
+
+static void debug_close_fd(int fd)
+{
+ if (fd > 2) {
+ close(fd);
+ }
+}
+
+enum debug_logtype debug_get_log_type(void)
+{
+ return state.logtype;
+}
+
+bool debug_get_output_is_stderr(void)
+{
+ return (state.logtype == DEBUG_DEFAULT_STDERR) || (state.logtype == DEBUG_STDERR);
+}
+
+bool debug_get_output_is_stdout(void)
+{
+ return (state.logtype == DEBUG_DEFAULT_STDOUT) || (state.logtype == DEBUG_STDOUT);
+}
+
+void debug_set_callback(void *private_ptr, debug_callback_fn fn)
+{
+ debug_init();
+ if (fn) {
+ state.logtype = DEBUG_CALLBACK;
+ state.callback_private = private_ptr;
+ state.callback = fn;
+ } else {
+ state.logtype = DEBUG_DEFAULT_STDERR;
+ state.callback_private = NULL;
+ state.callback = NULL;
+ }
+}
+
+static void debug_callback_log(const char *msg, size_t msg_len, int msg_level)
+{
+ char msg_copy[msg_len];
+
+ if ((msg_len > 0) && (msg[msg_len-1] == '\n')) {
+ memcpy(msg_copy, msg, msg_len-1);
+ msg_copy[msg_len-1] = '\0';
+ msg = msg_copy;
+ }
+
+ state.callback(state.callback_private, msg_level, msg);
+}
+
+/**************************************************************************
+ reopen the log files
+ note that we now do this unconditionally
+ We attempt to open the new debug fp before closing the old. This means
+ if we run out of fd's we just keep using the old fd rather than aborting.
+ Fix from dgibson@linuxcare.com.
+**************************************************************************/
+
+static bool reopen_one_log(struct debug_class *config)
+{
+ int old_fd = config->fd;
+ const char *logfile = config->logfile;
+ struct stat st;
+ int new_fd;
+ int ret;
+
+ if (logfile == NULL) {
+ debug_close_fd(old_fd);
+ config->fd = -1;
+ return true;
+ }
+
+ new_fd = open(logfile, O_WRONLY|O_APPEND|O_CREAT, 0644);
+ if (new_fd == -1) {
+ log_overflow = true;
+ DBG_ERR("Unable to open new log file '%s': %s\n",
+ logfile, strerror(errno));
+ log_overflow = false;
+ return false;
+ }
+
+ debug_close_fd(old_fd);
+ smb_set_close_on_exec(new_fd);
+ config->fd = new_fd;
+
+ ret = fstat(new_fd, &st);
+ if (ret != 0) {
+ log_overflow = true;
+ DBG_ERR("Unable to fstat() new log file '%s': %s\n",
+ logfile, strerror(errno));
+ log_overflow = false;
+ return false;
+ }
+
+ config->ino = st.st_ino;
+ return true;
+}
+
+/**
+ reopen the log file (usually called because the log file name might have changed)
+*/
+bool reopen_logs_internal(void)
+{
+ struct debug_backend *b = NULL;
+ mode_t oldumask;
+ size_t i;
+ bool ok = true;
+
+ if (state.reopening_logs) {
+ return true;
+ }
+
+ /* Now clear the SIGHUP induced flag */
+ state.schedule_reopen_logs = false;
+
+ switch (state.logtype) {
+ case DEBUG_CALLBACK:
+ return true;
+ case DEBUG_STDOUT:
+ case DEBUG_DEFAULT_STDOUT:
+ debug_close_fd(dbgc_config[DBGC_ALL].fd);
+ dbgc_config[DBGC_ALL].fd = 1;
+ return true;
+
+ case DEBUG_DEFAULT_STDERR:
+ case DEBUG_STDERR:
+ debug_close_fd(dbgc_config[DBGC_ALL].fd);
+ dbgc_config[DBGC_ALL].fd = 2;
+ return true;
+
+ case DEBUG_FILE:
+ b = debug_find_backend("file");
+ assert(b != NULL);
+
+ b->log_level = MAX_DEBUG_LEVEL;
+ break;
+ }
+
+ oldumask = umask( 022 );
+
+ for (i = DBGC_ALL; i < debug_num_classes; i++) {
+ if (dbgc_config[i].logfile != NULL) {
+ break;
+ }
+ }
+ if (i == debug_num_classes) {
+ return false;
+ }
+
+ state.reopening_logs = true;
+
+ for (i = DBGC_ALL; i < debug_num_classes; i++) {
+ ok = reopen_one_log(&dbgc_config[i]);
+ if (!ok) {
+ break;
+ }
+ }
+
+ /* Fix from klausr@ITAP.Physik.Uni-Stuttgart.De
+ * to fix problem where smbd's that generate less
+ * than 100 messages keep growing the log.
+ */
+ force_check_log_size();
+ (void)umask(oldumask);
+
+ /*
+ * If log file was opened or created successfully, take over stderr to
+ * catch output into logs.
+ */
+ if (!state.settings.debug_no_stderr_redirect &&
+ dbgc_config[DBGC_ALL].fd > 0) {
+ if (dup2(dbgc_config[DBGC_ALL].fd, 2) == -1) {
+ /* Close stderr too, if dup2 can't point it -
+ at the logfile. There really isn't much
+ that can be done on such a fundamental
+ failure... */
+ close_low_fd(2);
+ }
+ }
+
+ state.reopening_logs = false;
+
+ return ok;
+}
+
+/**************************************************************************
+ Force a check of the log size.
+ ***************************************************************************/
+
+void force_check_log_size( void )
+{
+ debug_count = 100;
+}
+
+_PUBLIC_ void debug_schedule_reopen_logs(void)
+{
+ state.schedule_reopen_logs = true;
+}
+
+
+/***************************************************************************
+ Check to see if there is any need to check if the logfile has grown too big.
+**************************************************************************/
+
+bool need_to_check_log_size(void)
+{
+ int maxlog;
+ size_t i;
+
+ if (debug_count < 100) {
+ return false;
+ }
+
+ maxlog = state.settings.max_log_size * 1024;
+ if (maxlog <= 0) {
+ debug_count = 0;
+ return false;
+ }
+
+ if (dbgc_config[DBGC_ALL].fd > 2) {
+ return true;
+ }
+
+ for (i = DBGC_ALL + 1; i < debug_num_classes; i++) {
+ if (dbgc_config[i].fd != -1) {
+ return true;
+ }
+ }
+
+ debug_count = 0;
+ return false;
+}
+
+/**************************************************************************
+ Check to see if the log has grown to be too big.
+ **************************************************************************/
+
+static void do_one_check_log_size(off_t maxlog, struct debug_class *config)
+{
+ char name[strlen(config->logfile) + 5];
+ struct stat st;
+ int ret;
+ bool reopen = false;
+ bool ok;
+
+ if (maxlog == 0) {
+ return;
+ }
+
+ ret = stat(config->logfile, &st);
+ if (ret != 0) {
+ return;
+ }
+ if (st.st_size >= maxlog ) {
+ reopen = true;
+ }
+
+ if (st.st_ino != config->ino) {
+ reopen = true;
+ }
+
+ if (!reopen) {
+ return;
+ }
+
+ /* reopen_logs_internal() modifies *_fd */
+ (void)reopen_logs_internal();
+
+ if (config->fd <= 2) {
+ return;
+ }
+ ret = fstat(config->fd, &st);
+ if (ret != 0) {
+ config->ino = (ino_t)0;
+ return;
+ }
+
+ config->ino = st.st_ino;
+
+ if (st.st_size < maxlog) {
+ return;
+ }
+
+ snprintf(name, sizeof(name), "%s.old", config->logfile);
+
+ (void)rename(config->logfile, name);
+
+ ok = reopen_logs_internal();
+ if (ok) {
+ return;
+ }
+ /* We failed to reopen a log - continue using the old name. */
+ (void)rename(name, config->logfile);
+}
+
+static void do_check_log_size(off_t maxlog)
+{
+ size_t i;
+
+ for (i = DBGC_ALL; i < debug_num_classes; i++) {
+ if (dbgc_config[i].fd == -1) {
+ continue;
+ }
+ if (dbgc_config[i].logfile == NULL) {
+ continue;
+ }
+ do_one_check_log_size(maxlog, &dbgc_config[i]);
+ }
+}
+
+void check_log_size( void )
+{
+ off_t maxlog;
+
+ if (geteuid() != 0) {
+ /*
+ * We need to be root to change the log file (tests use a fake
+ * geteuid() from third_party/uid_wrapper). Otherwise we skip
+ * this and let the main smbd loop or some other process do
+ * the work.
+ */
+ return;
+ }
+
+ if(log_overflow || (!state.schedule_reopen_logs && !need_to_check_log_size())) {
+ return;
+ }
+
+ maxlog = state.settings.max_log_size * 1024;
+
+ if (state.schedule_reopen_logs) {
+ (void)reopen_logs_internal();
+ }
+
+ do_check_log_size(maxlog);
+
+ /*
+ * Here's where we need to panic if dbgc_config[DBGC_ALL].fd == 0 or -1
+ * (invalid values)
+ */
+
+ if (dbgc_config[DBGC_ALL].fd <= 0) {
+ /* This code should only be reached in very strange
+ * circumstances. If we merely fail to open the new log we
+ * should stick with the old one. ergo this should only be
+ * reached when opening the logs for the first time: at
+ * startup or when the log level is increased from zero.
+ * -dwg 6 June 2000
+ */
+ int fd = open( "/dev/console", O_WRONLY, 0);
+ if (fd != -1) {
+ smb_set_close_on_exec(fd);
+ dbgc_config[DBGC_ALL].fd = fd;
+ DBG_ERR("check_log_size: open of debug file %s failed "
+ "- using console.\n",
+ dbgc_config[DBGC_ALL].logfile);
+ } else {
+ /*
+ * We cannot continue without a debug file handle.
+ */
+ abort();
+ }
+ }
+ debug_count = 0;
+}
+
+/*************************************************************************
+ Write an debug message on the debugfile.
+ This is called by format_debug_text().
+************************************************************************/
+
+static void Debug1(const char *msg, size_t msg_len)
+{
+ int old_errno = errno;
+
+ debug_count++;
+
+ switch(state.logtype) {
+ case DEBUG_CALLBACK:
+ debug_callback_log(msg, msg_len, current_msg_level);
+ break;
+ case DEBUG_STDOUT:
+ case DEBUG_STDERR:
+ case DEBUG_DEFAULT_STDOUT:
+ case DEBUG_DEFAULT_STDERR:
+ if (state.settings.debug_syslog_format ==
+ DEBUG_SYSLOG_FORMAT_ALWAYS) {
+ debug_file_log(current_msg_level, msg, msg_len);
+ } else {
+ if (dbgc_config[DBGC_ALL].fd > 0) {
+ ssize_t ret;
+ do {
+ ret = write(dbgc_config[DBGC_ALL].fd,
+ msg,
+ msg_len);
+ } while (ret == -1 && errno == EINTR);
+ }
+ }
+ break;
+ case DEBUG_FILE:
+ debug_backends_log(msg, msg_len, current_msg_level);
+ break;
+ };
+
+ errno = old_errno;
+}
+
+/**************************************************************************
+ Print the buffer content via Debug1(), then reset the buffer.
+ Input: none
+ Output: none
+****************************************************************************/
+
+static void bufr_print( void )
+{
+ format_bufr[format_pos] = '\0';
+ (void)Debug1(format_bufr, format_pos);
+ format_pos = 0;
+}
+
+/*
+ * If set (by tevent_thread_call_depth_set()) to value > 0, debug code will use
+ * it for the trace indentation.
+ */
+static size_t debug_call_depth = 0;
+
+size_t *debug_call_depth_addr(void)
+{
+ return &debug_call_depth;
+}
+
+/***************************************************************************
+ Format the debug message text.
+
+ Input: msg - Text to be added to the "current" debug message text.
+
+ Output: none.
+
+ Notes: The purpose of this is two-fold. First, each call to syslog()
+ (used by Debug1(), see above) generates a new line of syslog
+ output. This is fixed by storing the partial lines until the
+ newline character is encountered. Second, printing the debug
+ message lines when a newline is encountered allows us to add
+ spaces, thus indenting the body of the message and making it
+ more readable.
+**************************************************************************/
+
+static void format_debug_text( const char *msg )
+{
+ size_t i;
+ bool timestamp = (state.logtype == DEBUG_FILE && (state.settings.timestamp_logs));
+
+ debug_init();
+
+ for( i = 0; msg[i]; i++ ) {
+ /* Indent two spaces at each new line. */
+ if(timestamp && 0 == format_pos) {
+ /* Limit the maximum indentation to 20 levels */
+ size_t depth = MIN(20, debug_call_depth);
+ format_bufr[0] = format_bufr[1] = ' ';
+ format_pos = 2;
+ /*
+ * Indent by four spaces for each depth level,
+ * but only if the current debug level is >= 8.
+ */
+ if (depth > 0 && debuglevel_get() >= 8 &&
+ format_pos + 4 * depth < FORMAT_BUFR_SIZE) {
+ memset(&format_bufr[format_pos],
+ ' ',
+ 4 * depth);
+ format_pos += 4 * depth;
+ }
+ }
+
+ /* If there's room, copy the character to the format buffer. */
+ if (format_pos < FORMAT_BUFR_SIZE - 1)
+ format_bufr[format_pos++] = msg[i];
+
+ /* If a newline is encountered, print & restart. */
+ if( '\n' == msg[i] )
+ bufr_print();
+
+ /* If the buffer is full dump it out, reset it, and put out a line
+ * continuation indicator.
+ */
+ if (format_pos >= FORMAT_BUFR_SIZE - 1) {
+ const char cont[] = " +>\n";
+ bufr_print();
+ (void)Debug1(cont , sizeof(cont) - 1);
+ }
+ }
+
+ /* Just to be safe... */
+ format_bufr[format_pos] = '\0';
+}
+
+/***************************************************************************
+ Flush debug output, including the format buffer content.
+
+ Input: none
+ Output: none
+***************************************************************************/
+
+void dbgflush( void )
+{
+ bufr_print();
+}
+
+bool dbgsetclass(int level, int cls)
+{
+ /* Set current_msg_level. */
+ current_msg_level = level;
+
+ /* Set current message class */
+ current_msg_class = cls;
+
+ return true;
+}
+
+/***************************************************************************
+ Put a Debug Header into header_str.
+
+ Input: level - Debug level of the message (not the system-wide debug
+ level. )
+ cls - Debuglevel class of the calling module.
+ location - Pointer to a string containing the name of the file
+ from which this function was called, or an empty string
+ if the __FILE__ macro is not implemented.
+ func - Pointer to a string containing the name of the function
+ from which this function was called, or an empty string
+ if the __FUNCTION__ macro is not implemented.
+
+ Output: Always true. This makes it easy to fudge a call to dbghdr()
+ in a macro, since the function can be called as part of a test.
+ Eg: ( (level <= DEBUGLEVEL) && (dbghdr(level,"",line)) )
+
+ Notes: This function takes care of setting current_msg_level.
+
+****************************************************************************/
+
+bool dbghdrclass(int level, int cls, const char *location, const char *func)
+{
+ /* Ensure we don't lose any real errno value. */
+ int old_errno = errno;
+ bool verbose = false;
+ struct timeval tv;
+ struct timeval_buf tvbuf;
+
+ /*
+ * This might be overkill, but if another early return is
+ * added later then initialising these avoids potential
+ * problems
+ */
+ state.hs_len = 0;
+ state.header_str[0] = '\0';
+
+ if( format_pos ) {
+ /* This is a fudge. If there is stuff sitting in the format_bufr, then
+ * the *right* thing to do is to call
+ * format_debug_text( "\n" );
+ * to write the remainder, and then proceed with the new header.
+ * Unfortunately, there are several places in the code at which
+ * the DEBUG() macro is used to build partial lines. That in mind,
+ * we'll work under the assumption that an incomplete line indicates
+ * that a new header is *not* desired.
+ */
+ return( true );
+ }
+
+ dbgsetclass(level, cls);
+
+ /*
+ * Don't print a header if we're logging to stdout,
+ * unless 'debug syslog format = always'
+ */
+ if (state.logtype != DEBUG_FILE &&
+ state.settings.debug_syslog_format != DEBUG_SYSLOG_FORMAT_ALWAYS)
+ {
+ return true;
+ }
+
+ /*
+ * Print the header if timestamps (or debug syslog format) is
+ * turned on. If parameters are not yet loaded, then default
+ * to timestamps on.
+ */
+ if (!(state.settings.timestamp_logs ||
+ state.settings.debug_prefix_timestamp ||
+ state.settings.debug_syslog_format != DEBUG_SYSLOG_FORMAT_NO))
+ {
+ return true;
+ }
+
+ GetTimeOfDay(&tv);
+
+ if (state.settings.debug_syslog_format != DEBUG_SYSLOG_FORMAT_NO) {
+ if (state.settings.debug_hires_timestamp) {
+ timeval_str_buf(&tv, true, true, &tvbuf);
+ } else {
+ time_t t;
+ struct tm *tm;
+
+ t = (time_t)tv.tv_sec;
+ tm = localtime(&t);
+ if (tm != NULL) {
+ size_t len;
+ len = strftime(tvbuf.buf,
+ sizeof(tvbuf.buf),
+ "%b %e %T",
+ tm);
+ if (len == 0) {
+ /* Trigger default time format below */
+ tm = NULL;
+ }
+ }
+ if (tm == NULL) {
+ snprintf(tvbuf.buf,
+ sizeof(tvbuf.buf),
+ "%ld seconds since the Epoch", (long)t);
+ }
+ }
+
+ ensure_hostname();
+ state.hs_len = snprintf(state.header_str,
+ sizeof(state.header_str),
+ "%s %.*s %s[%u]: ",
+ tvbuf.buf,
+ (int)(sizeof(state.hostname) - 1),
+ state.hostname,
+ state.prog_name,
+ (unsigned int) getpid());
+
+ goto full;
+ }
+
+ timeval_str_buf(&tv, false, state.settings.debug_hires_timestamp,
+ &tvbuf);
+
+ state.hs_len = snprintf(state.header_str,
+ sizeof(state.header_str),
+ "[%s, %2d",
+ tvbuf.buf,
+ level);
+ if (state.hs_len >= sizeof(state.header_str) - 1) {
+ goto full;
+ }
+
+ if (unlikely(dbgc_config[cls].loglevel >= 10)) {
+ verbose = true;
+ }
+
+ if (verbose || state.settings.debug_pid) {
+ state.hs_len += snprintf(state.header_str + state.hs_len,
+ sizeof(state.header_str) - state.hs_len,
+ ", pid=%u",
+ (unsigned int)getpid());
+ if (state.hs_len >= sizeof(state.header_str) - 1) {
+ goto full;
+ }
+ }
+
+ if (verbose || state.settings.debug_uid) {
+ state.hs_len += snprintf(state.header_str + state.hs_len,
+ sizeof(state.header_str) - state.hs_len,
+ ", effective(%u, %u), real(%u, %u)",
+ (unsigned int)geteuid(),
+ (unsigned int)getegid(),
+ (unsigned int)getuid(),
+ (unsigned int)getgid());
+ if (state.hs_len >= sizeof(state.header_str) - 1) {
+ goto full;
+ }
+ }
+
+ if ((verbose || state.settings.debug_class)
+ && (cls != DBGC_ALL)) {
+ state.hs_len += snprintf(state.header_str + state.hs_len,
+ sizeof(state.header_str) - state.hs_len,
+ ", class=%s",
+ classname_table[cls]);
+ if (state.hs_len >= sizeof(state.header_str) - 1) {
+ goto full;
+ }
+ }
+
+ if (debug_traceid_get() != 0) {
+ state.hs_len += snprintf(state.header_str + state.hs_len,
+ sizeof(state.header_str) - state.hs_len,
+ ", traceid=%" PRIu64,
+ debug_traceid_get());
+ if (state.hs_len >= sizeof(state.header_str) - 1) {
+ goto full;
+ }
+ }
+
+ if (debug_call_depth > 0) {
+ state.hs_len += snprintf(state.header_str + state.hs_len,
+ sizeof(state.header_str) - state.hs_len,
+ ", depth=%zu",
+ debug_call_depth);
+ if (state.hs_len >= sizeof(state.header_str) - 1) {
+ goto full;
+ }
+ }
+
+ state.header_str[state.hs_len] = ']';
+ state.hs_len++;
+ if (state.hs_len < sizeof(state.header_str) - 1) {
+ state.header_str[state.hs_len] = ' ';
+ state.hs_len++;
+ }
+ state.header_str[state.hs_len] = '\0';
+
+ if (!state.settings.debug_prefix_timestamp) {
+ state.hs_len += snprintf(state.header_str + state.hs_len,
+ sizeof(state.header_str) - state.hs_len,
+ "%s(%s)\n",
+ location,
+ func);
+ if (state.hs_len >= sizeof(state.header_str)) {
+ goto full;
+ }
+ }
+
+full:
+ /*
+ * Above code never overflows state.header_str and always
+ * NUL-terminates correctly. However, state.hs_len can point
+ * past the end of the buffer to indicate that truncation
+ * occurred, so fix it if necessary, since state.hs_len is
+ * expected to be used after return.
+ */
+ if (state.hs_len >= sizeof(state.header_str)) {
+ state.hs_len = sizeof(state.header_str) - 1;
+ }
+
+ errno = old_errno;
+ return( true );
+}
+
+/***************************************************************************
+ Add text to the body of the "current" debug message via the format buffer.
+
+ Input: format_str - Format string, as used in printf(), et. al.
+ ... - Variable argument list.
+
+ ..or.. va_alist - Old style variable parameter list starting point.
+
+ Output: Always true. See dbghdr() for more info, though this is not
+ likely to be used in the same way.
+
+***************************************************************************/
+
+static inline bool __dbgtext_va(const char *format_str, va_list ap) PRINTF_ATTRIBUTE(1,0);
+static inline bool __dbgtext_va(const char *format_str, va_list ap)
+{
+ char *msgbuf = NULL;
+ bool ret = true;
+ int res;
+
+ res = vasprintf(&msgbuf, format_str, ap);
+ if (res != -1) {
+ format_debug_text(msgbuf);
+ } else {
+ ret = false;
+ }
+ SAFE_FREE(msgbuf);
+ return ret;
+}
+
+bool dbgtext_va(const char *format_str, va_list ap)
+{
+ return __dbgtext_va(format_str, ap);
+}
+
+bool dbgtext(const char *format_str, ... )
+{
+ va_list ap;
+ bool ret;
+
+ va_start(ap, format_str);
+ ret = __dbgtext_va(format_str, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+static uint64_t debug_traceid = 0;
+
+uint64_t debug_traceid_set(uint64_t id)
+{
+ uint64_t old_id = debug_traceid;
+ debug_traceid = id;
+ return old_id;
+}
+
+uint64_t debug_traceid_get(void)
+{
+ return debug_traceid;
+}
diff --git a/lib/util/debug.h b/lib/util/debug.h
new file mode 100644
index 0000000..4687ac0
--- /dev/null
+++ b/lib/util/debug.h
@@ -0,0 +1,396 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB debug stuff
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) John H Terpstra 1996-1998
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1998
+ Copyright (C) Paul Ashton 1998
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_DEBUG_H
+#define _SAMBA_DEBUG_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdarg.h>
+#include "attr.h"
+
+
+/* -------------------------------------------------------------------------- **
+ * Debugging code. See also debug.c
+ */
+
+/* the maximum debug level to compile into the code. This assumes a good
+ optimising compiler that can remove unused code
+ for embedded or low-memory systems set this to a value like 2 to get
+ only important messages. This gives *much* smaller binaries
+*/
+#ifndef MAX_DEBUG_LEVEL
+#define MAX_DEBUG_LEVEL 1000
+#endif
+
+bool dbgtext_va(const char *, va_list ap) PRINTF_ATTRIBUTE(1,0);
+bool dbgtext( const char *, ... ) PRINTF_ATTRIBUTE(1,2);
+bool dbghdrclass( int level, int cls, const char *location, const char *func);
+bool dbgsetclass(int level, int cls);
+
+/*
+ * Define all new debug classes here. A class is represented by an entry in
+ * the DEBUGLEVEL_CLASS array. Index zero of this array is equivalent to the
+ * old DEBUGLEVEL. Any source file that does NOT add the following lines:
+ *
+ * #undef DBGC_CLASS
+ * #define DBGC_CLASS DBGC_<your class name here>
+ *
+ * at the start of the file (after #include "includes.h") will default to
+ * using index zero, so it will behave just like it always has.
+ */
+#define DBGC_ALL 0 /* index equivalent to DEBUGLEVEL */
+
+#define DBGC_TDB 1
+#define DBGC_PRINTDRIVERS 2
+#define DBGC_LANMAN 3
+#define DBGC_SMB 4
+#define DBGC_RPC_PARSE 5
+#define DBGC_RPC_SRV 6
+#define DBGC_RPC_CLI 7
+#define DBGC_PASSDB 8
+#define DBGC_SAM 9
+#define DBGC_AUTH 10
+#define DBGC_WINBIND 11
+#define DBGC_VFS 12
+#define DBGC_IDMAP 13
+#define DBGC_QUOTA 14
+#define DBGC_ACLS 15
+#define DBGC_LOCKING 16
+#define DBGC_MSDFS 17
+#define DBGC_DMAPI 18
+#define DBGC_REGISTRY 19
+#define DBGC_SCAVENGER 20
+#define DBGC_DNS 21
+#define DBGC_LDB 22
+#define DBGC_TEVENT 23
+#define DBGC_AUTH_AUDIT 24
+#define DBGC_AUTH_AUDIT_JSON 25
+#define DBGC_KERBEROS 26
+#define DBGC_DRS_REPL 27
+#define DBGC_SMB2 28
+#define DBGC_SMB2_CREDITS 29
+#define DBGC_DSDB_AUDIT 30
+#define DBGC_DSDB_AUDIT_JSON 31
+#define DBGC_DSDB_PWD_AUDIT 32
+#define DBGC_DSDB_PWD_AUDIT_JSON 33
+#define DBGC_DSDB_TXN_AUDIT 34
+#define DBGC_DSDB_TXN_AUDIT_JSON 35
+#define DBGC_DSDB_GROUP_AUDIT 36
+#define DBGC_DSDB_GROUP_AUDIT_JSON 37
+
+/* So you can define DBGC_CLASS before including debug.h */
+#ifndef DBGC_CLASS
+#define DBGC_CLASS 0 /* override as shown above */
+#endif
+
+#define DEBUGLEVEL debuglevel_get()
+
+#define debuglevel_get() debuglevel_get_class(DBGC_ALL)
+#define debuglevel_set(lvl) debuglevel_set_class(DBGC_ALL, (lvl))
+
+/* Debugging macros
+ *
+ * DEBUGLVL()
+ * If the 'file specific' debug class level >= level OR the system-wide
+ * DEBUGLEVEL (synonym for DEBUGLEVEL_CLASS[ DBGC_ALL ]) >= level then
+ * generate a header using the default macros for file, line, and
+ * function name. Returns True if the debug level was <= DEBUGLEVEL.
+ *
+ * Example: if( DEBUGLVL( 2 ) ) dbgtext( "Some text.\n" );
+ *
+ * DEBUG()
+ * If the 'file specific' debug class level >= level OR the system-wide
+ * DEBUGLEVEL (synonym for DEBUGLEVEL_CLASS[ DBGC_ALL ]) >= level then
+ * generate a header using the default macros for file, line, and
+ * function name. Each call to DEBUG() generates a new header *unless* the
+ * previous debug output was unterminated (i.e. no '\n').
+ * See debug.c:dbghdr() for more info.
+ *
+ * Example: DEBUG( 2, ("Some text and a value %d.\n", value) );
+ *
+ * DEBUGC()
+ * If the 'macro specified' debug class level >= level OR the system-wide
+ * DEBUGLEVEL (synonym for DEBUGLEVEL_CLASS[ DBGC_ALL ]) >= level then
+ * generate a header using the default macros for file, line, and
+ * function name. Each call to DEBUG() generates a new header *unless* the
+ * previous debug output was unterminated (i.e. no '\n').
+ * See debug.c:dbghdr() for more info.
+ *
+ * Example: DEBUGC( DBGC_TDB, 2, ("Some text and a value %d.\n", value) );
+ *
+ * DEBUGADD(), DEBUGADDC()
+ * Same as DEBUG() and DEBUGC() except the text is appended to the previous
+ * DEBUG(), DEBUGC(), DEBUGADD(), DEBUGADDC() with out another interviening
+ * header.
+ *
+ * Example: DEBUGADD( 2, ("Some text and a value %d.\n", value) );
+ * DEBUGADDC( DBGC_TDB, 2, ("Some text and a value %d.\n", value) );
+ *
+ * Note: If the debug class has not be redefined (see above) then the optimizer
+ * will remove the extra conditional test.
+ */
+
+/*
+ * From talloc.c:
+ */
+
+/* these macros gain us a few percent of speed on gcc */
+#if (__GNUC__ >= 3)
+/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
+ as its first argument */
+#ifndef likely
+#define likely(x) __builtin_expect(!!(x), 1)
+#endif
+#ifndef unlikely
+#define unlikely(x) __builtin_expect(!!(x), 0)
+#endif
+#else
+#ifndef likely
+#define likely(x) (x)
+#endif
+#ifndef unlikely
+#define unlikely(x) (x)
+#endif
+#endif
+
+int debuglevel_get_class(size_t idx);
+void debuglevel_set_class(size_t idx, int level);
+
+#define CHECK_DEBUGLVL( level ) \
+ ( ((level) <= MAX_DEBUG_LEVEL) && \
+ unlikely(debuglevel_get_class(DBGC_CLASS) >= (level)))
+
+#define CHECK_DEBUGLVLC( dbgc_class, level ) \
+ ( ((level) <= MAX_DEBUG_LEVEL) && \
+ unlikely(debuglevel_get_class(dbgc_class) >= (level)))
+
+#define DEBUGLVL( level ) \
+ ( CHECK_DEBUGLVL(level) \
+ && dbghdrclass( level, DBGC_CLASS, __location__, __FUNCTION__ ) )
+
+#define DEBUGLVLC( dbgc_class, level ) \
+ ( CHECK_DEBUGLVLC( dbgc_class, level ) \
+ && dbghdrclass( level, dbgc_class, __location__, __FUNCTION__ ) )
+
+#define DEBUG( level, body ) \
+ (void)( ((level) <= MAX_DEBUG_LEVEL) && \
+ unlikely(debuglevel_get_class(DBGC_CLASS) >= (level)) \
+ && (dbghdrclass( level, DBGC_CLASS, __location__, __FUNCTION__ )) \
+ && (dbgtext body) )
+
+/**
+ * @brief DEBUGLF is same as DEBUG with explicit location and function arguments
+ *
+ * To be used when passing location and function of a caller appearing earlier in
+ * the call stack instead of some helper function.
+ *
+ * @code
+ * DEBUGLF( 2, ("Some text.\n"), "foo.c:1", "foo" );
+ * DEBUGLF( 5, ("Some text.\n"), location, function );
+ * @endcode
+ *
+ * @return void.
+ */
+#define DEBUGLF( level, body, location, function ) \
+ (void)( ((level) <= MAX_DEBUG_LEVEL) && \
+ unlikely(debuglevel_get_class(DBGC_CLASS) >= (level)) \
+ && (dbghdrclass( level, DBGC_CLASS, location, function )) \
+ && (dbgtext body) )
+
+#define DEBUGC( dbgc_class, level, body ) \
+ (void)( ((level) <= MAX_DEBUG_LEVEL) && \
+ unlikely(debuglevel_get_class(dbgc_class) >= (level)) \
+ && (dbghdrclass( level, dbgc_class, __location__, __FUNCTION__ )) \
+ && (dbgtext body) )
+
+#define DEBUGADD( level, body ) \
+ (void)( ((level) <= MAX_DEBUG_LEVEL) && \
+ unlikely(debuglevel_get_class(DBGC_CLASS) >= (level)) \
+ && (dbgsetclass(level, DBGC_CLASS)) \
+ && (dbgtext body) )
+
+#define DEBUGADDC( dbgc_class, level, body ) \
+ (void)( ((level) <= MAX_DEBUG_LEVEL) && \
+ unlikely((debuglevel_get_class(dbgc_class) >= (level))) \
+ && (dbgsetclass(level, dbgc_class)) \
+ && (dbgtext body) )
+
+/* Print a separator to the debug log. */
+#define DEBUGSEP(level)\
+ DEBUG((level),("===============================================================\n"))
+
+/* Prefix messages with the function name */
+#define DBG_PREFIX(level, body ) \
+ (void)( ((level) <= MAX_DEBUG_LEVEL) && \
+ unlikely(debuglevel_get_class(DBGC_CLASS) >= (level)) \
+ && (dbghdrclass(level, DBGC_CLASS, __location__, __func__ )) \
+ && (dbgtext("%s: ", __func__)) \
+ && (dbgtext body) )
+
+/* Prefix messages with the function name - class specific */
+#define DBGC_PREFIX(dbgc_class, level, body ) \
+ (void)( ((level) <= MAX_DEBUG_LEVEL) && \
+ unlikely(debuglevel_get_class(dbgc_class) >= (level)) \
+ && (dbghdrclass(level, dbgc_class, __location__, __func__ )) \
+ && (dbgtext("%s: ", __func__)) \
+ && (dbgtext body) )
+
+
+#ifdef DEVELOPER
+#define DBG_DEV(...) \
+ (void)( (debug_developer_enabled()) \
+ && (dbgtext("%s:DEV:%d: ", __func__, getpid())) \
+ && (dbgtext(__VA_ARGS__)) )
+#else
+#define DBG_DEV(...) /* DBG_DEV was here */
+#endif
+
+/*
+ * Debug levels matching RFC 3164
+ */
+#define DBGLVL_ERR 0 /* error conditions */
+#define DBGLVL_WARNING 1 /* warning conditions */
+#define DBGLVL_NOTICE 3 /* normal, but significant, condition */
+#define DBGLVL_INFO 5 /* informational message */
+#define DBGLVL_DEBUG 10 /* debug-level message */
+
+#define DBG_STARTUP_NOTICE(...) do { \
+ debug_set_forced_log_priority(DBGLVL_NOTICE); \
+ D_ERR(__VA_ARGS__); \
+ debug_set_forced_log_priority(-1); \
+} while(0)
+
+#define DBG_ERR(...) DBG_PREFIX(DBGLVL_ERR, (__VA_ARGS__))
+#define DBG_WARNING(...) DBG_PREFIX(DBGLVL_WARNING, (__VA_ARGS__))
+#define DBG_NOTICE(...) DBG_PREFIX(DBGLVL_NOTICE, (__VA_ARGS__))
+#define DBG_INFO(...) DBG_PREFIX(DBGLVL_INFO, (__VA_ARGS__))
+#define DBG_DEBUG(...) DBG_PREFIX(DBGLVL_DEBUG, (__VA_ARGS__))
+
+#define DBGC_ERR(dbgc_class, ...) DBGC_PREFIX(dbgc_class, \
+ DBGLVL_ERR, (__VA_ARGS__))
+#define DBGC_WARNING(dbgc_class, ...) DBGC_PREFIX(dbgc_class, \
+ DBGLVL_WARNING, (__VA_ARGS__))
+#define DBGC_NOTICE(dbgc_class, ...) DBGC_PREFIX(dbgc_class, \
+ DBGLVL_NOTICE, (__VA_ARGS__))
+#define DBGC_INFO(dbgc_class, ...) DBGC_PREFIX(dbgc_class, \
+ DBGLVL_INFO, (__VA_ARGS__))
+#define DBGC_DEBUG(dbgc_class, ...) DBGC_PREFIX(dbgc_class, \
+ DBGLVL_DEBUG, (__VA_ARGS__))
+
+#define D_ERR(...) DEBUG(DBGLVL_ERR, (__VA_ARGS__))
+#define D_WARNING(...) DEBUG(DBGLVL_WARNING, (__VA_ARGS__))
+#define D_NOTICE(...) DEBUG(DBGLVL_NOTICE, (__VA_ARGS__))
+#define D_INFO(...) DEBUG(DBGLVL_INFO, (__VA_ARGS__))
+#define D_DEBUG(...) DEBUG(DBGLVL_DEBUG, (__VA_ARGS__))
+
+#define DC_ERR(...) DEBUGC(dbgc_class, \
+ DBGLVL_ERR, (__VA_ARGS__))
+#define DC_WARNING(...) DEBUGC(dbgc_class, \
+ DBGLVL_WARNING, (__VA_ARGS__))
+#define DC_NOTICE(...) DEBUGC(dbgc_class, \
+ DBGLVL_NOTICE, (__VA_ARGS__))
+#define DC_INFO(...) DEBUGC(dbgc_class, \
+ DBGLVL_INFO, (__VA_ARGS__))
+#define DC_DEBUG(...) DEBUGC(dbgc_class, \
+ DBGLVL_DEBUG, (__VA_ARGS__))
+
+/* The following definitions come from lib/debug.c */
+
+/**
+ * Possible destinations for the debug log.
+ *
+ * Set via setup_logging(); higher values have precedence.
+ */
+enum debug_logtype {
+ DEBUG_DEFAULT_STDERR = 0,
+ DEBUG_DEFAULT_STDOUT = 1,
+ DEBUG_FILE = 2,
+ DEBUG_STDOUT = 3,
+ DEBUG_STDERR = 4,
+ DEBUG_CALLBACK = 5
+};
+
+enum debug_syslog_format {
+ DEBUG_SYSLOG_FORMAT_NO = 0,
+ DEBUG_SYSLOG_FORMAT_IN_LOGS = 1,
+ DEBUG_SYSLOG_FORMAT_ALWAYS = 2,
+};
+
+struct debug_settings {
+ size_t max_log_size;
+ bool timestamp_logs;
+ bool debug_prefix_timestamp;
+ bool debug_hires_timestamp;
+ enum debug_syslog_format debug_syslog_format;
+ bool debug_pid;
+ bool debug_uid;
+ bool debug_class;
+ bool debug_no_stderr_redirect;
+};
+
+void setup_logging(const char *prog_name, enum debug_logtype new_logtype);
+
+void gfree_debugsyms(void);
+int debug_add_class(const char *classname);
+bool debug_parse_levels(const char *params_str);
+void debug_setup_talloc_log(void);
+void debug_set_logfile(const char *name);
+void debug_set_settings(struct debug_settings *settings,
+ const char *logging_param,
+ int syslog_level, bool syslog_only);
+void debug_set_hostname(const char *name);
+void debug_set_forced_log_priority(int forced_log_priority);
+bool reopen_logs_internal( void );
+void force_check_log_size( void );
+bool need_to_check_log_size( void );
+void check_log_size( void );
+void dbgflush( void );
+enum debug_logtype debug_get_log_type(void);
+bool debug_get_output_is_stderr(void);
+bool debug_get_output_is_stdout(void);
+void debug_schedule_reopen_logs(void);
+char *debug_list_class_names_and_levels(void);
+bool debug_developer_enabled(void);
+void debug_developer_enable(void);
+void debug_developer_disable(void);
+
+typedef void (*debug_callback_fn)(void *private_ptr, int level, const char *msg);
+
+/**
+ Set a callback for all debug messages. Use in dlz_bind9 to push output to the bind logs
+ */
+void debug_set_callback(void *private_ptr, debug_callback_fn fn);
+
+char *debug_get_ringbuf(void);
+size_t debug_get_ringbuf_size(void);
+
+/* Explicitly set new traceid. The old id is returned. */
+uint64_t debug_traceid_set(uint64_t id);
+
+/* Get the current traceid. */
+uint64_t debug_traceid_get(void);
+
+size_t *debug_call_depth_addr(void);
+
+#endif /* _SAMBA_DEBUG_H */
diff --git a/lib/util/debug_s3.c b/lib/util/debug_s3.c
new file mode 100644
index 0000000..1fd8637
--- /dev/null
+++ b/lib/util/debug_s3.c
@@ -0,0 +1,155 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Bartlett 2011
+ Copyright (C) Andrew Tridgell 1992-2002
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "lib/util/server_id.h"
+#include "librpc/gen_ndr/messaging.h"
+#include "messages.h"
+#include "lib/util/memory.h"
+
+/* This is the Samba3-specific implementation of reopen_logs(), which
+ * calls out to the s3 loadparm code, and means that we don't depend
+ * on loadparm directly. */
+
+bool reopen_logs(void)
+{
+ if (lp_loaded()) {
+ struct debug_settings settings = {
+ .max_log_size = lp_max_log_size(),
+ .timestamp_logs = lp_timestamp_logs(),
+ .debug_prefix_timestamp = lp_debug_prefix_timestamp(),
+ .debug_hires_timestamp = lp_debug_hires_timestamp(),
+ .debug_syslog_format = lp_debug_syslog_format(),
+ .debug_pid = lp_debug_pid(),
+ .debug_uid = lp_debug_uid(),
+ .debug_class = lp_debug_class(),
+ };
+ const struct loadparm_substitution *lp_sub =
+ loadparm_s3_global_substitution();
+
+ debug_set_logfile(lp_logfile(talloc_tos(), lp_sub));
+ debug_parse_levels(lp_log_level(talloc_tos(), lp_sub));
+ debug_set_settings(&settings,
+ lp_logging(talloc_tos(), lp_sub),
+ lp_syslog(),
+ lp_syslog_only());
+ } else {
+ /*
+ * Parameters are not yet loaded - configure debugging with
+ * reasonable defaults to enable logging for early
+ * startup failures.
+ */
+ struct debug_settings settings = {
+ .max_log_size = 5000,
+ .timestamp_logs = true,
+ .debug_prefix_timestamp = false,
+ .debug_hires_timestamp = true,
+ .debug_syslog_format = false,
+ .debug_pid = false,
+ .debug_uid = false,
+ .debug_class = false,
+ };
+ debug_set_settings(&settings,
+ "file",
+ 1,
+ false);
+ }
+ return reopen_logs_internal();
+}
+
+/****************************************************************************
+ Receive a "set debug level" message.
+****************************************************************************/
+
+void debug_message(struct messaging_context *msg_ctx,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id src,
+ DATA_BLOB *data)
+{
+ const char *params_str = (const char *)data->data;
+
+ /* Check, it's a proper string! */
+ if (params_str[(data->length)-1] != '\0') {
+ DEBUG(1, ("Invalid debug message from pid %u to pid %u\n",
+ (unsigned int)procid_to_pid(&src),
+ (unsigned int)getpid()));
+ return;
+ }
+
+ DEBUG(3, ("INFO: Remote set of debug to `%s' (pid %u from pid %u)\n",
+ params_str, (unsigned int)getpid(),
+ (unsigned int)procid_to_pid(&src)));
+
+ debug_parse_levels(params_str);
+}
+
+/****************************************************************************
+ Return current debug level.
+****************************************************************************/
+
+static void debuglevel_message(struct messaging_context *msg_ctx,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id src,
+ DATA_BLOB *data)
+{
+ char *message = debug_list_class_names_and_levels();
+ struct server_id_buf tmp;
+
+ if (!message) {
+ DEBUG(0,("debuglevel_message - debug_list_class_names_and_levels returned NULL\n"));
+ return;
+ }
+
+ DEBUG(1, ("INFO: Received REQ_DEBUGLEVEL message from PID %s\n",
+ server_id_str_buf(src, &tmp)));
+ messaging_send_buf(msg_ctx, src, MSG_DEBUGLEVEL,
+ (uint8_t *)message, strlen(message) + 1);
+
+ TALLOC_FREE(message);
+}
+
+static void debug_ringbuf_log(struct messaging_context *msg_ctx,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id src,
+ DATA_BLOB *data)
+{
+ char *log = debug_get_ringbuf();
+ size_t logsize = debug_get_ringbuf_size();
+
+ if (log == NULL) {
+ log = discard_const_p(char, "*disabled*\n");
+ logsize = strlen(log) + 1;
+ }
+
+ messaging_send_buf(msg_ctx, src, MSG_RINGBUF_LOG, (uint8_t *)log,
+ logsize);
+}
+
+void debug_register_msgs(struct messaging_context *msg_ctx)
+{
+ messaging_register(msg_ctx, NULL, MSG_DEBUG, debug_message);
+ messaging_register(msg_ctx, NULL, MSG_REQ_DEBUGLEVEL,
+ debuglevel_message);
+ messaging_register(msg_ctx, NULL, MSG_REQ_RINGBUF_LOG,
+ debug_ringbuf_log);
+}
diff --git a/lib/util/debug_s3.h b/lib/util/debug_s3.h
new file mode 100644
index 0000000..9e5211b
--- /dev/null
+++ b/lib/util/debug_s3.h
@@ -0,0 +1,26 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB debug stuff
+ Copyright (C) Andrew Tridgell 2002
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "librpc/gen_ndr/server_id.h"
+
+struct messaging_context;
+struct server_id;
+void debug_message(struct messaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data);
+void debug_register_msgs(struct messaging_context *msg_ctx);
+bool reopen_logs( void );
diff --git a/lib/util/discard.h b/lib/util/discard.h
new file mode 100644
index 0000000..d2b74ac
--- /dev/null
+++ b/lib/util/discard.h
@@ -0,0 +1,51 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_DISCARD_H_
+#define _SAMBA_DISCARD_H_
+
+/**
+ this is a warning hack. The idea is to use this everywhere that we
+ get the "discarding const" warning from gcc. That doesn't actually
+ fix the problem of course, but it means that when we do get to
+ cleaning them up we can do it by searching the code for
+ discard_const.
+
+ It also means that other error types aren't as swamped by the noise
+ of hundreds of const warnings, so we are more likely to notice when
+ we get new errors.
+
+ Please only add more uses of this macro when you find it
+ _really_ hard to fix const warnings. Our aim is to eventually use
+ this function in only a very few places.
+
+ Also, please call this via the discard_const_p() macro interface, as that
+ makes the return type safe.
+*/
+#ifndef discard_const
+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
+#endif
+
+/** Type-safe version of discard_const */
+#ifndef discard_const_p
+#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
+#endif
+
+#endif /* _SAMBA_DISCARD_H_ */
diff --git a/lib/util/dlinklist.h b/lib/util/dlinklist.h
new file mode 100644
index 0000000..49a135a
--- /dev/null
+++ b/lib/util/dlinklist.h
@@ -0,0 +1,198 @@
+/*
+ Unix SMB/CIFS implementation.
+ some simple double linked list macros
+
+ Copyright (C) Andrew Tridgell 1998-2010
+
+ ** NOTE! The following LGPL license applies to this file (*dlinklist.h).
+ ** This does NOT imply that all of Samba is released under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* To use these macros you must have a structure containing a next and
+ prev pointer */
+
+#ifndef _DLINKLIST_H
+#define _DLINKLIST_H
+
+/*
+ February 2010 - changed list format to have a prev pointer from the
+ list head. This makes DLIST_ADD_END() O(1) even though we only have
+ one list pointer.
+
+ The scheme is as follows:
+
+ 1) with no entries in the list:
+ list_head == NULL
+
+ 2) with 1 entry in the list:
+ list_head->next == NULL
+ list_head->prev == list_head
+
+ 3) with 2 entries in the list:
+ list_head->next == element2
+ list_head->prev == element2
+ element2->prev == list_head
+ element2->next == NULL
+
+ 4) with N entries in the list:
+ list_head->next == element2
+ list_head->prev == elementN
+ elementN->prev == element{N-1}
+ elementN->next == NULL
+
+ This allows us to find the tail of the list by using
+ list_head->prev, which means we can add to the end of the list in
+ O(1) time
+ */
+
+
+/*
+ add an element at the front of a list
+*/
+#define DLIST_ADD(list, p) \
+do { \
+ if (!(list)) { \
+ (p)->prev = (list) = (p); \
+ (p)->next = NULL; \
+ } else { \
+ (p)->prev = (list)->prev; \
+ (list)->prev = (p); \
+ (p)->next = (list); \
+ (list) = (p); \
+ } \
+} while (0)
+
+/*
+ remove an element from a list
+ Note that the element doesn't have to be in the list. If it
+ isn't then this is a no-op
+*/
+#define DLIST_REMOVE(list, p) \
+do { \
+ if ((p) == (list)) { \
+ if ((p)->next) (p)->next->prev = (p)->prev; \
+ (list) = (p)->next; \
+ } else if ((p)->prev && (list) && (p) == (list)->prev) { \
+ (p)->prev->next = NULL; \
+ (list)->prev = (p)->prev; \
+ } else { \
+ if ((p)->prev) (p)->prev->next = (p)->next; \
+ if ((p)->next) (p)->next->prev = (p)->prev; \
+ } \
+ if ((p) != (list)) (p)->next = (p)->prev = NULL; \
+} while (0)
+
+/*
+ find the head of the list given any element in it.
+ Note that this costs O(N), so you should avoid this macro
+ if at all possible!
+*/
+#define DLIST_HEAD(p, result_head) \
+do { \
+ (result_head) = (p); \
+ while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \
+} while(0)
+
+/* return the last element in the list */
+#define DLIST_TAIL(list) ((list)?(list)->prev:NULL)
+
+/* return the previous element in the list. */
+#define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL)
+
+/* insert 'p' after the given element 'el' in a list. If el is NULL then
+ this is the same as a DLIST_ADD() */
+#define DLIST_ADD_AFTER(list, p, el) \
+do { \
+ if (!(list) || !(el)) { \
+ DLIST_ADD(list, p); \
+ } else { \
+ (p)->prev = (el); \
+ (p)->next = (el)->next; \
+ (el)->next = (p); \
+ if ((p)->next) (p)->next->prev = (p); \
+ if ((list)->prev == (el)) (list)->prev = (p); \
+ }\
+} while (0)
+
+
+/*
+ add to the end of a list.
+*/
+#define DLIST_ADD_END(list, p) \
+do { \
+ if (!(list)) { \
+ DLIST_ADD(list, p); \
+ } else { \
+ DLIST_ADD_AFTER(list, p, (list)->prev); \
+ } \
+} while (0)
+
+/* promote an element to the front of a list */
+#define DLIST_PROMOTE(list, p) \
+do { \
+ DLIST_REMOVE(list, p); \
+ DLIST_ADD(list, p); \
+} while (0)
+
+/*
+ demote an element to the end of a list.
+*/
+#define DLIST_DEMOTE(list, p) \
+do { \
+ DLIST_REMOVE(list, p); \
+ DLIST_ADD_END(list, p); \
+} while (0)
+
+/*
+ * like DLIST_DEMOTE(), but optimized
+ * for short lists with 0, 1 or 2 elements
+ */
+#define DLIST_DEMOTE_SHORT(list, p) \
+do { \
+ if ((list) == NULL) { \
+ /* no reason to demote, just add */ \
+ DLIST_ADD(list, p); \
+ } else if ((list)->prev == (p)) { \
+ /* optimize if p is last */ \
+ } else if ((list) == (p)) { \
+ /* optimize if p is first */ \
+ (list)->prev->next = (p); \
+ (list) = (p)->next; \
+ (p)->next = NULL; \
+ } else { \
+ DLIST_DEMOTE(list, p); \
+ } \
+} while (0)
+
+/*
+ concatenate two lists - putting all elements of the 2nd list at the
+ end of the first list.
+*/
+#define DLIST_CONCATENATE(list1, list2) \
+do { \
+ if (!(list1)) { \
+ (list1) = (list2); \
+ } else { \
+ (list1)->prev->next = (list2); \
+ if (list2) { \
+ void *_tmplist = (void *)(list1)->prev; \
+ (list1)->prev = (list2)->prev; \
+ (list2)->prev = _tmplist; \
+ } \
+ } \
+} while (0)
+
+#endif /* _DLINKLIST_H */
diff --git a/lib/util/dprintf.c b/lib/util/dprintf.c
new file mode 100644
index 0000000..9d1573f
--- /dev/null
+++ b/lib/util/dprintf.c
@@ -0,0 +1,80 @@
+/*
+ Unix SMB/CIFS implementation.
+ display print functions
+ Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Jelmer Vernooij 2007
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/*
+ this module provides functions for printing internal strings in the
+ "display charset".
+
+ This charset may be quite different from the chosen unix charset.
+
+ Eventually these functions will need to take care of column count constraints
+
+ The d_ prefix on print functions in Samba refers to the display character set
+ conversion
+*/
+
+#include "replace.h"
+#include "system/locale.h"
+#include "lib/util/samba_util.h"
+
+static int d_vfprintf(FILE *f, const char *format, va_list ap)
+ PRINTF_ATTRIBUTE(2,0);
+
+static int d_vfprintf(FILE *f, const char *format, va_list ap)
+{
+ return vfprintf(f, format, ap);
+}
+
+
+_PUBLIC_ int d_fprintf(FILE *f, const char *format, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, format);
+ ret = d_vfprintf(f, format, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+static FILE *outfile;
+
+_PUBLIC_ int d_printf(const char *format, ...)
+{
+ int ret;
+ va_list ap;
+
+ if (!outfile) outfile = stdout;
+
+ va_start(ap, format);
+ ret = d_vfprintf(outfile, format, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+/* interactive programs need a way of tell d_*() to write to stderr instead
+ of stdout */
+void display_set_stderr(void)
+{
+ outfile = stderr;
+}
diff --git a/lib/util/fault.c b/lib/util/fault.c
new file mode 100644
index 0000000..10c3720
--- /dev/null
+++ b/lib/util/fault.c
@@ -0,0 +1,318 @@
+/*
+ Unix SMB/CIFS implementation.
+ Critical Fault handling
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Tim Prouty 2009
+ Copyright (C) James Peach 2006
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/wait.h"
+#include "version.h"
+
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
+
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
+
+#include "debug.h"
+#include "lib/util/signal.h" /* Avoid /usr/include/signal.h */
+#include "fault.h"
+#include "util_process.h"
+
+static struct {
+ bool disabled;
+ smb_panic_handler_t panic_handler;
+} fault_state;
+
+
+/*******************************************************************
+setup variables used for fault handling
+********************************************************************/
+void fault_configure(smb_panic_handler_t panic_handler)
+{
+ fault_state.panic_handler = panic_handler;
+}
+
+
+/**
+ disable setting up fault handlers
+ This is used for the bind9 dlz module, as we
+ don't want a Samba module in bind9 to override the bind
+ fault handling
+**/
+_PUBLIC_ void fault_setup_disable(void)
+{
+ fault_state.disabled = true;
+}
+
+
+#if !defined(HAVE_DISABLE_FAULT_HANDLING)
+/*******************************************************************
+report a fault
+********************************************************************/
+static void fault_report(int sig)
+{
+ static int counter;
+ char signal_string[128];
+
+ if (counter) _exit(1);
+
+ counter++;
+
+ snprintf(signal_string, sizeof(signal_string),
+ "Signal %d: %s", sig, strsignal(sig));
+ smb_panic(signal_string);
+
+ /* smb_panic() never returns, so this is really redundant */
+ exit(1);
+}
+
+/****************************************************************************
+catch serious errors
+****************************************************************************/
+static void sig_fault(int sig)
+{
+ fault_report(sig);
+}
+#endif
+/*******************************************************************
+setup our fault handlers
+********************************************************************/
+void fault_setup(void)
+{
+ if (fault_state.disabled) {
+ return;
+ }
+#if !defined(HAVE_DISABLE_FAULT_HANDLING)
+#ifdef SIGSEGV
+ CatchSignal(SIGSEGV, sig_fault);
+#endif
+#ifdef SIGBUS
+ CatchSignal(SIGBUS, sig_fault);
+#endif
+#ifdef SIGABRT
+ CatchSignal(SIGABRT, sig_fault);
+#endif
+#endif
+}
+
+_PUBLIC_ const char *panic_action = NULL;
+
+/*
+ default smb_panic() implementation
+*/
+static void smb_panic_default(const char *why) _NORETURN_;
+static void smb_panic_default(const char *why)
+{
+#if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
+ /*
+ * Make sure all children can attach a debugger.
+ */
+ prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
+#endif
+
+ if (panic_action && *panic_action) {
+ char cmdstring[200];
+ if (strlcpy(cmdstring, panic_action, sizeof(cmdstring)) < sizeof(cmdstring)) {
+ int result;
+ char pidstr[20];
+ char subst[200];
+ char *p = NULL;
+ snprintf(pidstr, sizeof(pidstr), "%d", (int) getpid());
+
+ p = strstr(cmdstring, "%d");
+ if (p != NULL) {
+ snprintf(subst,
+ sizeof(subst),
+ "%.*s%s%s",
+ (int)(p-cmdstring),
+ cmdstring,
+ pidstr,
+ p+2);
+ strlcpy(cmdstring, subst, sizeof(cmdstring));
+ }
+
+ DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmdstring));
+ result = system(cmdstring);
+
+ if (result == -1)
+ DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
+ strerror(errno)));
+ else
+ DEBUG(0, ("smb_panic(): action returned status %d\n",
+ WEXITSTATUS(result)));
+ }
+ }
+
+#ifdef SIGABRT
+ CatchSignal(SIGABRT, SIG_DFL);
+#endif
+ abort();
+}
+
+_PUBLIC_ void smb_panic_log(const char *why)
+{
+ const char *binary_name = process_get_saved_binary_name();
+ const char *short_title = process_get_short_title();
+ const char *long_title = process_get_long_title();
+
+ DEBUGSEP(0);
+ DEBUG(0,("INTERNAL ERROR: %s in %s (%s) (%s) pid %lld (%s)\n",
+ why,
+ binary_name,
+ short_title,
+ long_title,
+ (unsigned long long)getpid(),
+ SAMBA_VERSION_STRING));
+ DEBUG(0,("If you are running a recent Samba version, and "
+ "if you think this problem is not yet fixed in the "
+ "latest versions, please consider reporting this "
+ "bug, see "
+ "https://wiki.samba.org/index.php/Bug_Reporting\n"));
+ DEBUGSEP(0);
+ DEBUG(0,("PANIC (pid %llu): %s in " SAMBA_VERSION_STRING "\n",
+ (unsigned long long)getpid(), why));
+
+ log_stack_trace();
+}
+
+/**
+ Something really nasty happened - panic !
+
+ This function is in this file to allow sharing the last set process
+ title into the logs before the backtrace
+**/
+_PUBLIC_ void smb_panic(const char *why)
+{
+ smb_panic_log(why);
+
+ if (fault_state.panic_handler) {
+ fault_state.panic_handler(why);
+ _exit(1);
+ }
+ smb_panic_default(why);
+}
+
+/*******************************************************************
+ Print a backtrace of the stack to the debug log. This function
+ DELIBERATELY LEAKS MEMORY. The expectation is that you should
+ exit shortly after calling it.
+********************************************************************/
+
+/* Buffer size to use when printing backtraces */
+#define BACKTRACE_STACK_SIZE 64
+
+
+#ifdef HAVE_LIBUNWIND_H
+#include <libunwind.h>
+#endif
+
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+void log_stack_trace(void)
+{
+#ifdef HAVE_LIBUNWIND
+ /*
+ * --with-libunwind is required to use libunwind, the
+ * backtrace_symbols() code below is the default.
+ *
+ * This code is available because a previous version of this
+ * comment asserted that on ia64 libunwind correctly walks the
+ * stack in more circumstances than backtrace.
+ */
+ unw_cursor_t cursor;
+ unw_context_t uc;
+ unsigned i = 0;
+
+ char procname[256];
+ unw_word_t ip, sp, off;
+
+ procname[sizeof(procname) - 1] = '\0';
+
+ if (unw_getcontext(&uc) != 0) {
+ goto libunwind_failed;
+ }
+
+ if (unw_init_local(&cursor, &uc) != 0) {
+ goto libunwind_failed;
+ }
+
+ DEBUG(0, ("BACKTRACE:\n"));
+
+ do {
+ ip = sp = 0;
+ unw_get_reg(&cursor, UNW_REG_IP, &ip);
+ unw_get_reg(&cursor, UNW_REG_SP, &sp);
+
+ switch (unw_get_proc_name(&cursor,
+ procname, sizeof(procname) - 1, &off) ) {
+ case 0:
+ /* Name found. */
+ case -UNW_ENOMEM:
+ /* Name truncated. */
+ DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
+ i, procname, (long long)off,
+ (long long)ip, (long long) sp));
+ break;
+ default:
+ /* case -UNW_ENOINFO: */
+ /* case -UNW_EUNSPEC: */
+ /* No symbol name found. */
+ DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
+ i, "<unknown symbol>",
+ (long long)ip, (long long) sp));
+ }
+ ++i;
+ } while (unw_step(&cursor) > 0);
+
+ return;
+
+libunwind_failed:
+ DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
+
+#elif defined(HAVE_BACKTRACE_SYMBOLS)
+ void *backtrace_stack[BACKTRACE_STACK_SIZE];
+ size_t backtrace_size;
+ char **backtrace_strings;
+
+ /* get the backtrace (stack frames) */
+ backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
+ backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
+
+ DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
+ (unsigned long)backtrace_size));
+
+ if (backtrace_strings) {
+ size_t i;
+
+ for (i = 0; i < backtrace_size; i++)
+ DEBUGADD(0, (" #%zu %s\n", i, backtrace_strings[i]));
+
+ /* Leak the backtrace_strings, rather than risk what free() might do */
+ }
+
+#else
+ DEBUG(0, ("unable to produce a stack trace on this platform\n"));
+#endif
+}
diff --git a/lib/util/fault.h b/lib/util/fault.h
new file mode 100644
index 0000000..6aceaf6
--- /dev/null
+++ b/lib/util/fault.h
@@ -0,0 +1,59 @@
+/*
+ Unix SMB/CIFS implementation.
+ Critical Fault handling
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Tim Prouty 2009
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_FAULT_H_
+#define _SAMBA_FAULT_H_
+
+#include <sys/types.h>
+
+#include "attr.h"
+
+/* Please include header file debug.h if you want to use macro SMB_ASSERT */
+
+/**
+ * assert macros
+ */
+#ifdef _SAMBA_DEBUG_H
+#define SMB_ASSERT(b) \
+do { \
+ if (unlikely(!(b))) { \
+ DEBUG(0,("PANIC: assert failed at %s(%d): %s\n", \
+ __FILE__, __LINE__, #b)); \
+ smb_panic("assert failed: " #b); \
+ } \
+} while(0)
+#endif /* _SAMBA_DEBUG_H */
+
+extern const char *panic_action;
+
+/**
+ Something really nasty happened - panic !
+**/
+typedef void (*smb_panic_handler_t)(const char *why);
+
+void fault_configure(smb_panic_handler_t panic_handler);
+void fault_setup(void);
+void fault_setup_disable(void);
+_NORETURN_ void smb_panic(const char *reason);
+void smb_panic_log(const char *reason);
+
+void log_stack_trace(void);
+
+#endif /* _SAMBA_FAULT_H_ */
diff --git a/lib/util/fsusage.c b/lib/util/fsusage.c
new file mode 100644
index 0000000..d769b45
--- /dev/null
+++ b/lib/util/fsusage.c
@@ -0,0 +1,160 @@
+/*
+ Unix SMB/CIFS implementation.
+ functions to calculate the free disk space
+ Copyright (C) Andrew Tridgell 1998-2000
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "lib/util/samba_util.h"
+#include "system/filesys.h"
+
+/**
+ * @file
+ * @brief Utility functions for getting the amount of free disk space
+ */
+
+/* Return the number of TOSIZE-byte blocks used by
+ BLOCKS FROMSIZE-byte blocks, rounding away from zero.
+*/
+static uint64_t adjust_blocks(uint64_t blocks, uint64_t fromsize, uint64_t tosize)
+{
+ if (fromsize == tosize) { /* e.g., from 512 to 512 */
+ return blocks;
+ } else if (fromsize > tosize) { /* e.g., from 2048 to 512 */
+ return blocks * (fromsize / tosize);
+ } else { /* e.g., from 256 to 512 */
+ /* Protect against broken filesystems... */
+ if (fromsize == 0) {
+ fromsize = tosize;
+ }
+ return (blocks + 1) / (tosize / fromsize);
+ }
+}
+
+/**
+ * Retrieve amount of free disk space.
+ * this does all of the system specific guff to get the free disk space.
+ * It is derived from code in the GNU fileutils package, but has been
+ * considerably mangled for use here
+ *
+ * results are returned in *dfree and *dsize, in 512 byte units
+*/
+_PUBLIC_ int sys_fsusage(const char *path, uint64_t *dfree, uint64_t *dsize)
+{
+#ifdef STAT_STATFS3_OSF1
+#define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_fsize, (uint64_t)512)
+ struct statfs fsd;
+
+ if (statfs (path, &fsd, sizeof (struct statfs)) != 0)
+ return -1;
+#endif /* STAT_STATFS3_OSF1 */
+
+#ifdef STAT_STATFS2_FS_DATA /* Ultrix */
+#define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)1024, (uint64_t)512)
+ struct fs_data fsd;
+
+ if (statfs (path, &fsd) != 1)
+ return -1;
+
+ (*dsize) = CONVERT_BLOCKS (fsd.fd_req.btot);
+ (*dfree) = CONVERT_BLOCKS (fsd.fd_req.bfreen);
+#endif /* STAT_STATFS2_FS_DATA */
+
+#ifdef STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX */
+#define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_bsize, (uint64_t)512)
+ struct statfs fsd;
+
+ if (statfs (path, &fsd) < 0)
+ return -1;
+
+#ifdef STATFS_TRUNCATES_BLOCK_COUNTS
+ /* In SunOS 4.1.2, 4.1.3, and 4.1.3_U1, the block counts in the
+ struct statfs are truncated to 2GB. These conditions detect that
+ truncation, presumably without botching the 4.1.1 case, in which
+ the values are not truncated. The correct counts are stored in
+ undocumented spare fields. */
+ if (fsd.f_blocks == 0x1fffff && fsd.f_spare[0] > 0) {
+ fsd.f_blocks = fsd.f_spare[0];
+ fsd.f_bfree = fsd.f_spare[1];
+ fsd.f_bavail = fsd.f_spare[2];
+ }
+#endif /* STATFS_TRUNCATES_BLOCK_COUNTS */
+#endif /* STAT_STATFS2_BSIZE */
+
+
+#ifdef STAT_STATFS2_FSIZE /* 4.4BSD */
+#define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_fsize, (uint64_t)512)
+
+ struct statfs fsd;
+
+ if (statfs (path, &fsd) < 0)
+ return -1;
+#endif /* STAT_STATFS2_FSIZE */
+
+#ifdef STAT_STATFS4 /* SVR3, Dynix, Irix, AIX */
+# if _AIX || defined(_CRAY)
+# define CONVERT_BLOCKS(B) adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_bsize, (uint64_t)512)
+# ifdef _CRAY
+# define f_bavail f_bfree
+# endif
+# else
+# define CONVERT_BLOCKS(B) ((uint64_t)B)
+# ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx */
+# ifndef DOLPHIN /* DOLPHIN 3.8.alfa/7.18 has f_bavail */
+# define f_bavail f_bfree
+# endif
+# endif
+# endif
+
+ struct statfs fsd;
+
+ if (statfs (path, &fsd, sizeof fsd, 0) < 0)
+ return -1;
+ /* Empirically, the block counts on most SVR3 and SVR3-derived
+ systems seem to always be in terms of 512-byte blocks,
+ no matter what value f_bsize has. */
+
+#endif /* STAT_STATFS4 */
+
+#if defined(STAT_STATVFS) /* SVR4 */
+#ifdef HAVE_FRSIZE
+# define CONVERT_BLOCKS(B) \
+ adjust_blocks ((uint64_t)(B), fsd.f_frsize ? (uint64_t)fsd.f_frsize : (uint64_t)fsd.f_bsize, (uint64_t)512)
+#else
+# define CONVERT_BLOCKS(B) \
+ adjust_blocks ((uint64_t)(B), (uint64_t)fsd.f_bsize, (uint64_t)512)
+#endif
+
+ struct statvfs fsd;
+ if (statvfs(path, &fsd) < 0) return -1;
+
+ /* f_frsize isn't guaranteed to be supported. */
+
+#endif /* STAT_STATVFS */
+
+#ifndef CONVERT_BLOCKS
+ /* we don't have any dfree code! */
+ return -1;
+#else
+#if !defined(STAT_STATFS2_FS_DATA)
+ /* !Ultrix */
+ (*dsize) = CONVERT_BLOCKS (fsd.f_blocks);
+ (*dfree) = CONVERT_BLOCKS (fsd.f_bavail);
+#endif /* not STAT_STATFS2_FS_DATA */
+#endif
+
+ return 0;
+}
diff --git a/lib/util/genrand.c b/lib/util/genrand.c
new file mode 100644
index 0000000..d0b49db
--- /dev/null
+++ b/lib/util/genrand.c
@@ -0,0 +1,87 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Functions to create reasonable random numbers for crypto use.
+
+ Copyright (C) Jeremy Allison 2001
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "lib/util/fault.h"
+#include "lib/util/genrand.h"
+
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+
+/*
+ * Details about the GnuTLS CSPRNG:
+ *
+ * https://nikmav.blogspot.com/2017/03/improving-by-simplifying-gnutls-prng.html
+ */
+
+
+_NORETURN_ static void genrand_panic(int err,
+ const char *location,
+ const char *func)
+{
+ char buf[200];
+ snprintf(buf, sizeof(buf),
+ "%s:%s: GnuTLS could not generate a random buffer: %s [%d]\n",
+ location, func, gnutls_strerror_name(err), err);
+ smb_panic(buf);
+}
+
+
+_PUBLIC_ void generate_random_buffer(uint8_t *out, size_t len)
+{
+ /* Random number generator for temporary keys. */
+ int ret = gnutls_rnd(GNUTLS_RND_RANDOM, out, len);
+ if (ret != 0) {
+ genrand_panic(ret, __location__, __func__);
+ }
+}
+
+_PUBLIC_ void generate_secret_buffer(uint8_t *out, size_t len)
+{
+ /*
+ * Random number generator for long term keys.
+ *
+ * The key generator, will re-seed after a fixed amount of bytes is
+ * generated (typically less than the nonce), and will also re-seed
+ * based on time, i.e., after few hours of operation without reaching
+ * the limit for a re-seed. For its re-seed it mixes data obtained
+ * from the OS random device with the previous key.
+ */
+ int ret = gnutls_rnd(GNUTLS_RND_KEY, out, len);
+ if (ret != 0) {
+ genrand_panic(ret, __location__, __func__);
+ }
+}
+
+_PUBLIC_ void generate_nonce_buffer(uint8_t *out, size_t len)
+{
+ /*
+ * Random number generator for nonce and initialization vectors.
+ *
+ * The nonce generator will reseed after outputting a fixed amount of
+ * bytes (typically few megabytes), or after few hours of operation
+ * without reaching the limit has passed.
+ */
+ int ret = gnutls_rnd(GNUTLS_RND_NONCE, out, len);
+ if (ret != 0) {
+ genrand_panic(ret, __location__, __func__);
+ }
+}
diff --git a/lib/util/genrand.h b/lib/util/genrand.h
new file mode 100644
index 0000000..76e9b98
--- /dev/null
+++ b/lib/util/genrand.h
@@ -0,0 +1,49 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Functions to create reasonable random numbers for crypto use.
+
+ Copyright (C) Jeremy Allison 2001
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @brief Generate random values for session and temporary keys.
+ *
+ * @param[in] out A pointer to the buffer to fill with random data.
+ *
+ * @param[in] len The size of the buffer to fill.
+ */
+void generate_random_buffer(uint8_t *out, size_t len);
+
+/**
+ * @brief Generate random values for long term keys and passwords.
+ *
+ * @param[in] out A pointer to the buffer to fill with random data.
+ *
+ * @param[in] len The size of the buffer to fill.
+ */
+void generate_secret_buffer(uint8_t *out, size_t len);
+
+/**
+ * @brief Generate random values for a nonce buffer.
+ *
+ * This is also known as initialization vector.
+ *
+ * @param[in] out A pointer to the buffer to fill with random data.
+ *
+ * @param[in] len The size of the buffer to fill.
+ */
+void generate_nonce_buffer(uint8_t *out, size_t len);
diff --git a/lib/util/genrand_util.c b/lib/util/genrand_util.c
new file mode 100644
index 0000000..43005c5
--- /dev/null
+++ b/lib/util/genrand_util.c
@@ -0,0 +1,531 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Functions to create reasonable random numbers for crypto use.
+
+ Copyright (C) Jeremy Allison 2001
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/locale.h"
+#include <tevent.h>
+#include "lib/util/samba_util.h"
+#include "lib/util/debug.h"
+
+/**
+ * @file
+ * @brief Random number generation
+ */
+
+/**
+ generate a single random uint32_t
+**/
+_PUBLIC_ uint32_t generate_random(void)
+{
+ uint8_t v[4];
+ generate_random_buffer(v, 4);
+ return IVAL(v, 0);
+}
+
+/**
+ @brief generate a random uint64
+**/
+_PUBLIC_ uint64_t generate_random_u64(void)
+{
+ uint8_t v[8];
+ generate_random_buffer(v, 8);
+ return BVAL(v, 0);
+}
+
+/**
+ * @brief Generate a random number in the given range.
+ *
+ * @param lower The lower value of the range
+
+ * @param upper The upper value of the range
+ *
+ * @return A random number bigger than than lower and smaller than upper.
+ */
+_PUBLIC_ uint64_t generate_random_u64_range(uint64_t lower, uint64_t upper)
+{
+ return generate_random_u64() % (upper - lower) + lower;
+}
+
+_PUBLIC_ uint64_t generate_unique_u64(uint64_t veto_value)
+{
+ static struct generate_unique_u64_state {
+ uint64_t next_value;
+ int pid;
+ } generate_unique_u64_state;
+
+ int pid = tevent_cached_getpid();
+
+ if (unlikely(pid != generate_unique_u64_state.pid)) {
+ generate_unique_u64_state = (struct generate_unique_u64_state) {
+ .pid = pid,
+ .next_value = veto_value,
+ };
+ }
+
+ while (unlikely(generate_unique_u64_state.next_value == veto_value)) {
+ generate_nonce_buffer(
+ (void *)&generate_unique_u64_state.next_value,
+ sizeof(generate_unique_u64_state.next_value));
+ }
+
+ return generate_unique_u64_state.next_value++;
+}
+
+/**
+ Microsoft composed the following rules (among others) for quality
+ checks. This is an abridgment from
+ http://msdn.microsoft.com/en-us/subscriptions/cc786468%28v=ws.10%29.aspx:
+
+ Passwords must contain characters from three of the following five
+ categories:
+
+ - Uppercase characters of European languages (A through Z, with
+ diacritic marks, Greek and Cyrillic characters)
+ - Lowercase characters of European languages (a through z, sharp-s,
+ with diacritic marks, Greek and Cyrillic characters)
+ - Base 10 digits (0 through 9)
+ - Nonalphanumeric characters: ~!@#$%^&*_-+=`|\(){}[]:;"'<>,.?/
+ - Any Unicode character that is categorized as an alphabetic character
+ but is not uppercase or lowercase. This includes Unicode characters
+ from Asian languages.
+
+ Note: for now do not check if the unicode category is
+ alphabetic character
+**/
+_PUBLIC_ bool check_password_quality(const char *pwd)
+{
+ size_t ofs = 0;
+ size_t num_digits = 0;
+ size_t num_upper = 0;
+ size_t num_lower = 0;
+ size_t num_nonalpha = 0;
+ size_t num_unicode = 0;
+ size_t num_categories = 0;
+
+ if (pwd == NULL) {
+ return false;
+ }
+
+ while (true) {
+ const char *s = &pwd[ofs];
+ size_t len = 0;
+ codepoint_t c;
+
+ c = next_codepoint(s, &len);
+ if (c == INVALID_CODEPOINT) {
+ return false;
+ } else if (c == 0) {
+ break;
+ }
+ ofs += len;
+
+ if (len == 1) {
+ const char *na = "~!@#$%^&*_-+=`|\\(){}[]:;\"'<>,.?/";
+
+ if (isdigit(c)) {
+ num_digits += 1;
+ continue;
+ }
+
+ if (isupper(c)) {
+ num_upper += 1;
+ continue;
+ }
+
+ if (islower(c)) {
+ num_lower += 1;
+ continue;
+ }
+
+ if (strchr(na, c)) {
+ num_nonalpha += 1;
+ continue;
+ }
+
+ /*
+ * the rest does not belong to
+ * a category.
+ */
+ continue;
+ }
+
+ if (isupper_m(c)) {
+ num_upper += 1;
+ continue;
+ }
+
+ if (islower_m(c)) {
+ num_lower += 1;
+ continue;
+ }
+
+ /*
+ * Note: for now do not check if the unicode category is
+ * alphabetic character
+ *
+ * We would have to import the details from
+ * ftp://ftp.unicode.org/Public/6.3.0/ucd/UnicodeData-6.3.0d1.txt
+ */
+ num_unicode += 1;
+ continue;
+ }
+
+ if (num_digits > 0) {
+ num_categories += 1;
+ }
+ if (num_upper > 0) {
+ num_categories += 1;
+ }
+ if (num_lower > 0) {
+ num_categories += 1;
+ }
+ if (num_nonalpha > 0) {
+ num_categories += 1;
+ }
+ if (num_unicode > 0) {
+ num_categories += 1;
+ }
+
+ if (num_categories >= 3) {
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ Use the random number generator to generate a random string.
+**/
+
+_PUBLIC_ char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const char *list)
+{
+ size_t i;
+ size_t list_len = strlen(list);
+
+ char *retstr = talloc_array(mem_ctx, char, len + 1);
+ if (!retstr) return NULL;
+
+ generate_secret_buffer((uint8_t *)retstr, len);
+ for (i = 0; i < len; i++) {
+ retstr[i] = list[retstr[i] % list_len];
+ }
+ retstr[i] = '\0';
+
+ return retstr;
+}
+
+/**
+ * Generate a random text string consisting of the specified length.
+ * The returned string will be allocated.
+ *
+ * Characters used are: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,
+ */
+
+_PUBLIC_ char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len)
+{
+ char *retstr;
+ const char *c_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,";
+
+again:
+ retstr = generate_random_str_list(mem_ctx, len, c_list);
+ if (!retstr) return NULL;
+
+ /* we need to make sure the random string passes basic quality tests
+ or it might be rejected by windows as a password */
+ if (len >= 7 && !check_password_quality(retstr)) {
+ talloc_free(retstr);
+ goto again;
+ }
+
+ return retstr;
+}
+
+/**
+ * Generate a random text password (based on printable ascii characters).
+ */
+
+_PUBLIC_ char *generate_random_password(TALLOC_CTX *mem_ctx, size_t min, size_t max)
+{
+ char *retstr;
+ /* This list does not include { or } because they cause
+ * problems for our provision (it can create a substring
+ * ${...}, and for Fedora DS (which treats {...} at the start
+ * of a stored password as special
+ * -- Andrew Bartlett 2010-03-11
+ */
+ const char *c_list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,@$%&!?:;<=>()[]~";
+ size_t len = max;
+ size_t diff;
+
+ if (min > max) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ diff = max - min;
+
+ if (diff > 0 ) {
+ size_t tmp;
+
+ generate_secret_buffer((uint8_t *)&tmp, sizeof(tmp));
+
+ tmp %= diff;
+
+ len = min + tmp;
+ }
+
+again:
+ retstr = generate_random_str_list(mem_ctx, len, c_list);
+ if (!retstr) return NULL;
+
+ /* we need to make sure the random string passes basic quality tests
+ or it might be rejected by windows as a password */
+ if (len >= 7 && !check_password_quality(retstr)) {
+ talloc_free(retstr);
+ goto again;
+ }
+
+ return retstr;
+}
+
+/**
+ * Generate a random machine password (based on random utf16 characters,
+ * converted to utf8). min must be at least 14, max must be at most 255.
+ *
+ * If 'unix charset' is not utf8, the password consist of random ascii
+ * values!
+ *
+ * The return value is a talloc string with destructor talloc_keep_secret() set.
+ * The content will be overwritten by zeros when the mem_ctx is destroyed.
+ */
+
+_PUBLIC_ char *generate_random_machine_password(TALLOC_CTX *mem_ctx, size_t min, size_t max)
+{
+ TALLOC_CTX *frame = NULL;
+ struct generate_random_machine_password_state {
+ uint8_t password_buffer[256 * 2];
+ uint8_t tmp;
+ } *state;
+ char *new_pw = NULL;
+ size_t len = max;
+ char *utf8_pw = NULL;
+ size_t utf8_len = 0;
+ char *unix_pw = NULL;
+ size_t unix_len = 0;
+ size_t diff;
+ size_t i;
+ bool ok;
+ int cmp;
+
+ if (max > 255) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (min < 14) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (min > max) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ frame = talloc_stackframe_pool(2048);
+ state = talloc_zero(frame, struct generate_random_machine_password_state);
+ talloc_keep_secret(state);
+
+ diff = max - min;
+
+ if (diff > 0) {
+ size_t tmp;
+
+ generate_secret_buffer((uint8_t *)&tmp, sizeof(tmp));
+
+ tmp %= diff;
+
+ len = min + tmp;
+ }
+
+ /*
+ * Create a random machine account password
+ * We create a random buffer and convert that to utf8.
+ * This is similar to what windows is doing.
+ *
+ * In future we may store the raw random buffer,
+ * but for now we need to pass the password as
+ * char pointer through some layers.
+ *
+ * As most kerberos keys are derived from the
+ * utf8 password we need to fallback to
+ * ASCII passwords if "unix charset" is not utf8.
+ */
+ generate_secret_buffer(state->password_buffer, len * 2);
+ for (i = 0; i < len; i++) {
+ size_t idx = i*2;
+ uint16_t c;
+
+ /*
+ * both MIT krb5 and HEIMDAL only
+ * handle codepoints up to 0xffff.
+ *
+ * It means we need to avoid
+ * 0xD800 - 0xDBFF (high surrogate)
+ * and
+ * 0xDC00 - 0xDFFF (low surrogate)
+ * in the random utf16 data.
+ *
+ * 55296 0xD800 0154000 0b1101100000000000
+ * 57343 0xDFFF 0157777 0b1101111111111111
+ * 8192 0x2000 020000 0b10000000000000
+ *
+ * The above values show that we can check
+ * for 0xD800 and just add 0x2000 to avoid
+ * the surrogate ranges.
+ *
+ * The rest will be handled by CH_UTF16MUNGED
+ * see utf16_munged_pull().
+ */
+ c = SVAL(state->password_buffer, idx);
+ if (c & 0xD800) {
+ c |= 0x2000;
+ }
+ SSVAL(state->password_buffer, idx, c);
+ }
+ ok = convert_string_talloc(frame,
+ CH_UTF16MUNGED, CH_UTF8,
+ state->password_buffer, len * 2,
+ (void *)&utf8_pw, &utf8_len);
+ if (!ok) {
+ DEBUG(0, ("%s: convert_string_talloc() failed\n",
+ __func__));
+ TALLOC_FREE(frame);
+ return NULL;
+ }
+ talloc_keep_secret(utf8_pw);
+
+ ok = convert_string_talloc(frame,
+ CH_UTF16MUNGED, CH_UNIX,
+ state->password_buffer, len * 2,
+ (void *)&unix_pw, &unix_len);
+ if (!ok) {
+ goto ascii_fallback;
+ }
+ talloc_keep_secret(unix_pw);
+
+ if (utf8_len != unix_len) {
+ goto ascii_fallback;
+ }
+
+ cmp = memcmp((const uint8_t *)utf8_pw,
+ (const uint8_t *)unix_pw,
+ utf8_len);
+ if (cmp != 0) {
+ goto ascii_fallback;
+ }
+
+ new_pw = talloc_strdup(mem_ctx, utf8_pw);
+ if (new_pw == NULL) {
+ TALLOC_FREE(frame);
+ return NULL;
+ }
+ talloc_keep_secret(new_pw);
+ talloc_set_name_const(new_pw, __func__);
+ TALLOC_FREE(frame);
+ return new_pw;
+
+ascii_fallback:
+ for (i = 0; i < len; i++) {
+ /*
+ * truncate to ascii
+ */
+ state->tmp = state->password_buffer[i] & 0x7f;
+ if (state->tmp == 0) {
+ state->tmp = state->password_buffer[i] >> 1;
+ }
+ if (state->tmp == 0) {
+ state->tmp = 0x01;
+ }
+ state->password_buffer[i] = state->tmp;
+ }
+ state->password_buffer[i] = '\0';
+
+ new_pw = talloc_strdup(mem_ctx, (const char *)state->password_buffer);
+ if (new_pw == NULL) {
+ TALLOC_FREE(frame);
+ return NULL;
+ }
+ talloc_keep_secret(new_pw);
+ talloc_set_name_const(new_pw, __func__);
+ TALLOC_FREE(frame);
+ return new_pw;
+}
+
+/**
+ * Generate an array of unique text strings all of the same length.
+ * The returned string will be allocated.
+ * Returns NULL if the number of unique combinations cannot be created.
+ *
+ * Characters used are: abcdefghijklmnopqrstuvwxyz0123456789+_-#.,
+ */
+_PUBLIC_ char** generate_unique_strs(TALLOC_CTX *mem_ctx, size_t len,
+ uint32_t num)
+{
+ const char *c_list = "abcdefghijklmnopqrstuvwxyz0123456789+_-#.,";
+ const unsigned c_size = 42;
+ size_t i, j;
+ unsigned rem;
+ char ** strs = NULL;
+
+ if (num == 0 || len == 0)
+ return NULL;
+
+ strs = talloc_array(mem_ctx, char *, num);
+ if (strs == NULL) return NULL;
+
+ for (i = 0; i < num; i++) {
+ char *retstr = (char *)talloc_size(strs, len + 1);
+ if (retstr == NULL) {
+ talloc_free(strs);
+ return NULL;
+ }
+ rem = i;
+ for (j = 0; j < len; j++) {
+ retstr[j] = c_list[rem % c_size];
+ rem = rem / c_size;
+ }
+ retstr[j] = 0;
+ strs[i] = retstr;
+ if (rem != 0) {
+ /* we were not able to fit the number of
+ * combinations asked for in the length
+ * specified */
+ DEBUG(0,(__location__ ": Too many combinations %u for length %u\n",
+ num, (unsigned)len));
+
+ talloc_free(strs);
+ return NULL;
+ }
+ }
+
+ return strs;
+}
diff --git a/lib/util/getpass.c b/lib/util/getpass.c
new file mode 100644
index 0000000..0cbc7dd
--- /dev/null
+++ b/lib/util/getpass.c
@@ -0,0 +1,230 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * getpass.c - platform independent getpass function.
+ *
+ * Copyright (c) 2010-2012 Andreas Schneider <asn@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+
+#include "system/filesys.h"
+#include "system/terminal.h"
+
+#if !defined(SMB_MALLOC)
+#undef malloc
+#define SMB_MALLOC(s) malloc((s))
+#endif
+
+/**
+ * @internal
+ *
+ * @brief Get the password from the console.
+ *
+ * @param[in] prompt The prompt to display.
+ *
+ * @param[in] buf The buffer to fill.
+ *
+ * @param[in] len The length of the buffer.
+ *
+ * @param[in] verify Should the password be verified?
+ *
+ * @return 1 on success, 0 on error.
+ */
+static int samba_gets(const char *prompt, char *buf, size_t len, bool verify)
+{
+ char *tmp;
+ char *ptr = NULL;
+ int ok = 0;
+
+ tmp = SMB_MALLOC(len);
+ if (tmp == NULL) {
+ return 0;
+ }
+ memset(tmp,'\0',len);
+
+ /* read the password */
+ while (!ok) {
+ if (buf[0] != '\0') {
+ fprintf(stdout, "%s[%s] ", prompt, buf);
+ } else {
+ fprintf(stdout, "%s", prompt);
+ }
+ fflush(stdout);
+ if (fgets(tmp, len, stdin) == NULL) {
+ free(tmp);
+ return 0;
+ }
+
+ if ((ptr = strchr(tmp, '\n'))) {
+ *ptr = '\0';
+ }
+ fprintf(stdout, "\n");
+
+ if (*tmp) {
+ strncpy(buf, tmp, len);
+ }
+
+ if (verify) {
+ char *key_string;
+
+ key_string = SMB_MALLOC(len);
+ if (key_string == NULL) {
+ break;
+ }
+ memset(key_string, '\0', len);
+
+ fprintf(stdout, "\nVerifying, please re-enter. %s", prompt);
+ fflush(stdout);
+ if (! fgets(key_string, len, stdin)) {
+ memset(key_string, '\0', len);
+ SAFE_FREE(key_string);
+ clearerr(stdin);
+ continue;
+ }
+ if ((ptr = strchr(key_string, '\n'))) {
+ *ptr = '\0';
+ }
+ fprintf(stdout, "\n");
+ if (strcmp(buf, key_string)) {
+ printf("\n\07\07Mismatch - try again\n");
+ memset(key_string, '\0', len);
+ SAFE_FREE(key_string);
+ fflush(stdout);
+ continue;
+ }
+ memset(key_string, '\0', len);
+ SAFE_FREE(key_string);
+ }
+ ok = 1;
+ }
+ memset(tmp, '\0', len);
+ free(tmp);
+
+ return ok;
+}
+
+/**
+ * @brief Get a password from the console.
+ *
+ * You should make sure that the buffer is an empty string!
+ *
+ * You can also use this function to ask for a username. Then you can fill the
+ * buffer with the username and it is shows to the users. If the users just
+ * presses enter the buffer will be untouched.
+ *
+ * @code
+ * char username[128];
+ *
+ * snprintf(username, sizeof(username), "john");
+ *
+ * samba_getpass("Username:", username, sizeof(username), 1, 0);
+ * @endcode
+ *
+ * The prompt will look like this:
+ *
+ * Username: [john]
+ *
+ * If you press enter then john is used as the username, or you can type it in
+ * to change it.
+ *
+ * @param[in] prompt The prompt to show to ask for the password.
+ *
+ * @param[out] buf The buffer the password should be stored. It NEEDS to be
+ * empty or filled out.
+ *
+ * @param[in] len The length of the buffer.
+ *
+ * @param[in] echo Should we echo what you type.
+ *
+ * @param[in] verify Should we ask for the password twice.
+ *
+ * @return 0 on success, -1 on error.
+ */
+int samba_getpass(const char *prompt,
+ char *buf,
+ size_t len,
+ bool echo,
+ bool verify)
+{
+ struct termios attr;
+ struct termios old_attr;
+ int ok = 0;
+ int fd = -1;
+
+ /* fgets needs at least len - 1 */
+ if (prompt == NULL || buf == NULL || len < 2) {
+ return -1;
+ }
+
+ if (isatty (STDIN_FILENO)) {
+
+ ZERO_STRUCT(attr);
+ ZERO_STRUCT(old_attr);
+
+ /* get local terminal attributes */
+ if (tcgetattr(STDIN_FILENO, &attr) < 0) {
+ perror("tcgetattr");
+ return -1;
+ }
+
+ /* save terminal attributes */
+ memcpy(&old_attr, &attr, sizeof(attr));
+ if((fd = fcntl(0, F_GETFL, 0)) < 0) {
+ perror("fcntl");
+ return -1;
+ }
+
+ /* disable echo */
+ if (!echo) {
+ attr.c_lflag &= ~(ECHO);
+ }
+
+ /* write attributes to terminal */
+ if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &attr) < 0) {
+ perror("tcsetattr");
+ return -1;
+ }
+ }
+
+ /* disable nonblocking I/O */
+ if (fd & O_NDELAY) {
+ fcntl(0, F_SETFL, fd & ~O_NDELAY);
+ }
+
+ ok = samba_gets(prompt, buf, len, verify);
+
+ if (isatty (STDIN_FILENO)) {
+
+ /* reset terminal */
+ tcsetattr(STDIN_FILENO, TCSANOW, &old_attr);
+ }
+
+ /* close fd */
+ if (fd & O_NDELAY) {
+ fcntl(0, F_SETFL, fd);
+ }
+
+ if (!ok) {
+ memset (buf, '\0', len);
+ return -1;
+ }
+
+ /* force termination */
+ buf[len - 1] = '\0';
+
+ return 0;
+}
diff --git a/lib/util/gpfswrap.c b/lib/util/gpfswrap.c
new file mode 100644
index 0000000..2f15bf4
--- /dev/null
+++ b/lib/util/gpfswrap.c
@@ -0,0 +1,296 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Wrapper for GPFS library
+ * Copyright (C) Volker Lendecke 2005
+ * Copyright (C) Christof Schmitt 2015
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "gpfswrap.h"
+
+static int (*gpfs_set_share_fn)(int fd, unsigned int allow, unsigned int deny);
+static int (*gpfs_set_lease_fn)(int fd, unsigned int type);
+static int (*gpfs_fgetacl_fn)(int fd, int flags, void *acl);
+static int (*gpfs_putacl_fn)(const char *pathname, int flags, void *acl);
+static int (*gpfs_get_realfilename_path_fn)(const char *pathname,
+ char *filenamep,
+ int *len);
+static int (*gpfs_register_cifs_export_fn)(void);
+static int (*gpfs_set_winattrs_path_fn)(const char *pathname,
+ int flags,
+ struct gpfs_winattr *attrs);
+static int (*gpfs_set_winattrs_fn)(int fd, int flags,
+ struct gpfs_winattr *attrs);
+static int (*gpfs_get_winattrs_fn)(int fd, struct gpfs_winattr *attrs);
+static int (*gpfs_ftruncate_fn)(int fd, gpfs_off64_t length);
+static int (*gpfs_lib_init_fn)(int flags);
+static int (*gpfs_set_times_fn)(int fd, int flags, gpfs_timestruc_t times[4]);
+static int (*gpfs_set_times_path_fn)(char *path,
+ int flags,
+ gpfs_timestruc_t times[4]);
+static int (*gpfs_quotactl_fn)(const char *pathname,
+ int cmd,
+ int id,
+ void *bufp);
+static int (*gpfs_init_trace_fn)(void);
+static int (*gpfs_query_trace_fn)(void);
+static void (*gpfs_add_trace_fn)(int level, const char *msg);
+static void (*gpfs_fini_trace_fn)(void);
+static int (*gpfs_fstat_x_fn)(int fd, unsigned int *litemask,
+ struct gpfs_iattr64 *iattr, size_t len);
+static int (*gpfs_stat_x_fn)(const char *pathname, unsigned int *litemask,
+ struct gpfs_iattr64 *iattr, size_t len);
+
+int gpfswrap_init(void)
+{
+ static void *l;
+
+ if (l != NULL) {
+ return 0;
+ }
+
+ l = dlopen("libgpfs.so", RTLD_LAZY);
+ if (l == NULL) {
+ return -1;
+ }
+
+ gpfs_set_share_fn = dlsym(l, "gpfs_set_share");
+ gpfs_set_lease_fn = dlsym(l, "gpfs_set_lease");
+ gpfs_fgetacl_fn = dlsym(l, "gpfs_getacl_fd");
+ gpfs_putacl_fn = dlsym(l, "gpfs_putacl");
+ gpfs_get_realfilename_path_fn = dlsym(l, "gpfs_get_realfilename_path");
+ gpfs_register_cifs_export_fn = dlsym(l, "gpfs_register_cifs_export");
+ gpfs_set_winattrs_path_fn = dlsym(l, "gpfs_set_winattrs_path");
+ gpfs_set_winattrs_fn = dlsym(l, "gpfs_set_winattrs");
+ gpfs_get_winattrs_fn = dlsym(l, "gpfs_get_winattrs");
+ gpfs_ftruncate_fn = dlsym(l, "gpfs_ftruncate");
+ gpfs_lib_init_fn = dlsym(l, "gpfs_lib_init");
+ gpfs_set_times_fn = dlsym(l, "gpfs_set_times");
+ gpfs_set_times_path_fn = dlsym(l, "gpfs_set_times_path");
+ gpfs_quotactl_fn = dlsym(l, "gpfs_quotactl");
+ gpfs_init_trace_fn = dlsym(l, "gpfs_init_trace");
+ gpfs_query_trace_fn = dlsym(l, "gpfs_query_trace");
+ gpfs_add_trace_fn = dlsym(l, "gpfs_add_trace");
+ gpfs_fini_trace_fn = dlsym(l, "gpfs_fini_trace");
+ gpfs_fstat_x_fn = dlsym(l, "gpfs_fstat_x");
+ gpfs_stat_x_fn = dlsym(l, "gpfs_stat_x");
+
+ return 0;
+}
+
+int gpfswrap_set_share(int fd, unsigned int allow, unsigned int deny)
+{
+ if (gpfs_set_share_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_set_share_fn(fd, allow, deny);
+}
+
+int gpfswrap_set_lease(int fd, unsigned int type)
+{
+ if (gpfs_set_lease_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_set_lease_fn(fd, type);
+}
+
+int gpfswrap_fgetacl(int fd, int flags, void *acl)
+{
+ if (gpfs_fgetacl_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_fgetacl_fn(fd, flags, acl);
+}
+
+int gpfswrap_putacl(const char *pathname, int flags, void *acl)
+{
+ if (gpfs_putacl_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_putacl_fn(pathname, flags, acl);
+}
+
+int gpfswrap_get_realfilename_path(const char *pathname,
+ char *filenamep,
+ int *len)
+{
+ if (gpfs_get_realfilename_path_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_get_realfilename_path_fn(pathname, filenamep, len);
+}
+
+int gpfswrap_register_cifs_export(void)
+{
+ if (gpfs_register_cifs_export_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_register_cifs_export_fn();
+}
+
+int gpfswrap_set_winattrs_path(const char *pathname,
+ int flags,
+ struct gpfs_winattr *attrs)
+{
+ if (gpfs_set_winattrs_path_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_set_winattrs_path_fn(pathname, flags, attrs);
+}
+
+int gpfswrap_set_winattrs(int fd, int flags, struct gpfs_winattr *attrs)
+{
+ if (gpfs_set_winattrs_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_set_winattrs_fn(fd, flags, attrs);
+}
+
+int gpfswrap_get_winattrs(int fd, struct gpfs_winattr *attrs)
+{
+ if (gpfs_get_winattrs_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_get_winattrs_fn(fd, attrs);
+}
+
+int gpfswrap_ftruncate(int fd, gpfs_off64_t length)
+{
+ if (gpfs_ftruncate_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_ftruncate_fn(fd, length);
+}
+
+int gpfswrap_lib_init(int flags)
+{
+ if (gpfs_lib_init_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_lib_init_fn(flags);
+}
+
+int gpfswrap_set_times(int fd, int flags, gpfs_timestruc_t times[4])
+{
+ if (gpfs_set_times_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_set_times_fn(fd, flags, times);
+}
+
+int gpfswrap_set_times_path(char *path, int flags, gpfs_timestruc_t times[4])
+{
+ if (gpfs_set_times_path_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_set_times_path_fn(path, flags, times);
+}
+
+int gpfswrap_quotactl(const char *pathname, int cmd, int id, void *bufp)
+{
+ if (gpfs_quotactl_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_quotactl_fn(pathname, cmd, id, bufp);
+}
+
+int gpfswrap_init_trace(void)
+{
+ if (gpfs_init_trace_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_init_trace_fn();
+}
+
+int gpfswrap_query_trace(void)
+{
+ if (gpfs_query_trace_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_query_trace_fn();
+}
+
+void gpfswrap_add_trace(int level, const char *msg)
+{
+ if (gpfs_add_trace_fn == NULL) {
+ return;
+ }
+
+ gpfs_add_trace_fn(level, msg);
+}
+
+void gpfswrap_fini_trace(void)
+{
+ if (gpfs_fini_trace_fn == NULL) {
+ return;
+ }
+
+ gpfs_fini_trace_fn();
+}
+
+int gpfswrap_fstat_x(int fd, unsigned int *litemask,
+ struct gpfs_iattr64 *iattr, size_t len)
+{
+ if (gpfs_fstat_x_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_fstat_x_fn(fd, litemask, iattr, len);
+}
+
+int gpfswrap_stat_x(const char *pathname, unsigned int *litemask,
+ struct gpfs_iattr64 *iattr, size_t len)
+{
+ if (gpfs_stat_x_fn == NULL) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ return gpfs_stat_x_fn(pathname, litemask, iattr, len);
+}
diff --git a/lib/util/gpfswrap.h b/lib/util/gpfswrap.h
new file mode 100644
index 0000000..e387a56
--- /dev/null
+++ b/lib/util/gpfswrap.h
@@ -0,0 +1,57 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Wrapper for GPFS library
+ * Copyright (C) Christian Ambach <cambach1@de.ibm.com> 2006
+ * Copyright (C) Christof Schmitt 2015
+ *
+ * Major code contributions by Chetan Shringarpure <chetan.sh@in.ibm.com>
+ * and Gomati Mohanan <gomati.mohanan@in.ibm.com>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GPFSWRAP_H__
+#define __GPFSWRAP_H__
+
+#include <gpfs.h>
+
+int gpfswrap_init(void);
+int gpfswrap_set_share(int fd, unsigned int allow, unsigned int deny);
+int gpfswrap_set_lease(int fd, unsigned int type);
+int gpfswrap_fgetacl(int fd, int flags, void *acl);
+int gpfswrap_putacl(const char *pathname, int flags, void *acl);
+int gpfswrap_get_realfilename_path(const char *pathname,
+ char *filenamep,
+ int *len);
+int gpfswrap_register_cifs_export(void);
+int gpfswrap_set_winattrs_path(const char *pathname,
+ int flags,
+ struct gpfs_winattr *attrs);
+int gpfswrap_set_winattrs(int fd, int flags, struct gpfs_winattr *attrs);
+int gpfswrap_get_winattrs(int fd, struct gpfs_winattr *attrs);
+int gpfswrap_ftruncate(int fd, gpfs_off64_t length);
+int gpfswrap_lib_init(int flags);
+int gpfswrap_set_times(int fd, int flags, gpfs_timestruc_t times[4]);
+int gpfswrap_set_times_path(char *path, int flags, gpfs_timestruc_t times[4]);
+int gpfswrap_quotactl(const char *pathname, int cmd, int id, void *bufp);
+int gpfswrap_init_trace(void);
+int gpfswrap_query_trace(void);
+void gpfswrap_add_trace(int level, const char *msg);
+void gpfswrap_fini_trace(void);
+int gpfswrap_fstat_x(int fd, unsigned int *litemask,
+ struct gpfs_iattr64 *iattr, size_t len);
+int gpfswrap_stat_x(const char *pathname, unsigned int *litemask,
+ struct gpfs_iattr64 *iattr, size_t len);
+
+#endif
diff --git a/lib/util/idtree.c b/lib/util/idtree.c
new file mode 100644
index 0000000..7f08b42
--- /dev/null
+++ b/lib/util/idtree.c
@@ -0,0 +1,395 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ very efficient functions to manage mapping a id (such as a fnum) to
+ a pointer. This is used for fnum and search id allocation.
+
+ Copyright (C) Andrew Tridgell 2004
+
+ This code is derived from lib/idr.c in the 2.6 Linux kernel, which was
+ written by Jim Houston jim.houston@ccur.com, and is
+ Copyright (C) 2002 by Concurrent Computer Corporation
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ see the section marked "public interface" below for documentation
+*/
+
+/**
+ * @file
+ */
+
+#include "replace.h"
+#include <talloc.h>
+#include "debug.h"
+#include "idtree.h"
+
+#define IDR_BITS 5
+#define IDR_FULL 0xfffffffful
+#if 0 /* unused */
+#define TOP_LEVEL_FULL (IDR_FULL >> 30)
+#endif
+#define IDR_SIZE (1 << IDR_BITS)
+#define IDR_MASK ((1 << IDR_BITS)-1)
+#define MAX_ID_SHIFT (sizeof(int)*8 - 1)
+#define MAX_ID_BIT (1U << MAX_ID_SHIFT)
+#define MAX_ID_MASK (MAX_ID_BIT - 1)
+#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS
+#define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL
+
+#define set_bit(bit, v) (v) |= (1U<<(bit))
+#define clear_bit(bit, v) (v) &= ~(1U<<(bit))
+#define test_bit(bit, v) ((v) & (1U<<(bit)))
+
+struct idr_layer {
+ uint32_t bitmap;
+ struct idr_layer *ary[IDR_SIZE];
+ int count;
+};
+
+struct idr_context {
+ struct idr_layer *top;
+ struct idr_layer *id_free;
+ int layers;
+ int id_free_cnt;
+};
+
+static struct idr_layer *alloc_layer(struct idr_context *idp)
+{
+ struct idr_layer *p;
+
+ if (!(p = idp->id_free))
+ return NULL;
+ idp->id_free = p->ary[0];
+ idp->id_free_cnt--;
+ p->ary[0] = NULL;
+ return p;
+}
+
+static int find_next_bit(uint32_t bm, int maxid, int n)
+{
+ while (n<maxid && !test_bit(n, bm)) n++;
+ return n;
+}
+
+static void free_layer(struct idr_context *idp, struct idr_layer *p)
+{
+ p->ary[0] = idp->id_free;
+ idp->id_free = p;
+ idp->id_free_cnt++;
+}
+
+static int idr_pre_get(struct idr_context *idp)
+{
+ while (idp->id_free_cnt < IDR_FREE_MAX) {
+ struct idr_layer *pn = talloc_zero(idp, struct idr_layer);
+ if(pn == NULL)
+ return (0);
+ free_layer(idp, pn);
+ }
+ return 1;
+}
+
+static int sub_alloc(struct idr_context *idp, void *ptr, int *starting_id)
+{
+ int n, m, sh;
+ struct idr_layer *p, *pn;
+ struct idr_layer *pa[MAX_LEVEL+1];
+ unsigned int l, id, oid;
+ uint32_t bm;
+
+ memset(pa, 0, sizeof(pa));
+
+ id = *starting_id;
+restart:
+ p = idp->top;
+ l = idp->layers;
+ pa[l--] = NULL;
+ while (1) {
+ /*
+ * We run around this while until we reach the leaf node...
+ */
+ n = (id >> (IDR_BITS*l)) & IDR_MASK;
+ bm = ~p->bitmap;
+ m = find_next_bit(bm, IDR_SIZE, n);
+ if (m == IDR_SIZE) {
+ /* no space available go back to previous layer. */
+ l++;
+ oid = id;
+ id = (id | ((1 << (IDR_BITS*l))-1)) + 1;
+
+ /* if already at the top layer, we need to grow */
+ if (!(p = pa[l])) {
+ *starting_id = id;
+ return -2;
+ }
+
+ /* If we need to go up one layer, continue the
+ * loop; otherwise, restart from the top.
+ */
+ sh = IDR_BITS * (l + 1);
+ if (oid >> sh == id >> sh)
+ continue;
+ else
+ goto restart;
+ }
+ if (m != n) {
+ sh = IDR_BITS*l;
+ id = ((id >> sh) ^ n ^ m) << sh;
+ }
+ if (id >= MAX_ID_BIT)
+ return -1;
+ if (l == 0)
+ break;
+ /*
+ * Create the layer below if it is missing.
+ */
+ if (!p->ary[m]) {
+ if (!(pn = alloc_layer(idp)))
+ return -1;
+ p->ary[m] = pn;
+ p->count++;
+ }
+ pa[l--] = p;
+ p = p->ary[m];
+ }
+ /*
+ * We have reached the leaf node, plant the
+ * users pointer and return the raw id.
+ */
+ p->ary[m] = (struct idr_layer *)ptr;
+ set_bit(m, p->bitmap);
+ p->count++;
+ /*
+ * If this layer is full mark the bit in the layer above
+ * to show that this part of the radix tree is full.
+ * This may complete the layer above and require walking
+ * up the radix tree.
+ */
+ n = id;
+ while (p->bitmap == IDR_FULL) {
+ if (l >= MAX_LEVEL) {
+ break;
+ }
+ p = pa[++l];
+ if (p == NULL) {
+ break;
+ }
+ n = n >> IDR_BITS;
+ set_bit((n & IDR_MASK), p->bitmap);
+ }
+ return(id);
+}
+
+static int idr_get_new_above_int(struct idr_context *idp, void *ptr, int starting_id)
+{
+ struct idr_layer *p, *pn;
+ int layers, v, id;
+
+ idr_pre_get(idp);
+
+ id = starting_id;
+build_up:
+ p = idp->top;
+ layers = idp->layers;
+ if (!p) {
+ if (!(p = alloc_layer(idp)))
+ return -1;
+ layers = 1;
+ }
+ /*
+ * Add a new layer to the top of the tree if the requested
+ * id is larger than the currently allocated space.
+ */
+ while ((layers < MAX_LEVEL) && (id >= (1 << (layers*IDR_BITS)))) {
+ layers++;
+ if (!p->count)
+ continue;
+ if (!(pn = alloc_layer(idp))) {
+ /*
+ * The allocation failed. If we built part of
+ * the structure tear it down.
+ */
+ for (pn = p; p && p != idp->top; pn = p) {
+ p = p->ary[0];
+ pn->ary[0] = NULL;
+ pn->bitmap = pn->count = 0;
+ free_layer(idp, pn);
+ }
+ return -1;
+ }
+ pn->ary[0] = p;
+ pn->count = 1;
+ if (p->bitmap == IDR_FULL)
+ set_bit(0, pn->bitmap);
+ p = pn;
+ }
+ idp->top = p;
+ idp->layers = layers;
+ v = sub_alloc(idp, ptr, &id);
+ if (v == -2)
+ goto build_up;
+ return(v);
+}
+
+static int sub_remove(struct idr_context *idp, int shift, int id)
+{
+ struct idr_layer *p = idp->top;
+ struct idr_layer **pa[1+MAX_LEVEL];
+ struct idr_layer ***paa = &pa[0];
+ int n;
+
+ *paa = NULL;
+ *++paa = &idp->top;
+
+ while ((shift > 0) && p) {
+ n = (id >> shift) & IDR_MASK;
+ clear_bit(n, p->bitmap);
+ *++paa = &p->ary[n];
+ p = p->ary[n];
+ shift -= IDR_BITS;
+ }
+ n = id & IDR_MASK;
+ if (p != NULL && test_bit(n, p->bitmap)) {
+ clear_bit(n, p->bitmap);
+ p->ary[n] = NULL;
+ while(*paa && ! --((**paa)->count)){
+ free_layer(idp, **paa);
+ **paa-- = NULL;
+ }
+ if ( ! *paa )
+ idp->layers = 0;
+ return 0;
+ }
+ return -1;
+}
+
+static void *_idr_find(struct idr_context *idp, int id)
+{
+ int n;
+ struct idr_layer *p;
+
+ n = idp->layers * IDR_BITS;
+ p = idp->top;
+ /*
+ * This tests to see if bits outside the current tree are
+ * present. If so, tain't one of ours!
+ */
+ if (n + IDR_BITS < 31 &&
+ ((id & ~(~0U << MAX_ID_SHIFT)) >> (n + IDR_BITS))) {
+ return NULL;
+ }
+
+ /* Mask off upper bits we don't use for the search. */
+ id &= MAX_ID_MASK;
+
+ while (n >= IDR_BITS && p) {
+ n -= IDR_BITS;
+ p = p->ary[(id >> n) & IDR_MASK];
+ }
+ return((void *)p);
+}
+
+static int _idr_remove(struct idr_context *idp, int id)
+{
+ struct idr_layer *p;
+
+ /* Mask off upper bits we don't use for the search. */
+ id &= MAX_ID_MASK;
+
+ if (sub_remove(idp, (idp->layers - 1) * IDR_BITS, id) == -1) {
+ return -1;
+ }
+
+ if ( idp->top && idp->top->count == 1 &&
+ (idp->layers > 1) &&
+ idp->top->ary[0]) {
+ /* We can drop a layer */
+ p = idp->top->ary[0];
+ idp->top->bitmap = idp->top->count = 0;
+ free_layer(idp, idp->top);
+ idp->top = p;
+ --idp->layers;
+ }
+ while (idp->id_free_cnt >= IDR_FREE_MAX) {
+ p = alloc_layer(idp);
+ talloc_free(p);
+ }
+ return 0;
+}
+
+/************************************************************************
+ this is the public interface
+**************************************************************************/
+
+/**
+ initialise a idr tree. The context return value must be passed to
+ all subsequent idr calls. To destroy the idr tree use talloc_free()
+ on this context
+ */
+_PUBLIC_ struct idr_context *idr_init(TALLOC_CTX *mem_ctx)
+{
+ return talloc_zero(mem_ctx, struct idr_context);
+}
+
+/**
+ allocate the next available id, and assign 'ptr' into its slot.
+ you can retrieve later this pointer using idr_find()
+*/
+_PUBLIC_ int idr_get_new(struct idr_context *idp, void *ptr, int limit)
+{
+ int ret = idr_get_new_above_int(idp, ptr, 0);
+ if (ret > limit) {
+ idr_remove(idp, ret);
+ return -1;
+ }
+ return ret;
+}
+
+/**
+ allocate a new id, giving the first available value greater than or
+ equal to the given starting id
+*/
+_PUBLIC_ int idr_get_new_above(struct idr_context *idp, void *ptr, int starting_id, int limit)
+{
+ int ret = idr_get_new_above_int(idp, ptr, starting_id);
+ if (ret > limit) {
+ idr_remove(idp, ret);
+ return -1;
+ }
+ return ret;
+}
+
+/**
+ find a pointer value previously set with idr_get_new given an id
+*/
+_PUBLIC_ void *idr_find(struct idr_context *idp, int id)
+{
+ return _idr_find(idp, id);
+}
+
+/**
+ remove an id from the idr tree
+*/
+_PUBLIC_ int idr_remove(struct idr_context *idp, int id)
+{
+ int ret;
+ ret = _idr_remove((struct idr_context *)idp, id);
+ if (ret != 0) {
+ DEBUG(0,("WARNING: attempt to remove unset id %d in idtree\n", id));
+ }
+ return ret;
+}
diff --git a/lib/util/idtree.h b/lib/util/idtree.h
new file mode 100644
index 0000000..79d2d8c
--- /dev/null
+++ b/lib/util/idtree.h
@@ -0,0 +1,63 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ very efficient functions to manage mapping a id (such as a fnum) to
+ a pointer. This is used for fnum and search id allocation.
+
+ Copyright (C) Andrew Tridgell 2004
+
+ This code is derived from lib/idr.c in the 2.6 Linux kernel, which was
+ written by Jim Houston jim.houston@ccur.com, and is
+ Copyright (C) 2002 by Concurrent Computer Corporation
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_IDTREE_H_
+#define _SAMBA_IDTREE_H_
+
+#include <talloc.h>
+
+struct idr_context;
+
+/**
+ initialise a idr tree. The context return value must be passed to
+ all subsequent idr calls. To destroy the idr tree use talloc_free()
+ on this context
+ */
+struct idr_context *idr_init(TALLOC_CTX *mem_ctx);
+
+/**
+ allocate the next available id, and assign 'ptr' into its slot.
+ you can retrieve later this pointer using idr_find()
+*/
+int idr_get_new(struct idr_context *idp, void *ptr, int limit);
+
+/**
+ allocate a new id, giving the first available value greater than or
+ equal to the given starting id
+*/
+int idr_get_new_above(struct idr_context *idp, void *ptr, int starting_id, int limit);
+
+/**
+ find a pointer value previously set with idr_get_new given an id
+*/
+void *idr_find(struct idr_context *idp, int id);
+
+/**
+ remove an id from the idr tree
+*/
+int idr_remove(struct idr_context *idp, int id);
+
+#endif /* _SAMBA_IDTREE_H_ */
diff --git a/lib/util/idtree_random.c b/lib/util/idtree_random.c
new file mode 100644
index 0000000..d22245a
--- /dev/null
+++ b/lib/util/idtree_random.c
@@ -0,0 +1,68 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ very efficient functions to manage mapping a id (such as a fnum) to
+ a pointer. This is used for fnum and search id allocation.
+
+ Copyright (C) Andrew Tridgell 2004
+
+ This code is derived from lib/idr.c in the 2.6 Linux kernel, which was
+ written by Jim Houston jim.houston@ccur.com, and is
+ Copyright (C) 2002 by Concurrent Computer Corporation
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ see the section marked "public interface" below for documentation
+*/
+
+/**
+ * @file
+ */
+
+#include "replace.h"
+#include "samba_util.h" /* generate_random() */
+#include "idtree.h"
+#include "idtree_random.h"
+
+/**
+ allocate a new id randomly in the given range
+*/
+_PUBLIC_ int idr_get_new_random(struct idr_context *idp,
+ void *ptr,
+ int starting_id,
+ int limit)
+{
+ int id;
+
+ /* first try a random starting point in the whole range, and if that fails,
+ then start randomly in the bottom half of the range. This can only
+ fail if the range is over half full, and finally fallback to any
+ free id */
+ id = idr_get_new_above(
+ idp, ptr, starting_id+(generate_random() % limit), limit);
+ if (id == -1) {
+ id = idr_get_new_above(
+ idp,
+ ptr,
+ starting_id+(generate_random()%(limit/2)),
+ limit);
+ }
+ if (id == -1) {
+ id = idr_get_new_above(idp, ptr, starting_id, limit);
+ }
+
+ return id;
+}
diff --git a/lib/util/idtree_random.h b/lib/util/idtree_random.h
new file mode 100644
index 0000000..623147c
--- /dev/null
+++ b/lib/util/idtree_random.h
@@ -0,0 +1,41 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ very efficient functions to manage mapping a id (such as a fnum) to
+ a pointer. This is used for fnum and search id allocation.
+
+ Copyright (C) Andrew Tridgell 2004
+
+ This code is derived from lib/idr.c in the 2.6 Linux kernel, which was
+ written by Jim Houston jim.houston@ccur.com, and is
+ Copyright (C) 2002 by Concurrent Computer Corporation
+
+ 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_IDTREE_RANDOM_H_
+#define _SAMBA_IDTREE_RANDOM_H_
+
+#include <talloc.h>
+#include "idtree.h"
+
+/**
+ allocate a new id randomly in the given range
+*/
+int idr_get_new_random(struct idr_context *idp,
+ void *ptr,
+ int starting_id,
+ int limit);
+
+#endif /* _SAMBA_IDTREE_RANDOM_H_ */
diff --git a/lib/util/iov_buf.c b/lib/util/iov_buf.c
new file mode 100644
index 0000000..0c18466
--- /dev/null
+++ b/lib/util/iov_buf.c
@@ -0,0 +1,43 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba system utilities
+ * Copyright (C) Volker Lendecke 2014
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "iov_buf.h"
+#include <talloc.h>
+
+uint8_t *iov_concat(TALLOC_CTX *mem_ctx, const struct iovec *iov, int count)
+{
+ ssize_t buflen;
+ uint8_t *buf;
+
+ buflen = iov_buflen(iov, count);
+ if (buflen == -1) {
+ return NULL;
+ }
+
+ buf = talloc_array(mem_ctx, uint8_t, buflen);
+ if (buf == NULL) {
+ return NULL;
+ }
+
+ iov_buf(iov, count, buf, buflen);
+
+ return buf;
+}
diff --git a/lib/util/iov_buf.h b/lib/util/iov_buf.h
new file mode 100644
index 0000000..cb330de
--- /dev/null
+++ b/lib/util/iov_buf.h
@@ -0,0 +1,102 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba system utilities
+ * Copyright (C) Volker Lendecke 2014
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIB_IOV_BUF_H__
+#define __LIB_IOV_BUF_H__
+
+#include "replace.h"
+#include <talloc.h>
+#include "system/filesys.h"
+
+static inline
+ssize_t iov_buf(const struct iovec *iov, int iovcnt,
+ uint8_t *buf, size_t buflen)
+{
+ size_t needed = 0;
+ uint8_t *p = buf;
+ int i;
+
+ for (i=0; i<iovcnt; i++) {
+ size_t thislen = iov[i].iov_len;
+ size_t tmp;
+
+ tmp = needed + thislen;
+
+ if (tmp < needed) {
+ /* wrap */
+ return -1;
+ }
+ needed = tmp;
+
+ if ((p != NULL) && needed <= buflen && thislen > 0) {
+ memcpy(p, iov[i].iov_base, thislen);
+ p += thislen;
+ }
+ }
+
+ return needed;
+}
+
+static inline
+ssize_t iov_buflen(const struct iovec *iov, int iovcnt)
+{
+ return iov_buf(iov, iovcnt, NULL, 0);
+}
+
+static inline
+bool iov_advance(struct iovec **iov, int *iovcnt, size_t n)
+{
+ struct iovec *v = *iov;
+ int cnt = *iovcnt;
+
+ while (n > 0) {
+ if (cnt == 0) {
+ return false;
+ }
+ if (n < v->iov_len) {
+ v->iov_base = (char *)v->iov_base + n;
+ v->iov_len -= n;
+ break;
+ }
+ n -= v->iov_len;
+ v += 1;
+ cnt -= 1;
+ }
+
+ /*
+ * Skip 0-length iovec's
+ *
+ * There might be empty buffers at the end of iov. Next time we do a
+ * readv/writev based on this iov would give 0 transferred bytes, also
+ * known as EPIPE. So we need to be careful discarding them.
+ */
+
+ while ((cnt > 0) && (v->iov_len == 0)) {
+ v += 1;
+ cnt -= 1;
+ }
+
+ *iov = v;
+ *iovcnt = cnt;
+ return true;
+}
+
+uint8_t *iov_concat(TALLOC_CTX *mem_ctx, const struct iovec *iov, int count);
+
+#endif
diff --git a/lib/util/mainpage.dox b/lib/util/mainpage.dox
new file mode 100644
index 0000000..464151e
--- /dev/null
+++ b/lib/util/mainpage.dox
@@ -0,0 +1,11 @@
+/**
+
+\mainpage util
+
+\section Introduction
+
+This library contains convenience functions that are used heavily
+throughout Samba. None of these functions are SMB or Samba-specific.
+It's a bit to Samba what GLib is to the GNOME folks.
+
+*/
diff --git a/lib/util/memcache.c b/lib/util/memcache.c
new file mode 100644
index 0000000..98e317c
--- /dev/null
+++ b/lib/util/memcache.c
@@ -0,0 +1,467 @@
+/*
+ Unix SMB/CIFS implementation.
+ In-memory cache
+ Copyright (C) Volker Lendecke 2007
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include <talloc.h>
+#include "../lib/util/debug.h"
+#include "../lib/util/samba_util.h"
+#include "../lib/util/dlinklist.h"
+#include "../lib/util/rbtree.h"
+#include "memcache.h"
+
+static struct memcache *global_cache;
+
+struct memcache_talloc_value {
+ void *ptr;
+ size_t len;
+};
+
+struct memcache_element {
+ struct rb_node rb_node;
+ struct memcache_element *prev, *next;
+ size_t keylength, valuelength;
+ uint8_t n; /* This is really an enum, but save memory */
+ char data[1]; /* placeholder for offsetof */
+};
+
+struct memcache {
+ struct memcache_element *mru;
+ struct rb_root tree;
+ size_t size;
+ size_t max_size;
+};
+
+static void memcache_element_parse(struct memcache_element *e,
+ DATA_BLOB *key, DATA_BLOB *value);
+
+static bool memcache_is_talloc(enum memcache_number n)
+{
+ bool result;
+
+ switch (n) {
+ case GETPWNAM_CACHE:
+ case PDB_GETPWSID_CACHE:
+ case SINGLETON_CACHE_TALLOC:
+ case SHARE_MODE_LOCK_CACHE:
+ case GETWD_CACHE:
+ case VIRUSFILTER_SCAN_RESULTS_CACHE_TALLOC:
+ result = true;
+ break;
+ default:
+ result = false;
+ break;
+ }
+
+ return result;
+}
+
+static int memcache_destructor(struct memcache *cache) {
+ struct memcache_element *e, *next;
+
+ for (e = cache->mru; e != NULL; e = next) {
+ next = e->next;
+ TALLOC_FREE(e);
+ }
+ return 0;
+}
+
+struct memcache *memcache_init(TALLOC_CTX *mem_ctx, size_t max_size)
+{
+ struct memcache *result;
+
+ result = talloc_zero(mem_ctx, struct memcache);
+ if (result == NULL) {
+ return NULL;
+ }
+ result->max_size = max_size;
+ talloc_set_destructor(result, memcache_destructor);
+ return result;
+}
+
+void memcache_set_global(struct memcache *cache)
+{
+ TALLOC_FREE(global_cache);
+ global_cache = cache;
+}
+
+static struct memcache_element *memcache_node2elem(struct rb_node *node)
+{
+ return (struct memcache_element *)
+ ((char *)node - offsetof(struct memcache_element, rb_node));
+}
+
+static void memcache_element_parse(struct memcache_element *e,
+ DATA_BLOB *key, DATA_BLOB *value)
+{
+ key->data = ((uint8_t *)e) + offsetof(struct memcache_element, data);
+ key->length = e->keylength;
+ value->data = key->data + e->keylength;
+ value->length = e->valuelength;
+}
+
+static size_t memcache_element_size(size_t key_length, size_t value_length)
+{
+ return sizeof(struct memcache_element) - 1 + key_length + value_length;
+}
+
+static int memcache_compare(struct memcache_element *e, enum memcache_number n,
+ DATA_BLOB key)
+{
+ DATA_BLOB this_key, this_value;
+
+ if ((int)e->n < (int)n) return 1;
+ if ((int)e->n > (int)n) return -1;
+
+ if (e->keylength < key.length) return 1;
+ if (e->keylength > key.length) return -1;
+
+ memcache_element_parse(e, &this_key, &this_value);
+ return memcmp(this_key.data, key.data, key.length);
+}
+
+static struct memcache_element *memcache_find(
+ struct memcache *cache, enum memcache_number n, DATA_BLOB key)
+{
+ struct rb_node *node;
+
+ node = cache->tree.rb_node;
+
+ while (node != NULL) {
+ struct memcache_element *elem = memcache_node2elem(node);
+ int cmp;
+
+ cmp = memcache_compare(elem, n, key);
+ if (cmp == 0) {
+ return elem;
+ }
+ node = (cmp < 0) ? node->rb_left : node->rb_right;
+ }
+
+ return NULL;
+}
+
+bool memcache_lookup(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key, DATA_BLOB *value)
+{
+ struct memcache_element *e;
+
+ if (cache == NULL) {
+ cache = global_cache;
+ }
+ if (cache == NULL) {
+ return false;
+ }
+
+ e = memcache_find(cache, n, key);
+ if (e == NULL) {
+ return false;
+ }
+
+ if (cache->size != 0) {
+ DLIST_PROMOTE(cache->mru, e);
+ }
+
+ memcache_element_parse(e, &key, value);
+ return true;
+}
+
+void *memcache_lookup_talloc(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key)
+{
+ DATA_BLOB value;
+ struct memcache_talloc_value mtv;
+
+ if (!memcache_lookup(cache, n, key, &value)) {
+ return NULL;
+ }
+
+ if (value.length != sizeof(mtv)) {
+ return NULL;
+ }
+
+ memcpy(&mtv, value.data, sizeof(mtv));
+
+ return mtv.ptr;
+}
+
+static void memcache_delete_element(struct memcache *cache,
+ struct memcache_element *e)
+{
+ rb_erase(&e->rb_node, &cache->tree);
+
+ DLIST_REMOVE(cache->mru, e);
+
+ if (memcache_is_talloc(e->n)) {
+ DATA_BLOB cache_key, cache_value;
+ struct memcache_talloc_value mtv;
+
+ memcache_element_parse(e, &cache_key, &cache_value);
+ SMB_ASSERT(cache_value.length == sizeof(mtv));
+ memcpy(&mtv, cache_value.data, sizeof(mtv));
+ cache->size -= mtv.len;
+ TALLOC_FREE(mtv.ptr);
+ }
+
+ cache->size -= memcache_element_size(e->keylength, e->valuelength);
+
+ TALLOC_FREE(e);
+}
+
+static void memcache_trim(struct memcache *cache, struct memcache_element *e)
+{
+ struct memcache_element *tail = NULL;
+
+ if (cache->max_size == 0) {
+ return;
+ }
+
+ for (tail = DLIST_TAIL(cache->mru);
+ (cache->size > cache->max_size) && (tail != NULL);
+ tail = DLIST_TAIL(cache->mru))
+ {
+ if (tail == e) {
+ tail = DLIST_PREV(tail);
+ if (tail == NULL) {
+ break;
+ }
+ }
+ memcache_delete_element(cache, tail);
+ }
+}
+
+void memcache_delete(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key)
+{
+ struct memcache_element *e;
+
+ if (cache == NULL) {
+ cache = global_cache;
+ }
+ if (cache == NULL) {
+ return;
+ }
+
+ e = memcache_find(cache, n, key);
+ if (e == NULL) {
+ return;
+ }
+
+ memcache_delete_element(cache, e);
+}
+
+bool memcache_add(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key, DATA_BLOB value)
+{
+ struct memcache_element *e;
+ struct rb_node **p;
+ struct rb_node *parent;
+ DATA_BLOB cache_key, cache_value;
+ size_t element_size;
+
+ if (cache == NULL) {
+ cache = global_cache;
+ }
+ if (cache == NULL) {
+ return false;
+ }
+
+ if (key.length == 0) {
+ return false;
+ }
+
+ e = memcache_find(cache, n, key);
+
+ if (e != NULL) {
+ memcache_element_parse(e, &cache_key, &cache_value);
+
+ if (value.length <= cache_value.length) {
+ if (memcache_is_talloc(e->n)) {
+ struct memcache_talloc_value mtv;
+
+ SMB_ASSERT(cache_value.length == sizeof(mtv));
+ memcpy(&mtv, cache_value.data, sizeof(mtv));
+ cache->size -= mtv.len;
+ TALLOC_FREE(mtv.ptr);
+ }
+ /*
+ * We can reuse the existing record
+ */
+ memcpy(cache_value.data, value.data, value.length);
+ e->valuelength = value.length;
+
+ if (memcache_is_talloc(e->n)) {
+ struct memcache_talloc_value mtv;
+
+ SMB_ASSERT(cache_value.length == sizeof(mtv));
+ memcpy(&mtv, cache_value.data, sizeof(mtv));
+ cache->size += mtv.len;
+ }
+ return true;
+ }
+
+ memcache_delete_element(cache, e);
+ }
+
+ element_size = memcache_element_size(key.length, value.length);
+
+ e = talloc_size(cache, element_size);
+ if (e == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ return false;
+ }
+ talloc_set_type(e, struct memcache_element);
+
+ e->n = n;
+ e->keylength = key.length;
+ e->valuelength = value.length;
+
+ memcache_element_parse(e, &cache_key, &cache_value);
+ memcpy(cache_key.data, key.data, key.length);
+ memcpy(cache_value.data, value.data, value.length);
+
+ parent = NULL;
+ p = &cache->tree.rb_node;
+
+ while (*p) {
+ struct memcache_element *elem = memcache_node2elem(*p);
+ int cmp;
+
+ parent = (*p);
+
+ cmp = memcache_compare(elem, n, key);
+
+ p = (cmp < 0) ? &(*p)->rb_left : &(*p)->rb_right;
+ }
+
+ rb_link_node(&e->rb_node, parent, p);
+ rb_insert_color(&e->rb_node, &cache->tree);
+
+ DLIST_ADD(cache->mru, e);
+
+ cache->size += element_size;
+ if (memcache_is_talloc(e->n)) {
+ struct memcache_talloc_value mtv;
+
+ SMB_ASSERT(cache_value.length == sizeof(mtv));
+ memcpy(&mtv, cache_value.data, sizeof(mtv));
+ cache->size += mtv.len;
+ }
+ memcache_trim(cache, e);
+
+ return true;
+}
+
+bool memcache_add_talloc(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key, void *pptr)
+{
+ struct memcache_talloc_value mtv;
+ void **ptr = (void **)pptr;
+
+ if (cache == NULL) {
+ cache = global_cache;
+ }
+ if (cache == NULL) {
+ return false;
+ }
+
+ mtv.len = talloc_total_size(*ptr);
+ mtv.ptr = talloc_move(cache, ptr);
+
+ return memcache_add(cache, n, key, data_blob_const(&mtv, sizeof(mtv)));
+}
+
+void memcache_flush(struct memcache *cache, enum memcache_number n)
+{
+ struct rb_node *node;
+
+ if (cache == NULL) {
+ cache = global_cache;
+ }
+ if (cache == NULL) {
+ return;
+ }
+
+ /*
+ * Find the smallest element of number n
+ */
+
+ node = cache->tree.rb_node;
+ if (node == NULL) {
+ return;
+ }
+
+ /*
+ * First, find *any* element of number n
+ */
+
+ while (true) {
+ struct memcache_element *elem = memcache_node2elem(node);
+ struct rb_node *next;
+
+ if ((int)elem->n == (int)n) {
+ break;
+ }
+
+ if ((int)elem->n < (int)n) {
+ next = node->rb_right;
+ }
+ else {
+ next = node->rb_left;
+ }
+ if (next == NULL) {
+ break;
+ }
+ node = next;
+ }
+
+ /*
+ * Then, find the leftmost element with number n
+ */
+
+ while (true) {
+ struct rb_node *prev = rb_prev(node);
+ struct memcache_element *elem;
+
+ if (prev == NULL) {
+ break;
+ }
+ elem = memcache_node2elem(prev);
+ if ((int)elem->n != (int)n) {
+ break;
+ }
+ node = prev;
+ }
+
+ while (node != NULL) {
+ struct memcache_element *e = memcache_node2elem(node);
+ struct rb_node *next = rb_next(node);
+
+ if (e->n != n) {
+ break;
+ }
+
+ memcache_delete_element(cache, e);
+ node = next;
+ }
+}
+
+void gfree_memcache(void)
+{
+ TALLOC_FREE(global_cache);
+}
diff --git a/lib/util/memcache.h b/lib/util/memcache.h
new file mode 100644
index 0000000..6986760
--- /dev/null
+++ b/lib/util/memcache.h
@@ -0,0 +1,119 @@
+/*
+ Unix SMB/CIFS implementation.
+ In-memory cache
+ Copyright (C) Volker Lendecke 2007-2008
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __MEMCACHE_H__
+#define __MEMCACHE_H__
+
+#include <talloc.h>
+#include "lib/util/data_blob.h"
+
+struct memcache;
+
+/*
+ * A memcache can store different subkeys with overlapping keys, the
+ * memcache_number becomes part of the key. Feel free to add caches of your
+ * own here.
+ *
+ * If you add talloc type caches, also note this in the switch statement in
+ * memcache_is_talloc().
+ */
+
+enum memcache_number {
+ STAT_CACHE,
+ GETREALFILENAME_CACHE,
+ GETWD_CACHE,
+ GETPWNAM_CACHE, /* talloc */
+ MANGLE_HASH2_CACHE,
+ PDB_GETPWSID_CACHE, /* talloc */
+ SINGLETON_CACHE_TALLOC, /* talloc */
+ SINGLETON_CACHE,
+ SMB1_SEARCH_OFFSET_MAP,
+ SHARE_MODE_LOCK_CACHE, /* talloc */
+ VIRUSFILTER_SCAN_RESULTS_CACHE_TALLOC, /* talloc */
+ DFREE_CACHE,
+};
+
+/*
+ * Create a memcache structure. max_size is in bytes, if you set it 0 it will
+ * not forget anything.
+ */
+
+struct memcache *memcache_init(TALLOC_CTX *mem_ctx, size_t max_size);
+
+/*
+ * If you set this global memcache, use it as the default cache when NULL is
+ * passed to the memcache functions below. This is a workaround for many
+ * situations where passing the cache everywhere would be a big hassle.
+ */
+
+void memcache_set_global(struct memcache *cache);
+
+/*
+ * Add a data blob to the cache
+ */
+
+bool memcache_add(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key, DATA_BLOB value);
+
+/*
+ * Add a talloc object to the cache. The difference to memcache_add() is that
+ * when the objects is to be discarded, talloc_free is called for it. Also
+ * talloc_move() ownership of the object to the cache.
+ *
+ * Please note that the current implementation has a fixed relationship
+ * between what cache subtypes store talloc objects and which ones store plain
+ * blobs. We can fix this, but for now we don't have a mixed use of blobs vs
+ * talloc objects in the cache types.
+ */
+
+bool memcache_add_talloc(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key, void *ptr);
+
+/*
+ * Delete an object from the cache
+ */
+
+void memcache_delete(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key);
+
+/*
+ * Look up an object from the cache. Memory still belongs to the cache, so
+ * make a copy of it if needed.
+ */
+
+bool memcache_lookup(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key, DATA_BLOB *value);
+
+/*
+ * Look up an object from the cache. Memory still belongs to the cache, so
+ * make a copy of it if needed.
+ */
+
+void *memcache_lookup_talloc(struct memcache *cache, enum memcache_number n,
+ DATA_BLOB key);
+
+/*
+ * Flush a complete cache subset.
+ */
+
+void memcache_flush(struct memcache *cache, enum memcache_number n);
+
+void gfree_memcache(void);
+
+#endif
diff --git a/lib/util/memory.h b/lib/util/memory.h
new file mode 100644
index 0000000..40c66d8
--- /dev/null
+++ b/lib/util/memory.h
@@ -0,0 +1,129 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_MEMORY_H_
+#define _SAMBA_MEMORY_H_
+
+#ifndef SAFE_FREE /* Oh no this is also defined in tdb.h */
+/**
+ * Free memory if the pointer and zero the pointer.
+ *
+ * @note You are explicitly allowed to pass NULL pointers -- they will
+ * always be ignored.
+ **/
+#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0)
+#endif
+
+/**
+ * Zero string and free memory if the pointer and zero the pointer.
+ *
+ * @note You are explicitly allowed to pass NULL pointers -- they will
+ * always be ignored.
+ **/
+#define BURN_FREE_STR(x) do { \
+ if ((x) != NULL) { \
+ size_t s = strlen(x); \
+ memset_s((x), s, 0, s); \
+ free(x); (x) = NULL; \
+ } \
+ } while(0)
+
+/**
+ * Zero and free memory if the pointer and zero the pointer.
+ *
+ * @note You are explicitly allowed to pass NULL pointers -- they will
+ * always be ignored.
+ **/
+#define BURN_FREE(x, s) do { \
+ if ((x) != NULL) { \
+ memset_s((x), (s), 0, (s)); \
+ free(x); (x) = NULL; \
+ } \
+ } while(0)
+
+/**
+ * Type-safe version of malloc. Allocated one copy of the
+ * specified data type.
+ */
+#define malloc_p(type) (type *)malloc(sizeof(type))
+
+/**
+ * Allocate an array of elements of one data type. Does type-checking.
+ */
+#define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type), count, false)
+
+/**
+ * Resize an array of elements of one data type. Does type-checking.
+ */
+#define realloc_p(p, type, count) (type *)realloc_array(p, sizeof(type), count, false)
+
+/**
+ * Zero a structure.
+ */
+#ifndef ZERO_STRUCT
+#define ZERO_STRUCT(x) memset_s((char *)&(x), sizeof(x), 0, sizeof(x))
+#endif
+
+/**
+ * Zero a structure given a pointer to the structure.
+ */
+#ifndef ZERO_STRUCTP
+#define ZERO_STRUCTP(x) do { \
+ if ((x) != NULL) { \
+ memset_s((char *)(x), sizeof(*(x)), 0, sizeof(*(x))); \
+ } \
+} while(0)
+#endif
+
+/**
+ * Zero a structure given a pointer to the structure - no zero check.
+ */
+#ifndef ZERO_STRUCTPN
+#define ZERO_STRUCTPN(x) memset_s((char *)(x), sizeof(*(x)), 0, sizeof(*(x)))
+#endif
+
+/**
+ * Zero an array - note that sizeof(array) must work - ie. it must not be a
+ * pointer.
+ */
+#ifndef ZERO_ARRAY
+#define ZERO_ARRAY(x) memset_s((char *)(x), sizeof(x), 0, sizeof(x))
+#endif
+
+/**
+ * Zero a given len of an array
+ */
+#define ZERO_ARRAY_LEN(x, l) memset_s((char *)(x), (l), 0, (l))
+
+/**
+ * Work out how many elements there are in a static array
+ */
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
+#endif
+
+/**
+ * Pointer difference macro.
+ */
+#ifndef PTR_DIFF
+#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((const char *)(p1)) - (const char *)(p2)))
+#endif
+
+#endif /* _SAMBA_MEMORY_H_ */
diff --git a/lib/util/mkdir_p.c b/lib/util/mkdir_p.c
new file mode 100644
index 0000000..87a3f79
--- /dev/null
+++ b/lib/util/mkdir_p.c
@@ -0,0 +1,70 @@
+/*
+ mkdir -p
+
+ Copyright (C) Amitay Isaacs 2014
+ Copyright (C) Martin Schwenke 2014
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+#include "replace.h"
+#include <sys/stat.h>
+#include <libgen.h>
+#include "mkdir_p.h"
+
+int mkdir_p(const char *dir, int mode)
+{
+ char t[PATH_MAX];
+ ssize_t len;
+ int ret;
+
+ if (strcmp(dir, "/") == 0) {
+ return 0;
+ }
+
+ if (strcmp(dir, ".") == 0) {
+ return 0;
+ }
+
+ /* Try to create directory */
+ ret = mkdir(dir, mode);
+ /* Succeed if that worked or if it already existed */
+ if (ret == 0 || errno == EEXIST) {
+ return 0;
+ }
+ /* Fail on anything else except ENOENT */
+ if (errno != ENOENT) {
+ return ret;
+ }
+
+ /* Create ancestors */
+ len = strlen(dir);
+ ret = snprintf(t, sizeof(t), "%s", dir);
+ if (ret != len) {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ ret = mkdir_p(dirname(t), mode);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* Create directory */
+ ret = mkdir(dir, mode);
+ if ((ret == -1) && (errno == EEXIST)) {
+ ret = 0;
+ }
+
+ return ret;
+}
diff --git a/lib/util/mkdir_p.h b/lib/util/mkdir_p.h
new file mode 100644
index 0000000..9281de8
--- /dev/null
+++ b/lib/util/mkdir_p.h
@@ -0,0 +1,21 @@
+/*
+ mkdir -p
+
+ Copyright (C) Amitay Isaacs 2014
+ Copyright (C) Martin Schwenke 2014
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+int mkdir_p(const char *dir, int mode);
diff --git a/lib/util/modules.c b/lib/util/modules.c
new file mode 100644
index 0000000..4260234
--- /dev/null
+++ b/lib/util/modules.c
@@ -0,0 +1,320 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Jelmer Vernooij 2002-2003,2005-2007
+ Copyright (C) Stefan (metze) Metzmacher 2003
+ Copyright (C) Andrew Bartlett 2011
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "dynconfig/dynconfig.h"
+#include "lib/util/samba_modules.h"
+#include "lib/util/util_paths.h"
+#include "system/filesys.h"
+#include "system/dir.h"
+
+/**
+ * Obtain the init function from a shared library file
+ */
+init_module_fn load_module(const char *path, bool is_probe, void **handle_out)
+{
+ void *handle;
+ void *init_fn;
+ char *error;
+
+ /* This should be a WAF build, where modules should be built
+ * with no undefined symbols and are already linked against
+ * the libraries that they are loaded by */
+ handle = dlopen(path, RTLD_NOW);
+
+ /* This call should reset any possible non-fatal errors that
+ occurred since last call to dl* functions */
+ error = dlerror();
+
+ if (handle == NULL) {
+ int level = is_probe ? 5 : 0;
+ DEBUG(level, ("Error loading module '%s': %s\n", path, error ? error : ""));
+ return NULL;
+ }
+
+ init_fn = (init_module_fn)dlsym(handle, SAMBA_INIT_MODULE);
+
+ /* we could check dlerror() to determine if it worked, because
+ dlsym() can validly return NULL, but what would we do with
+ a NULL pointer as a module init function? */
+
+ if (init_fn == NULL) {
+ DEBUG(0, ("Unable to find %s() in %s: %s\n",
+ SAMBA_INIT_MODULE, path, dlerror()));
+ DEBUG(1, ("Loading module '%s' failed\n", path));
+ dlclose(handle);
+ return NULL;
+ }
+
+ if (handle_out) {
+ *handle_out = handle;
+ }
+
+ return (init_module_fn)init_fn;
+}
+
+/**
+ * Obtain list of init functions from the modules in the specified
+ * directory
+ */
+static init_module_fn *load_modules(TALLOC_CTX *mem_ctx, const char *path)
+{
+ DIR *dir;
+ struct dirent *entry;
+ char *filename;
+ int success = 0;
+ init_module_fn *ret = talloc_array(mem_ctx, init_module_fn, 2);
+
+ ret[0] = NULL;
+
+ dir = opendir(path);
+ if (dir == NULL) {
+ talloc_free(ret);
+ return NULL;
+ }
+
+ while((entry = readdir(dir))) {
+ if (ISDOT(entry->d_name) || ISDOTDOT(entry->d_name))
+ continue;
+
+ filename = talloc_asprintf(mem_ctx, "%s/%s", path, entry->d_name);
+
+ ret[success] = load_module(filename, true, NULL);
+ if (ret[success]) {
+ ret = talloc_realloc(mem_ctx, ret, init_module_fn, success+2);
+ success++;
+ ret[success] = NULL;
+ }
+
+ talloc_free(filename);
+ }
+
+ closedir(dir);
+
+ return ret;
+}
+
+/**
+ * Run the specified init functions.
+ *
+ * @return true if all functions ran successfully, false otherwise
+ */
+bool run_init_functions(TALLOC_CTX *ctx, init_module_fn *fns)
+{
+ int i;
+ bool ret = true;
+
+ if (fns == NULL)
+ return true;
+
+ for (i = 0; fns[i]; i++) { ret &= (bool)NT_STATUS_IS_OK(fns[i](ctx)); }
+
+ return ret;
+}
+
+/**
+ * Load the initialization functions from DSO files for a specific subsystem.
+ *
+ * Will return an array of function pointers to initialization functions
+ */
+
+init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, const char *subsystem)
+{
+ char *path = modules_path(mem_ctx, subsystem);
+ init_module_fn *ret;
+
+ ret = load_modules(mem_ctx, path);
+
+ talloc_free(path);
+
+ return ret;
+}
+
+static NTSTATUS load_module_absolute_path(const char *module_path,
+ bool is_probe)
+{
+ void *handle;
+ init_module_fn init;
+ NTSTATUS status;
+
+ DBG_INFO("%s module '%s'\n",
+ is_probe ? "Probing" : "Loading",
+ module_path);
+
+ init = load_module(module_path, is_probe, &handle);
+ if (init == NULL) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ DBG_NOTICE("Module '%s' loaded\n", module_path);
+
+ status = init(NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("Module '%s' initialization failed: %s\n",
+ module_path,
+ get_friendly_nt_error_msg(status));
+ dlclose(handle);
+ return status;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/* Load all modules in list and return number of
+ * modules that has been successfully loaded */
+int smb_load_all_modules_absoute_path(const char **modules)
+{
+ int i;
+ int success = 0;
+
+ for(i = 0; modules[i] != NULL; i++) {
+ const char *module = modules[i];
+ NTSTATUS status;
+
+ if (module[0] != '/') {
+ continue;
+ }
+
+ status = load_module_absolute_path(module, false);
+ if (NT_STATUS_IS_OK(status)) {
+ success++;
+ }
+ }
+
+ DEBUG(2, ("%d modules successfully loaded\n", success));
+
+ return success;
+}
+
+/**
+ * @brief Check if a module exist and load it.
+ *
+ * @param[in] subsystem The name of the subsystem the module belongs too.
+ *
+ * @param[in] module The name of the module
+ *
+ * @return A NTSTATUS code
+ */
+NTSTATUS smb_probe_module(const char *subsystem, const char *module)
+{
+ NTSTATUS status;
+ char *module_path = NULL;
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+
+ if (subsystem == NULL) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+ if (module == NULL) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
+ if (strchr(module, '/')) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
+ module_path = talloc_asprintf(tmp_ctx,
+ "%s/%s.%s",
+ modules_path(tmp_ctx, subsystem),
+ module,
+ shlib_ext());
+ if (module_path == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ status = load_module_absolute_path(module_path, true);
+
+done:
+ TALLOC_FREE(tmp_ctx);
+ return status;
+}
+
+/**
+ * @brief Check if a module exist and load it.
+ *
+ * Warning: Using this function can have security implecations!
+ *
+ * @param[in] subsystem The name of the subsystem the module belongs too.
+ *
+ * @param[in] module Load a module using an absolute path.
+ *
+ * @return A NTSTATUS code
+ */
+NTSTATUS smb_probe_module_absolute_path(const char *module)
+{
+ if (module == NULL) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ if (module[0] != '/') {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ return load_module_absolute_path(module, true);
+}
+
+/**
+ * @brief Load a module.
+ *
+ * @param[in] subsystem The name of the subsystem the module belongs too.
+ *
+ * @param[in] module Check if a module exists and load it.
+ *
+ * @return A NTSTATUS code
+ */
+NTSTATUS smb_load_module(const char *subsystem, const char *module)
+{
+ NTSTATUS status;
+ char *module_path = NULL;
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+
+ if (subsystem == NULL) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+ if (module == NULL) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
+ if (strchr(module, '/')) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
+ module_path = talloc_asprintf(tmp_ctx,
+ "%s/%s.%s",
+ modules_path(tmp_ctx, subsystem),
+ module,
+ shlib_ext());
+ if (module_path == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ status = load_module_absolute_path(module_path, false);
+
+done:
+ TALLOC_FREE(tmp_ctx);
+ return status;
+}
diff --git a/lib/util/ms_fnmatch.c b/lib/util/ms_fnmatch.c
new file mode 100644
index 0000000..48454a8
--- /dev/null
+++ b/lib/util/ms_fnmatch.c
@@ -0,0 +1,249 @@
+/*
+ Unix SMB/CIFS implementation.
+ filename matching routine
+ Copyright (C) Andrew Tridgell 1992-2004
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ This module was originally based on fnmatch.c copyright by the Free
+ Software Foundation. It bears little (if any) resemblance to that
+ code now
+*/
+
+/**
+ * @file
+ * @brief MS-style Filename matching
+ */
+
+#include "replace.h"
+#include "lib/util/samba_util.h"
+#include "libcli/smb/smb_constants.h"
+
+static int null_match(const char *p)
+{
+ for (;*p;p++) {
+ if (*p != '*' &&
+ *p != '<' &&
+ *p != '"' &&
+ *p != '>') return -1;
+ }
+ return 0;
+}
+
+/*
+ the max_n structure is purely for efficiency, it doesn't contribute
+ to the matching algorithm except by ensuring that the algorithm does
+ not grow exponentially
+*/
+struct max_n {
+ const char *predot;
+ const char *postdot;
+};
+
+
+/*
+ p and n are the pattern and string being matched. The max_n array is
+ an optimisation only. The ldot pointer is NULL if the string does
+ not contain a '.', otherwise it points at the last dot in 'n'.
+*/
+static int ms_fnmatch_core(const char *p, const char *n,
+ struct max_n *max_n, const char *ldot,
+ bool is_case_sensitive)
+{
+ codepoint_t c, c2;
+ int i;
+ size_t size, size_n;
+
+ while ((c = next_codepoint(p, &size))) {
+ p += size;
+
+ switch (c) {
+ case '*':
+ /* a '*' matches zero or more characters of any type */
+ if (max_n != NULL && max_n->predot &&
+ max_n->predot <= n) {
+ return null_match(p);
+ }
+ for (i=0; n[i]; i += size_n) {
+ next_codepoint(n+i, &size_n);
+ if (ms_fnmatch_core(p, n+i, max_n+1, ldot, is_case_sensitive) == 0) {
+ return 0;
+ }
+ }
+ if (max_n != NULL && (!max_n->predot ||
+ max_n->predot > n)) {
+ max_n->predot = n;
+ }
+ return null_match(p);
+
+ case '<':
+ /* a '<' matches zero or more characters of
+ any type, but stops matching at the last
+ '.' in the string. */
+ if (max_n != NULL && max_n->predot &&
+ max_n->predot <= n) {
+ return null_match(p);
+ }
+ if (max_n != NULL && max_n->postdot &&
+ max_n->postdot <= n && n <= ldot) {
+ return -1;
+ }
+ for (i=0; n[i]; i += size_n) {
+ next_codepoint(n+i, &size_n);
+ if (ms_fnmatch_core(p, n+i, max_n+1, ldot, is_case_sensitive) == 0) return 0;
+ if (n+i == ldot) {
+ if (ms_fnmatch_core(p, n+i+size_n, max_n+1, ldot, is_case_sensitive) == 0) return 0;
+ if (max_n != NULL) {
+ if (!max_n->postdot ||
+ max_n->postdot > n) {
+ max_n->postdot = n;
+ }
+ }
+ return -1;
+ }
+ }
+ if (max_n != NULL && (!max_n->predot ||
+ max_n->predot > n)) {
+ max_n->predot = n;
+ }
+ return null_match(p);
+
+ case '?':
+ /* a '?' matches any single character */
+ if (! *n) {
+ return -1;
+ }
+ next_codepoint(n, &size_n);
+ n += size_n;
+ break;
+
+ case '>':
+ /* a '?' matches any single character, but
+ treats '.' specially */
+ if (n[0] == '.') {
+ if (! n[1] && null_match(p) == 0) {
+ return 0;
+ }
+ break;
+ }
+ if (! *n) return null_match(p);
+ next_codepoint(n, &size_n);
+ n += size_n;
+ break;
+
+ case '"':
+ /* a bit like a soft '.' */
+ if (*n == 0 && null_match(p) == 0) {
+ return 0;
+ }
+ if (*n != '.') return -1;
+ next_codepoint(n, &size_n);
+ n += size_n;
+ break;
+
+ default:
+ c2 = next_codepoint(n, &size_n);
+ if (c != c2) {
+ if (is_case_sensitive) {
+ return -1;
+ }
+ if (codepoint_cmpi(c, c2) != 0) {
+ return -1;
+ }
+ }
+ n += size_n;
+ break;
+ }
+ }
+
+ if (! *n) {
+ return 0;
+ }
+
+ return -1;
+}
+
+int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol,
+ bool is_case_sensitive)
+{
+ int ret = -1;
+ size_t count, i;
+
+ if (strcmp(string, "..") == 0) {
+ string = ".";
+ }
+
+ if (strpbrk(pattern, "<>*?\"") == NULL) {
+ /* this is not just an optimisation - it is essential
+ for LANMAN1 correctness */
+ return strcasecmp_m(pattern, string);
+ }
+
+ if (protocol <= PROTOCOL_LANMAN2) {
+ char *p = talloc_strdup(NULL, pattern);
+ if (p == NULL) {
+ return -1;
+ }
+ /*
+ for older negotiated protocols it is possible to
+ translate the pattern to produce a "new style"
+ pattern that exactly matches w2k behaviour
+ */
+ for (i=0;p[i];i++) {
+ if (p[i] == '?') {
+ p[i] = '>';
+ } else if (p[i] == '.' &&
+ (p[i+1] == '?' ||
+ p[i+1] == '*' ||
+ p[i+1] == 0)) {
+ p[i] = '"';
+ } else if (p[i] == '*' &&
+ p[i+1] == '.') {
+ p[i] = '<';
+ }
+ }
+ ret = ms_fnmatch_protocol(p, string, PROTOCOL_NT1,
+ is_case_sensitive);
+ talloc_free(p);
+ return ret;
+ }
+
+ for (count=i=0;pattern[i];i++) {
+ if (pattern[i] == '*' || pattern[i] == '<') count++;
+ }
+
+ /* If the pattern includes '*' or '<' */
+ if (count >= 1) {
+ struct max_n max_n[count];
+
+ memset(max_n, 0, sizeof(struct max_n) * count);
+
+ ret = ms_fnmatch_core(pattern, string, max_n, strrchr(string, '.'),
+ is_case_sensitive);
+ } else {
+ ret = ms_fnmatch_core(pattern, string, NULL, strrchr(string, '.'),
+ is_case_sensitive);
+ }
+
+ return ret;
+}
+
+
+/** a generic fnmatch function - uses for non-CIFS pattern matching */
+int gen_fnmatch(const char *pattern, const char *string)
+{
+ return ms_fnmatch_protocol(pattern, string, PROTOCOL_NT1, false);
+}
diff --git a/lib/util/msghdr.c b/lib/util/msghdr.c
new file mode 100644
index 0000000..3a1d6f5
--- /dev/null
+++ b/lib/util/msghdr.c
@@ -0,0 +1,273 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Copyright (C) Volker Lendecke 2014
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "lib/util/msghdr.h"
+#include "lib/util/iov_buf.h"
+#include <sys/socket.h>
+
+#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
+
+ssize_t msghdr_prep_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
+ const int *fds, size_t num_fds)
+{
+ size_t fds_size = sizeof(int) * MIN(num_fds, INT8_MAX);
+ size_t cmsg_len = CMSG_LEN(fds_size);
+ size_t cmsg_space = CMSG_SPACE(fds_size);
+ struct cmsghdr *cmsg;
+ void *fdptr;
+
+ if (num_fds == 0) {
+ if (msg != NULL) {
+ msg->msg_control = NULL;
+ msg->msg_controllen = 0;
+ }
+ /*
+ * C99 doesn't allow 0-length arrays
+ */
+ return 1;
+ }
+ if (num_fds > INT8_MAX) {
+ return -1;
+ }
+ if ((msg == NULL) || (cmsg_space > bufsize)) {
+ /*
+ * C99 doesn't allow 0-length arrays
+ */
+ return MAX(cmsg_space, 1);
+ }
+
+ msg->msg_control = buf;
+ msg->msg_controllen = cmsg_space;
+
+ cmsg = CMSG_FIRSTHDR(msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = cmsg_len;
+ fdptr = CMSG_DATA(cmsg);
+ memcpy(fdptr, fds, fds_size);
+ msg->msg_controllen = cmsg->cmsg_len;
+
+ return cmsg_space;
+}
+
+size_t msghdr_prep_recv_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
+ size_t num_fds)
+{
+ size_t ret = CMSG_SPACE(sizeof(int) * num_fds);
+
+ if (bufsize < ret) {
+ return ret;
+ }
+ if (msg != NULL) {
+ if (num_fds != 0) {
+ msg->msg_control = buf;
+ msg->msg_controllen = ret;
+ } else {
+ msg->msg_control = NULL;
+ msg->msg_controllen = 0;
+ }
+ }
+ return ret;
+}
+
+size_t msghdr_extract_fds(struct msghdr *msg, int *fds, size_t fds_size)
+{
+ struct cmsghdr *cmsg;
+ size_t num_fds;
+
+ for(cmsg = CMSG_FIRSTHDR(msg);
+ cmsg != NULL;
+ cmsg = CMSG_NXTHDR(msg, cmsg))
+ {
+ if ((cmsg->cmsg_type == SCM_RIGHTS) &&
+ (cmsg->cmsg_level == SOL_SOCKET)) {
+ break;
+ }
+ }
+
+ if (cmsg == NULL) {
+ return 0;
+ }
+
+ num_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
+
+ if ((num_fds != 0) && (fds != NULL) && (fds_size >= num_fds)) {
+ memcpy(fds, CMSG_DATA(cmsg), num_fds * sizeof(int));
+ }
+
+ return num_fds;
+}
+
+#elif defined(HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS)
+
+ssize_t msghdr_prep_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
+ const int *fds, size_t num_fds)
+{
+ size_t needed;
+
+ if (num_fds > INT8_MAX) {
+ return -1;
+ }
+
+ needed = sizeof(int) * num_fds;
+
+ if ((msg == NULL) || (needed > bufsize)) {
+ return needed;
+ }
+
+ memcpy(buf, fds, needed);
+
+ msg->msg_accrights = (caddr_t) buf;
+ msg->msg_accrightslen = needed;
+
+ return needed;
+}
+
+size_t msghdr_prep_recv_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
+ size_t num_fds)
+{
+ size_t ret = num_fds * sizeof(int);
+
+ if (bufsize < ret) {
+ return ret;
+ }
+
+ if (msg != NULL) {
+ if (num_fds != 0) {
+ msg->msg_accrights = (caddr_t) buf;
+ msg->msg_accrightslen = ret;
+ } else {
+ msg->msg_accrights = NULL;
+ msg->msg_accrightslen = 0;
+ }
+ }
+ return ret;
+}
+
+size_t msghdr_extract_fds(struct msghdr *msg, int *fds, size_t fds_size)
+{
+ size_t num_fds = msg->msg_accrightslen / sizeof(int);
+
+ if ((fds != 0) && (num_fds <= fds_size)) {
+ memcpy(fds, msg->msg_accrights, msg->msg_accrightslen);
+ }
+
+ return num_fds;
+}
+
+#else
+
+ssize_t msghdr_prep_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
+ const int *fds, size_t num_fds)
+{
+ return -1;
+}
+
+size_t msghdr_prep_recv_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
+ size_t num_fds)
+{
+ return 0;
+}
+
+size_t msghdr_extract_fds(struct msghdr *msg, int *fds, size_t fds_size)
+{
+ return 0;
+}
+
+#endif
+
+struct msghdr_buf {
+ struct msghdr msg;
+ struct sockaddr_storage addr;
+ struct iovec iov;
+ uint8_t buf[];
+};
+
+ssize_t msghdr_copy(struct msghdr_buf *msg, size_t msgsize,
+ const void *addr, socklen_t addrlen,
+ const struct iovec *iov, int iovcnt,
+ const int *fds, size_t num_fds)
+{
+ ssize_t fd_len;
+ size_t iov_len, needed, bufsize;
+
+ bufsize = (msgsize > offsetof(struct msghdr_buf, buf)) ?
+ msgsize - offsetof(struct msghdr_buf, buf) : 0;
+
+ if (msg != NULL) {
+ msg->msg = (struct msghdr) { 0 };
+
+ fd_len = msghdr_prep_fds(&msg->msg, msg->buf, bufsize,
+ fds, num_fds);
+ } else {
+ fd_len = msghdr_prep_fds(NULL, NULL, bufsize, fds, num_fds);
+ }
+
+ if (fd_len == -1) {
+ return -1;
+ }
+
+ if (bufsize >= (size_t)fd_len) {
+ bufsize -= fd_len;
+ } else {
+ bufsize = 0;
+ }
+
+ if (msg != NULL) {
+
+ if (addr != NULL) {
+ if (addrlen > sizeof(struct sockaddr_storage)) {
+ errno = EMSGSIZE;
+ return -1;
+ }
+ memcpy(&msg->addr, addr, addrlen);
+ msg->msg.msg_name = &msg->addr;
+ msg->msg.msg_namelen = addrlen;
+ } else {
+ msg->msg.msg_name = NULL;
+ msg->msg.msg_namelen = 0;
+ }
+
+ msg->iov.iov_base = msg->buf + fd_len;
+ msg->iov.iov_len = iov_buf(
+ iov, iovcnt, msg->iov.iov_base, bufsize);
+ iov_len = msg->iov.iov_len;
+
+ msg->msg.msg_iov = &msg->iov;
+ msg->msg.msg_iovlen = 1;
+ } else {
+ iov_len = iov_buflen(iov, iovcnt);
+ }
+
+ needed = offsetof(struct msghdr_buf, buf) + fd_len;
+ if (needed < (size_t)fd_len) {
+ return -1;
+ }
+ needed += iov_len;
+ if (needed < iov_len) {
+ return -1;
+ }
+
+ return needed;
+}
+
+struct msghdr *msghdr_buf_msghdr(struct msghdr_buf *msg)
+{
+ return &msg->msg;
+}
diff --git a/lib/util/msghdr.h b/lib/util/msghdr.h
new file mode 100644
index 0000000..c1676d2
--- /dev/null
+++ b/lib/util/msghdr.h
@@ -0,0 +1,42 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Copyright (C) Volker Lendecke 2014
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIB_MSGHDR_H__
+#define __LIB_MSGHDR_H__
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+
+ssize_t msghdr_prep_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
+ const int *fds, size_t num_fds);
+
+struct msghdr_buf;
+
+ssize_t msghdr_copy(struct msghdr_buf *msg, size_t msgsize,
+ const void *addr, socklen_t addrlen,
+ const struct iovec *iov, int iovcnt,
+ const int *fds, size_t num_fds);
+struct msghdr *msghdr_buf_msghdr(struct msghdr_buf *msg);
+
+size_t msghdr_prep_recv_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
+ size_t num_fds);
+size_t msghdr_extract_fds(struct msghdr *msg, int *fds, size_t num_fds);
+
+#endif
diff --git a/lib/util/params.c b/lib/util/params.c
new file mode 100644
index 0000000..dac7782
--- /dev/null
+++ b/lib/util/params.c
@@ -0,0 +1,116 @@
+/* -------------------------------------------------------------------------- **
+ * Microsoft Network Services for Unix, AKA., Andrew Tridgell's SAMBA.
+ *
+ * This module Copyright (C) 1990-1998 Karl Auer
+ *
+ * Rewritten almost completely by Christopher R. Hertel
+ * at the University of Minnesota, September, 1997.
+ * This module Copyright (C) 1997-1998 by the University of Minnesota
+ * -------------------------------------------------------------------------- **
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * Module name: params
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * This module performs lexical analysis and initial parsing of a
+ * Windows-like parameter file. It recognizes and handles four token
+ * types: section-name, parameter-name, parameter-value, and
+ * end-of-file. Comments and line continuation are handled
+ * internally.
+ *
+ * The entry point to the module is function pm_process(). This
+ * function opens the source file, calls the Parse() function to parse
+ * the input, and then closes the file when either the EOF is reached
+ * or a fatal error is encountered.
+ *
+ * A sample parameter file might look like this:
+ *
+ * [section one]
+ * parameter one = value string
+ * parameter two = another value
+ * [section two]
+ * new parameter = some value or t'other
+ *
+ * The parameter file is divided into sections by section headers:
+ * section names enclosed in square brackets (eg. [section one]).
+ * Each section contains parameter lines, each of which consist of a
+ * parameter name and value delimited by an equal sign. Roughly, the
+ * syntax is:
+ *
+ * <file> :== { <section> } EOF
+ *
+ * <section> :== <section header> { <parameter line> }
+ *
+ * <section header> :== '[' NAME ']'
+ *
+ * <parameter line> :== NAME '=' VALUE '\n'
+ *
+ * Blank lines and comment lines are ignored. Comment lines are lines
+ * beginning with either a semicolon (';') or a pound sign ('#').
+ *
+ * All whitespace in section names and parameter names is compressed
+ * to single spaces. Leading and trailing whitespace is stripped from
+ * both names and values.
+ *
+ * Only the first equals sign in a parameter line is significant.
+ * Parameter values may contain equals signs, square brackets and
+ * semicolons. Internal whitespace is retained in parameter values,
+ * with the exception of the '\r' character, which is stripped for
+ * historic reasons. Parameter names may not start with a left square
+ * bracket, an equal sign, a pound sign, or a semicolon, because these
+ * are used to identify other tokens.
+ *
+ * -------------------------------------------------------------------------- **
+ */
+
+#include "replace.h"
+#include "lib/util/samba_util.h"
+#include "tini.h"
+
+bool pm_process(const char *filename,
+ bool (*sfunc)(const char *section, void *private_data),
+ bool (*pfunc)(const char *name, const char *value,
+ void *private_data),
+ void *private_data)
+{
+ bool ret = pm_process_with_flags(
+ filename, false, sfunc, pfunc, private_data);
+ return ret;
+}
+
+bool pm_process_with_flags(const char *filename,
+ bool allow_empty_values,
+ bool (*sfunc)(const char *section, void *private_data),
+ bool (*pfunc)(const char *name, const char *value,
+ void *private_data),
+ void *private_data)
+{
+ FILE *f;
+ bool ret;
+
+ f = fopen(filename, "r");
+ if (f == NULL) {
+ return false;
+ }
+
+ ret = tini_parse(f, allow_empty_values, sfunc, pfunc, private_data);
+
+ fclose(f);
+
+ return ret;
+}
diff --git a/lib/util/pidfile.c b/lib/util/pidfile.c
new file mode 100644
index 0000000..6ffbbea
--- /dev/null
+++ b/lib/util/pidfile.c
@@ -0,0 +1,238 @@
+/*
+ Unix SMB/CIFS implementation.
+ pidfile handling
+ Copyright (C) Andrew Tridgell 1998
+ Copyright (C) Amitay Isaccs 2016
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/filesys.h"
+
+#include "lib/util/blocking.h"
+#include "lib/util/debug.h"
+#include "lib/util/samba_util.h" /* For process_exists_by_pid() */
+
+#include "lib/util/pidfile.h"
+
+int pidfile_path_create(const char *path, int *pfd, pid_t *existing_pid)
+{
+ struct flock lck;
+ char tmp[64] = { 0 };
+ int fd, ret = 0;
+ int len;
+ ssize_t nwritten;
+ bool retried = false;
+
+ fd = open(path, O_CREAT|O_WRONLY|O_NONBLOCK, 0644);
+ if (fd == -1) {
+ return errno;
+ }
+
+ if (! set_close_on_exec(fd)) {
+ ret = errno;
+ goto fail;
+ }
+
+retry:
+ lck = (struct flock) {
+ .l_type = F_WRLCK,
+ .l_whence = SEEK_SET,
+ };
+
+ do {
+ ret = fcntl(fd, F_SETLK, &lck);
+ } while ((ret == -1) && (errno == EINTR));
+
+ if (ret != 0) {
+ ret = errno;
+
+ if ((ret == EACCES) || (ret == EAGAIN)) {
+ do {
+ ret = fcntl(fd, F_GETLK, &lck);
+ } while ((ret == -1) && (errno == EINTR));
+
+ if (ret == -1) {
+ ret = errno;
+ goto fail;
+ }
+
+ if (lck.l_type == F_UNLCK) {
+ if (!retried) {
+ /* Lock holder died, retry once */
+ retried = true;
+ goto retry;
+ }
+ /* Something badly wrong */
+ ret = EIO;
+ goto fail;
+ }
+
+ if (existing_pid != NULL) {
+ *existing_pid = lck.l_pid;
+ }
+ return EAGAIN;
+ }
+ goto fail;
+ }
+
+ /*
+ * PID file is locked by us so from here on we should unlink
+ * on failure
+ */
+ len = snprintf(tmp, sizeof(tmp), "%u\n", getpid());
+ if (len < 0) {
+ ret = errno;
+ goto fail_unlink;
+ }
+ if ((size_t)len >= sizeof(tmp)) {
+ ret = ENOSPC;
+ goto fail_unlink;
+ }
+
+ do {
+ nwritten = write(fd, tmp, len);
+ } while ((nwritten == -1) && (errno == EINTR));
+
+ if ((nwritten == -1) || (nwritten != len)) {
+ ret = errno;
+ goto fail_unlink;
+ }
+
+ do {
+ ret = ftruncate(fd, len);
+ } while ((ret == -1) && (errno == EINTR));
+
+ if (ret == -1) {
+ ret = errno;
+ goto fail_unlink;
+ }
+
+ *pfd = fd;
+ return 0;
+
+fail_unlink:
+ unlink(path);
+fail:
+ close(fd);
+ return ret;
+}
+
+void pidfile_fd_close(int fd)
+{
+ struct flock lck = {
+ .l_type = F_UNLCK,
+ .l_whence = SEEK_SET,
+ };
+ int ret;
+
+ do {
+ ret = fcntl(fd, F_SETLK, &lck);
+ } while ((ret == -1) && (errno == EINTR));
+
+ do {
+ ret = close(fd);
+ } while ((ret == -1) && (errno == EINTR));
+}
+
+
+/**
+ * return the pid in a pidfile. return 0 if the process (or pidfile)
+ * does not exist
+ */
+pid_t pidfile_pid(const char *piddir, const char *name)
+{
+ size_t len = strlen(piddir) + strlen(name) + 6;
+ char pidFile[len];
+ int fd;
+ char pidstr[20] = { 0, };
+ pid_t ret = -1;
+
+ snprintf(pidFile, sizeof(pidFile), "%s/%s.pid", piddir, name);
+
+ fd = open(pidFile, O_NONBLOCK | O_RDONLY, 0644);
+
+ if (fd == -1) {
+ return 0;
+ }
+
+ if (read(fd, pidstr, sizeof(pidstr)-1) <= 0) {
+ goto noproc;
+ }
+
+ ret = (pid_t)atoi(pidstr);
+ if (ret <= 0) {
+ DEBUG(1, ("Could not parse contents of pidfile %s\n",
+ pidFile));
+ goto noproc;
+ }
+
+ if (!process_exists_by_pid(ret)) {
+ DEBUG(10, ("Process with PID=%d does not exist.\n", (int)ret));
+ goto noproc;
+ }
+
+ if (fcntl_lock(fd,F_SETLK,0,1,F_RDLCK)) {
+ /* we could get the lock - it can't be a Samba process */
+ DEBUG(10, ("Process with PID=%d is not a Samba process.\n",
+ (int)ret));
+ goto noproc;
+ }
+
+ close(fd);
+ DEBUG(10, ("Process with PID=%d is running.\n", (int)ret));
+ return ret;
+
+ noproc:
+ close(fd);
+ return 0;
+}
+
+/**
+ * create a pid file in the pid directory. open it and leave it locked
+ */
+void pidfile_create(const char *piddir, const char *name)
+{
+ size_t len = strlen(piddir) + strlen(name) + 6;
+ char pidFile[len];
+ pid_t pid = (pid_t)-1;
+ int ret, fd;
+
+ snprintf(pidFile, sizeof(pidFile), "%s/%s.pid", piddir, name);
+
+ ret = pidfile_path_create(pidFile, &fd, &pid);
+ if (ret == EAGAIN) {
+ DEBUG(0,("ERROR: %s is already running. File %s exists and process id %d is running.\n",
+ name, pidFile, (int)pid));
+ exit(1);
+ }
+
+ /* Leave pid file open & locked for the duration... */
+}
+
+void pidfile_unlink(const char *piddir, const char *name)
+{
+ size_t len = strlen(piddir) + strlen(name) + 6;
+ char pidFile[len];
+ int ret;
+
+ snprintf(pidFile, sizeof(pidFile), "%s/%s.pid", piddir, name);
+
+ ret = unlink(pidFile);
+ if (ret == -1) {
+ DEBUG(0,("Failed to delete pidfile %s. Error was %s\n",
+ pidFile, strerror(errno)));
+ }
+}
diff --git a/lib/util/pidfile.h b/lib/util/pidfile.h
new file mode 100644
index 0000000..6f345a9
--- /dev/null
+++ b/lib/util/pidfile.h
@@ -0,0 +1,85 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Jeremy Allison 2012.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_PIDFILE_H_
+#define _SAMBA_PIDFILE_H_
+
+/**
+ * @file pidfile.h
+ *
+ * @brief PID file handling
+ */
+
+/**
+ * @brief Create a PID file
+ *
+ * Opens file, locks it, and writes PID. Returns EAGAIN if another
+ * process has the PID file locked. Use unlink(2) and
+ * pidfile_fd_close() to remove the PID file.
+ *
+ * @param[in] path PID file name
+ * @param[out] outfd File descriptor of open/locked PID file
+ * @param[out] existing_pid Return existing PID on EAGAIN
+ * @return 0 on success, errno on failure
+ */
+int pidfile_path_create(
+ const char *path, int *outfd, pid_t *existing_pid);
+
+/**
+ * @brief Unlock and close a PID file
+ *
+ * @param[in] fd File descriptor of open/locked PID file
+ */
+void pidfile_fd_close(int fd);
+
+/**
+ * @brief Check a PID file
+ *
+ * PID file name is <piddir>/<name>.pid
+ *
+ * @param[in] piddir Directory for PID file
+ * @param[in] name PID file process name
+ * @return PID of active process, 0 if PID file missing/stale/error
+ */
+pid_t pidfile_pid(const char *piddir, const char *name);
+
+/**
+ * @brief Create a PID file
+ *
+ * Leave PID file open/locked on success, exit on failure. On
+ * success, use pidfile_unlink() to remove PID file before exiting.
+ *
+ * PID file name is <piddir>/<name>.pid
+ *
+ * @param[in] piddir Directory for PID file
+ * @param[in] name PID file process name
+ */
+void pidfile_create(const char *piddir, const char *name);
+
+/**
+ * @brief Remove a PID file
+ *
+ * PID file name is <piddir>/<name>.pid
+ *
+ * @param[in] piddir Directory for PID file
+ * @param[in] name PID file process name
+ */
+void pidfile_unlink(const char *piddir, const char *name);
+
+#endif
diff --git a/lib/util/rbtree.c b/lib/util/rbtree.c
new file mode 100644
index 0000000..aa663f4
--- /dev/null
+++ b/lib/util/rbtree.c
@@ -0,0 +1,429 @@
+/*
+ Red Black Trees
+ (C) 1999 Andrea Arcangeli <andrea@suse.de>
+ (C) 2002 David Woodhouse <dwmw2@infradead.org>
+
+ 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
+
+ linux/lib/rbtree.c
+*/
+
+#include "replace.h"
+#include "rbtree.h"
+#include "fault.h"
+
+#define RB_RED 0
+#define RB_BLACK 1
+
+#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3))
+#define rb_color(r) ((r)->rb_parent_color & 1)
+#define rb_is_red(r) (!rb_color(r))
+#define rb_is_black(r) rb_color(r)
+#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0)
+#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0)
+
+static void rb_set_parent(struct rb_node *rb, struct rb_node *p)
+{
+ rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
+}
+static void rb_set_color(struct rb_node *rb, int color)
+{
+ rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
+}
+
+#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
+#define RB_EMPTY_NODE(node) (rb_parent(node) == node)
+#define RB_CLEAR_NODE(node) (rb_set_parent(node, node))
+
+static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
+{
+ struct rb_node *right = node->rb_right;
+ struct rb_node *parent = rb_parent(node);
+
+ if ((node->rb_right = right->rb_left))
+ rb_set_parent(right->rb_left, node);
+ right->rb_left = node;
+
+ rb_set_parent(right, parent);
+
+ if (parent)
+ {
+ if (node == parent->rb_left)
+ parent->rb_left = right;
+ else
+ parent->rb_right = right;
+ }
+ else
+ root->rb_node = right;
+ rb_set_parent(node, right);
+}
+
+static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
+{
+ struct rb_node *left = node->rb_left;
+ struct rb_node *parent = rb_parent(node);
+
+ if ((node->rb_left = left->rb_right))
+ rb_set_parent(left->rb_right, node);
+ left->rb_right = node;
+
+ rb_set_parent(left, parent);
+
+ if (parent)
+ {
+ if (node == parent->rb_right)
+ parent->rb_right = left;
+ else
+ parent->rb_left = left;
+ }
+ else
+ root->rb_node = left;
+ rb_set_parent(node, left);
+}
+
+void rb_insert_color(struct rb_node *node, struct rb_root *root)
+{
+ struct rb_node *parent, *gparent;
+
+ while ((parent = rb_parent(node)) && rb_is_red(parent))
+ {
+ gparent = rb_parent(parent);
+
+ if (parent == gparent->rb_left)
+ {
+ {
+ register struct rb_node *uncle = gparent->rb_right;
+ if (uncle && rb_is_red(uncle))
+ {
+ rb_set_black(uncle);
+ rb_set_black(parent);
+ rb_set_red(gparent);
+ node = gparent;
+ continue;
+ }
+ }
+
+ if (parent->rb_right == node)
+ {
+ register struct rb_node *tmp;
+ __rb_rotate_left(parent, root);
+ tmp = parent;
+ parent = node;
+ node = tmp;
+ }
+
+ rb_set_black(parent);
+ rb_set_red(gparent);
+ __rb_rotate_right(gparent, root);
+ } else {
+ {
+ register struct rb_node *uncle = gparent->rb_left;
+ if (uncle && rb_is_red(uncle))
+ {
+ rb_set_black(uncle);
+ rb_set_black(parent);
+ rb_set_red(gparent);
+ node = gparent;
+ continue;
+ }
+ }
+
+ if (parent->rb_left == node)
+ {
+ register struct rb_node *tmp;
+ __rb_rotate_right(parent, root);
+ tmp = parent;
+ parent = node;
+ node = tmp;
+ }
+
+ rb_set_black(parent);
+ rb_set_red(gparent);
+ __rb_rotate_left(gparent, root);
+ }
+ }
+
+ rb_set_black(root->rb_node);
+}
+
+static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
+ struct rb_root *root)
+{
+ struct rb_node *other;
+
+ while ((!node || rb_is_black(node)) && node != root->rb_node)
+ {
+ if (parent->rb_left == node)
+ {
+ other = parent->rb_right;
+ if (other == NULL) {
+ /* we should never get here */
+ smb_panic("corrupted rb tree");
+ /* satisfy static checkers */
+ return;
+ }
+ if (rb_is_red(other))
+ {
+ rb_set_black(other);
+ rb_set_red(parent);
+ __rb_rotate_left(parent, root);
+ other = parent->rb_right;
+ }
+ if ((!other->rb_left || rb_is_black(other->rb_left)) &&
+ (!other->rb_right || rb_is_black(other->rb_right)))
+ {
+ rb_set_red(other);
+ node = parent;
+ parent = rb_parent(node);
+ }
+ else
+ {
+ if (!other->rb_right || rb_is_black(other->rb_right))
+ {
+ struct rb_node *o_left;
+ if ((o_left = other->rb_left))
+ rb_set_black(o_left);
+ rb_set_red(other);
+ __rb_rotate_right(other, root);
+ other = parent->rb_right;
+ }
+ rb_set_color(other, rb_color(parent));
+ rb_set_black(parent);
+ if (other->rb_right)
+ rb_set_black(other->rb_right);
+ __rb_rotate_left(parent, root);
+ node = root->rb_node;
+ break;
+ }
+ }
+ else
+ {
+ other = parent->rb_left;
+ if (rb_is_red(other))
+ {
+ rb_set_black(other);
+ rb_set_red(parent);
+ __rb_rotate_right(parent, root);
+ other = parent->rb_left;
+ }
+ if ((!other->rb_left || rb_is_black(other->rb_left)) &&
+ (!other->rb_right || rb_is_black(other->rb_right)))
+ {
+ rb_set_red(other);
+ node = parent;
+ parent = rb_parent(node);
+ }
+ else
+ {
+ if (!other->rb_left || rb_is_black(other->rb_left))
+ {
+ register struct rb_node *o_right;
+ if ((o_right = other->rb_right))
+ rb_set_black(o_right);
+ rb_set_red(other);
+ __rb_rotate_left(other, root);
+ other = parent->rb_left;
+ }
+ rb_set_color(other, rb_color(parent));
+ rb_set_black(parent);
+ if (other->rb_left)
+ rb_set_black(other->rb_left);
+ __rb_rotate_right(parent, root);
+ node = root->rb_node;
+ break;
+ }
+ }
+ }
+ if (node)
+ rb_set_black(node);
+}
+
+void rb_erase(struct rb_node *node, struct rb_root *root)
+{
+ struct rb_node *child, *parent;
+ int color;
+
+ if (!node->rb_left)
+ child = node->rb_right;
+ else if (!node->rb_right)
+ child = node->rb_left;
+ else
+ {
+ struct rb_node *old = node, *left;
+
+ node = node->rb_right;
+ while ((left = node->rb_left) != NULL)
+ node = left;
+ child = node->rb_right;
+ parent = rb_parent(node);
+ color = rb_color(node);
+
+ if (child)
+ rb_set_parent(child, parent);
+ if (parent == old) {
+ parent->rb_right = child;
+ parent = node;
+ } else
+ parent->rb_left = child;
+
+ node->rb_parent_color = old->rb_parent_color;
+ node->rb_right = old->rb_right;
+ node->rb_left = old->rb_left;
+
+ if (rb_parent(old))
+ {
+ if (rb_parent(old)->rb_left == old)
+ rb_parent(old)->rb_left = node;
+ else
+ rb_parent(old)->rb_right = node;
+ } else
+ root->rb_node = node;
+
+ rb_set_parent(old->rb_left, node);
+ if (old->rb_right)
+ rb_set_parent(old->rb_right, node);
+ goto color;
+ }
+
+ parent = rb_parent(node);
+ color = rb_color(node);
+
+ if (child)
+ rb_set_parent(child, parent);
+ if (parent)
+ {
+ if (parent->rb_left == node)
+ parent->rb_left = child;
+ else
+ parent->rb_right = child;
+ }
+ else
+ root->rb_node = child;
+
+ color:
+ if (color == RB_BLACK)
+ __rb_erase_color(child, parent, root);
+}
+
+/*
+ * This function returns the first node (in sort order) of the tree.
+ */
+struct rb_node *rb_first(struct rb_root *root)
+{
+ struct rb_node *n;
+
+ n = root->rb_node;
+ if (!n)
+ return NULL;
+ while (n->rb_left)
+ n = n->rb_left;
+ return n;
+}
+
+struct rb_node *rb_last(struct rb_root *root)
+{
+ struct rb_node *n;
+
+ n = root->rb_node;
+ if (!n)
+ return NULL;
+ while (n->rb_right)
+ n = n->rb_right;
+ return n;
+}
+
+struct rb_node *rb_next(struct rb_node *node)
+{
+ struct rb_node *parent;
+
+ if (rb_parent(node) == node)
+ return NULL;
+
+ /* If we have a right-hand child, go down and then left as far
+ as we can. */
+ if (node->rb_right) {
+ node = node->rb_right;
+ while (node->rb_left)
+ node=node->rb_left;
+ return node;
+ }
+
+ /* No right-hand children. Everything down and left is
+ smaller than us, so any 'next' node must be in the general
+ direction of our parent. Go up the tree; any time the
+ ancestor is a right-hand child of its parent, keep going
+ up. First time it's a left-hand child of its parent, said
+ parent is our 'next' node. */
+ while ((parent = rb_parent(node)) && node == parent->rb_right)
+ node = parent;
+
+ return parent;
+}
+
+struct rb_node *rb_prev(struct rb_node *node)
+{
+ struct rb_node *parent;
+
+ if (rb_parent(node) == node)
+ return NULL;
+
+ /* If we have a left-hand child, go down and then right as far
+ as we can. */
+ if (node->rb_left) {
+ node = node->rb_left;
+ while (node->rb_right)
+ node=node->rb_right;
+ return node;
+ }
+
+ /* No left-hand children. Go up till we find an ancestor which
+ is a right-hand child of its parent */
+ while ((parent = rb_parent(node)) && node == parent->rb_left)
+ node = parent;
+
+ return parent;
+}
+
+void rb_replace_node(struct rb_node *victim, struct rb_node *new_node,
+ struct rb_root *root)
+{
+ struct rb_node *parent = rb_parent(victim);
+
+ /* Set the surrounding nodes to point to the replacement */
+ if (parent) {
+ if (victim == parent->rb_left)
+ parent->rb_left = new_node;
+ else
+ parent->rb_right = new_node;
+ } else {
+ root->rb_node = new_node;
+ }
+ if (victim->rb_left)
+ rb_set_parent(victim->rb_left, new_node);
+ if (victim->rb_right)
+ rb_set_parent(victim->rb_right, new_node);
+
+ /* Copy the pointers/colour from the victim to the replacement */
+ *new_node = *victim;
+}
+
+void rb_link_node(struct rb_node * node, struct rb_node * parent,
+ struct rb_node ** rb_link)
+{
+ node->rb_parent_color = (unsigned long )parent;
+ node->rb_left = node->rb_right = NULL;
+
+ *rb_link = node;
+}
diff --git a/lib/util/rbtree.h b/lib/util/rbtree.h
new file mode 100644
index 0000000..1cfd346
--- /dev/null
+++ b/lib/util/rbtree.h
@@ -0,0 +1,132 @@
+/*
+ Red Black Trees
+ (C) 1999 Andrea Arcangeli <andrea@suse.de>
+
+ 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
+
+ linux/include/linux/rbtree.h
+
+ To use rbtrees you'll have to implement your own insert and search cores.
+ This will avoid us to use callbacks and to drop drammatically performances.
+ I know it's not the cleaner way, but in C (not in C++) to get
+ performances and genericity...
+
+ Some example of insert and search follows here. The search is a plain
+ normal search over an ordered tree. The insert instead must be implemented
+ int two steps: as first thing the code must insert the element in
+ order as a red leaf in the tree, then the support library function
+ rb_insert_color() must be called. Such function will do the
+ not trivial work to rebalance the rbtree if necessary.
+
+-----------------------------------------------------------------------
+static inline struct page * rb_search_page_cache(struct inode * inode,
+ unsigned long offset)
+{
+ struct rb_node * n = inode->i_rb_page_cache.rb_node;
+ struct page * page;
+
+ while (n)
+ {
+ page = rb_entry(n, struct page, rb_page_cache);
+
+ if (offset < page->offset)
+ n = n->rb_left;
+ else if (offset > page->offset)
+ n = n->rb_right;
+ else
+ return page;
+ }
+ return NULL;
+}
+
+static inline struct page * __rb_insert_page_cache(struct inode * inode,
+ unsigned long offset,
+ struct rb_node * node)
+{
+ struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
+ struct rb_node * parent = NULL;
+ struct page * page;
+
+ while (*p)
+ {
+ parent = *p;
+ page = rb_entry(parent, struct page, rb_page_cache);
+
+ if (offset < page->offset)
+ p = &(*p)->rb_left;
+ else if (offset > page->offset)
+ p = &(*p)->rb_right;
+ else
+ return page;
+ }
+
+ rb_link_node(node, parent, p);
+
+ return NULL;
+}
+
+static inline struct page * rb_insert_page_cache(struct inode * inode,
+ unsigned long offset,
+ struct rb_node * node)
+{
+ struct page * ret;
+ if ((ret = __rb_insert_page_cache(inode, offset, node)))
+ goto out;
+ rb_insert_color(node, &inode->i_rb_page_cache);
+ out:
+ return ret;
+}
+-----------------------------------------------------------------------
+*/
+
+#ifndef _LINUX_RBTREE_H
+#define _LINUX_RBTREE_H
+
+struct rb_node
+{
+ unsigned long rb_parent_color;
+ struct rb_node *rb_right;
+ struct rb_node *rb_left;
+};
+
+struct rb_root
+{
+ struct rb_node *rb_node;
+};
+
+
+#define RB_ROOT (struct rb_root) { NULL, }
+
+#if 0
+#define rb_entry(ptr, type, member) container_of(ptr, type, member)
+#endif
+
+void rb_insert_color(struct rb_node *, struct rb_root *);
+void rb_erase(struct rb_node *, struct rb_root *);
+
+/* Find logical next and previous nodes in a tree */
+struct rb_node *rb_next(struct rb_node *);
+struct rb_node *rb_prev(struct rb_node *);
+struct rb_node *rb_first(struct rb_root *);
+struct rb_node *rb_last(struct rb_root *);
+
+/* Fast replacement of a single node without remove/rebalance/add/rebalance */
+extern void rb_replace_node(struct rb_node *victim, struct rb_node *new_node,
+ struct rb_root *root);
+
+void rb_link_node(struct rb_node * node, struct rb_node * parent,
+ struct rb_node ** rb_link);
+
+#endif /* _LINUX_RBTREE_H */
diff --git a/lib/util/rfc1738.c b/lib/util/rfc1738.c
new file mode 100644
index 0000000..7b8db11
--- /dev/null
+++ b/lib/util/rfc1738.c
@@ -0,0 +1,198 @@
+/*
+ * Functions for RFC 3986 percent-encoding.
+ *
+ * NOTE:
+ *
+ * This file was originally imported from the Squid project but has been
+ * significantly altered. The licence below is reproduced intact, but refers
+ * to files in Squid's repository, not in Samba. See COPYING for the GPLv3
+ * notice (being the later version mentioned below).
+ */
+
+/*
+ * $Id$
+ *
+ * DEBUG:
+ * AUTHOR: Harvest Derived
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * 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, USA.
+ *
+ */
+
+#include "replace.h"
+#include <talloc.h>
+#include "lib/util/samba_util.h"
+
+#define RFC1738_ENCODE 1
+#define RFC1738_RESERVED 2
+
+/*
+ * According to RFC 1738, "$-_.+!*'()," are not reserved or unsafe, but as
+ * that has been obsolete since 2004, we sm instead for RFC 3986, where:
+ *
+ * reserved = : / ? # [ ] @ ! $ & ' ( ) * + , ; =
+ * unreserved = ALPHA DIGIT - . _ ~
+ *
+ * and whatever is not in either of those are what RFC 1738 called "unsafe",
+ * meaning that they should are canonically but not mandatorily escaped.
+ *
+ * Characters below 0x20 or above 0x7E are always encoded.
+ */
+
+static const unsigned char escapees[127] = {
+ [' '] = RFC1738_ENCODE,
+ ['"'] = RFC1738_ENCODE,
+ ['%'] = RFC1738_ENCODE,
+ ['<'] = RFC1738_ENCODE,
+ ['>'] = RFC1738_ENCODE,
+ ['\\'] = RFC1738_ENCODE,
+ ['^'] = RFC1738_ENCODE,
+ ['`'] = RFC1738_ENCODE,
+ ['{'] = RFC1738_ENCODE,
+ ['|'] = RFC1738_ENCODE,
+ ['}'] = RFC1738_ENCODE,
+ /* reserved : / ? # [ ] @ ! $ & ' ( ) * + , ; = */
+ [':'] = RFC1738_RESERVED,
+ ['/'] = RFC1738_RESERVED,
+ ['?'] = RFC1738_RESERVED,
+ ['#'] = RFC1738_RESERVED,
+ ['['] = RFC1738_RESERVED,
+ [']'] = RFC1738_RESERVED,
+ ['@'] = RFC1738_RESERVED,
+ ['!'] = RFC1738_RESERVED,
+ ['$'] = RFC1738_RESERVED,
+ ['&'] = RFC1738_RESERVED,
+ ['\''] = RFC1738_RESERVED,
+ ['('] = RFC1738_RESERVED,
+ [')'] = RFC1738_RESERVED,
+ ['*'] = RFC1738_RESERVED,
+ ['+'] = RFC1738_RESERVED,
+ [','] = RFC1738_RESERVED,
+ [';'] = RFC1738_RESERVED,
+ ['='] = RFC1738_RESERVED,
+};
+
+/*
+ * rfc1738_do_escape - fills a preallocated buffer with an escaped version of
+ * the given string.
+ *
+ * For canonical escaping, mask should be RFC1738_ENCODE | RFC1738_RESERVED.
+ * For mandatory escaping, mask should be RFC1738_RESERVED.
+ */
+static char *
+rfc1738_do_escape(char *buf, size_t bufsize,
+ const char *url, size_t len, unsigned char mask)
+{
+ size_t i;
+ size_t j = 0;
+ for (i = 0; i < len; i++) {
+ unsigned int c = (unsigned char) url[i];
+ if (c > 126 || c < 32 || (escapees[c] & mask)) {
+ if (j + 3 >= bufsize) {
+ return NULL;
+ }
+ (void) snprintf(&buf[j], 4, "%%%02X", c);
+ j += 3;
+ } else {
+ if (j + 1 >= bufsize) {
+ return NULL;
+ }
+ buf[j] = c;
+ j++;
+ }
+ }
+ buf[j] = '\0';
+ return buf;
+}
+
+/*
+ * rfc1738_escape_part - Returns a talloced buffer that contains the RFC 3986
+ * compliant, escaped version of the given url segment.
+ */
+char *
+rfc1738_escape_part(TALLOC_CTX *mem_ctx, const char *url)
+{
+ size_t bufsize = 0;
+ char *buf = NULL;
+
+ size_t len = strlen(url);
+ if (len >= SIZE_MAX / 3) {
+ return NULL;
+ }
+
+ bufsize = len * 3 + 1;
+ buf = talloc_array(mem_ctx, char, bufsize);
+ if (buf == NULL) {
+ return NULL;
+ }
+
+ talloc_set_name_const(buf, buf);
+
+ return rfc1738_do_escape(buf, bufsize, url, len,
+ RFC1738_ENCODE | RFC1738_RESERVED);
+}
+
+/*
+ * rfc1738_unescape() - Converts url-escaped characters in the string.
+ *
+ * The two characters following a '%' in a string should be hex digits that
+ * describe an encoded byte. For example, "%25" is hex 0x25 or '%' in ASCII;
+ * this is the only way to include a % in the unescaped string. Any character
+ * can be escaped, including plain letters (e.g. "%61" for "a"). Anything
+ * other than 2 hex characters following the % is an error.
+ *
+ * The conversion is done in-place, which is always safe as unescapes can only
+ * shorten the string.
+ *
+ * Returns a pointer to the end of the string (that is, the '\0' byte), or
+ * NULL on error, at which point s is in an undefined state.
+ *
+ * Note that after `char *e = rfc_unescape(s)`, `strlen(s)` will not equal
+ * `e - s` if s originally contained "%00". You might want to check for this.
+ */
+
+_PUBLIC_ char *rfc1738_unescape(char *s)
+{
+ size_t i, j; /* i is write, j is read */
+ for (i = 0, j = 0; s[j] != '\0'; i++, j++) {
+ if (s[j] == '%') {
+ uint8_t v;
+ bool ok;
+
+ ok = hex_byte(&s[j+1], &v);
+ if (!ok) {
+ return NULL;
+ }
+ j += 2; /* OK; hex_byte() has checked ahead */
+ s[i] = (unsigned char)v;
+ } else {
+ s[i] = s[j];
+ }
+ }
+ s[i] = '\0';
+ return s + i;
+}
diff --git a/lib/util/safe_string.h b/lib/util/safe_string.h
new file mode 100644
index 0000000..edff296
--- /dev/null
+++ b/lib/util/safe_string.h
@@ -0,0 +1,64 @@
+/*
+ Unix SMB/CIFS implementation.
+ Safe string handling routines.
+ Copyright (C) Andrew Tridgell 1994-1998
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAFE_STRING_H
+#define _SAFE_STRING_H
+#ifndef _SPLINT_ /* http://www.splint.org */
+
+/* Some macros to ensure people don't use buffer overflow vulnerable string
+ functions. */
+
+#ifdef bcopy
+#undef bcopy
+#endif /* bcopy */
+#define bcopy(src,dest,size) __ERROR__XX__NEVER_USE_BCOPY___;
+
+#ifdef strcpy
+#undef strcpy
+#endif /* strcpy */
+#define strcpy(dest,src) __ERROR__XX__NEVER_USE_STRCPY___;
+
+#ifdef strcat
+#undef strcat
+#endif /* strcat */
+#define strcat(dest,src) __ERROR__XX__NEVER_USE_STRCAT___;
+
+#ifdef sprintf
+#undef sprintf
+#endif /* sprintf */
+#define sprintf __ERROR__XX__NEVER_USE_SPRINTF__;
+
+/*
+ * strcasecmp/strncasecmp aren't an error, but it means you're not thinking about
+ * multibyte. Don't use them. JRA.
+ */
+#ifdef strcasecmp
+#undef strcasecmp
+#endif
+#define strcasecmp __ERROR__XX__NEVER_USE_STRCASECMP__;
+
+#ifdef strncasecmp
+#undef strncasecmp
+#endif
+#define strncasecmp __ERROR__XX__NEVER_USE_STRNCASECMP__;
+
+#endif /* !_SPLINT_ */
+
+#endif
diff --git a/lib/util/samba-util.pc.in b/lib/util/samba-util.pc.in
new file mode 100644
index 0000000..65876c4
--- /dev/null
+++ b/lib/util/samba-util.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: samba-util
+Description: Samba utility functions
+Requires: talloc tevent
+Version: @PACKAGE_VERSION@
+Libs: @LIB_RPATH@ -L${libdir} -lsamba-util
+Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1
diff --git a/lib/util/samba_modules.h b/lib/util/samba_modules.h
new file mode 100644
index 0000000..c698691
--- /dev/null
+++ b/lib/util/samba_modules.h
@@ -0,0 +1,61 @@
+/*
+ Unix SMB/CIFS implementation.
+ Handling of idle/exit events
+ Copyright (C) Stefan (metze) Metzmacher 2003
+ Copyright (C) Andrew Bartlett 2011
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_MODULES_H
+#define _SAMBA_MODULES_H
+
+/* Module support */
+typedef NTSTATUS (*init_module_fn) (TALLOC_CTX *ctx);
+
+NTSTATUS samba_init_module(TALLOC_CTX *ctx);
+
+/* this needs to be a string which is not in the C library. We
+ previously used "init_module", but that meant that modules which
+ did not define this function ended up calling the C library
+ function init_module() which makes a system call */
+#define SAMBA_INIT_MODULE "samba_init_module"
+
+/**
+ * Obtain the init function from a shared library file.
+ *
+ * The handle to dlclose() in case of error is returns in *handle if handle is not NULL
+ */
+init_module_fn load_module(const char *path, bool is_probe, void **handle);
+
+/**
+ * Run the specified init functions.
+ *
+ * @return true if all functions ran successfully, false otherwise
+ */
+bool run_init_functions(TALLOC_CTX *ctx, init_module_fn *fns);
+
+/**
+ * Load the initialization functions from DSO files for a specific subsystem.
+ *
+ * Will return an array of function pointers to initialization functions
+ */
+init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, const char *subsystem);
+
+int smb_load_all_modules_absoute_path(const char **modules);
+NTSTATUS smb_probe_module(const char *subsystem, const char *module);
+NTSTATUS smb_probe_module_absolute_path(const char *module);
+NTSTATUS smb_load_module(const char *subsystem, const char *module);
+
+#endif /* _SAMBA_MODULES_H */
diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h
new file mode 100644
index 0000000..e672b4b
--- /dev/null
+++ b/lib/util/samba_util.h
@@ -0,0 +1,708 @@
+/*
+ Unix SMB/CIFS implementation.
+ Utility functions for Samba
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Jelmer Vernooij 2005
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_UTIL_H_
+#define _SAMBA_UTIL_H_
+
+#ifndef SAMBA_UTIL_CORE_ONLY
+#include "lib/util/charset/charset.h"
+#else
+#include "charset_compat.h"
+#endif
+
+#include "lib/util/attr.h"
+
+/* for TALLOC_CTX */
+#include <talloc.h>
+
+/* for struct stat */
+#include <sys/stat.h>
+
+/**
+ * @file
+ * @brief Helpful macros
+ */
+
+struct smbsrv_tcon;
+
+extern const char *panic_action;
+
+#include "lib/util/time.h"
+#include "lib/util/data_blob.h"
+#include "lib/util/byteorder.h"
+#include "lib/util/talloc_stack.h"
+#include "lib/util/talloc_keep_secret.h"
+
+#ifndef ABS
+#define ABS(a) ((a)>0?(a):(-(a)))
+#endif
+
+#include "lib/util/memory.h"
+#include "lib/util/discard.h"
+
+#include "fault.h"
+
+#include "lib/util/util.h"
+
+/**
+ * Write backtrace to debug log
+ */
+_PUBLIC_ void dump_core_setup(const char *progname, const char *logfile);
+
+/**
+ register a fault handler.
+ Should only be called once in the execution of smbd.
+*/
+_PUBLIC_ bool register_fault_handler(const char *name, void (*fault_handler)(int sig));
+
+#include "lib/util/signal.h" /* Avoid /usr/include/signal.h */
+
+struct sockaddr;
+
+_PUBLIC_ int sys_getnameinfo(const struct sockaddr *psa,
+ int salen,
+ char *host,
+ size_t hostlen,
+ char *service,
+ size_t servlen,
+ int flags);
+
+/* The following definitions come from lib/util/genrand.c */
+
+#include "lib/util/genrand.h"
+
+/**
+ generate a single random uint32_t
+**/
+_PUBLIC_ uint32_t generate_random(void);
+
+/**
+ * generate a single random uint64_t
+ * @see generate_unique_u64
+**/
+_PUBLIC_ uint64_t generate_random_u64(void);
+
+_PUBLIC_ uint64_t generate_random_u64_range(uint64_t lower, uint64_t upper);
+
+/**
+ * @brief Generate random nonces usable for re-use detection.
+ *
+ * We have a lot of places which require a unique id that can
+ * be used as a unique identitier for caching states.
+ *
+ * Always using generate_nonce_buffer() has it's performance costs,
+ * it's typically much better than generate_random_buffer(), but
+ * still it's overhead we want to avoid in performance critical
+ * workloads.
+ *
+ * We call generate_nonce_buffer() just once per given state
+ * and process.
+ *
+ * This is much lighter than generate_random_u64() and it's
+ * designed for performance critical code paths.
+ *
+ * @veto_value It is guaranteed that the return value is different from
+ * the veto_value.
+ *
+ * @return a unique value per given state and process
+ *
+ * @see generate_random_u64
+ */
+uint64_t generate_unique_u64(uint64_t veto_value);
+
+/**
+ very basic password quality checker
+**/
+_PUBLIC_ bool check_password_quality(const char *s);
+
+/**
+ * Generate a random text password (based on printable ascii characters).
+ * This function is designed to provide a password that
+ * meats the complexity requirements of UF_NORMAL_ACCOUNT objects
+ * and they should be human readable and writeable on any keyboard layout.
+ *
+ * Characters used are:
+ * ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,@$%&!?:;<=>()[]~
+ */
+_PUBLIC_ char *generate_random_password(TALLOC_CTX *mem_ctx, size_t min, size_t max);
+
+/**
+ * Generate a random machine password
+ *
+ * min and max are the number of utf16 characters used
+ * to generate on utf8 compatible password.
+ *
+ * Note: if 'unix charset' is not 'utf8' (the default)
+ * then each utf16 character is only filled with
+ * values from 0x01 to 0x7f (ascii values without 0x00).
+ * This is important as the password neets to be
+ * a valid value as utf8 string and at the same time
+ * a valid value in the 'unix charset'.
+ *
+ * If 'unix charset' is 'utf8' (the default) then
+ * each utf16 character is a random value from 0x0000
+ * 0xFFFF (excluding the surrogate ranges from 0xD800-0xDFFF)
+ * while the translation from CH_UTF16MUNGED
+ * to CH_UTF8 replaces invalid values (see utf16_munged_pull()).
+ *
+ * Note: these passwords may not pass the complexity requirements
+ * for UF_NORMAL_ACCOUNT objects (except krbtgt accounts).
+ */
+_PUBLIC_ char *generate_random_machine_password(TALLOC_CTX *mem_ctx, size_t min, size_t max);
+
+/**
+ Use the random number generator to generate a random string.
+**/
+_PUBLIC_ char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const char *list);
+
+/**
+ * Generate a random text string consisting of the specified length.
+ * The returned string will be allocated.
+ *
+ * Characters used are: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,
+ */
+_PUBLIC_ char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len);
+
+/**
+ * Generate an array of unique text strings all of the same length.
+ * The returned strings will be allocated.
+ * Returns NULL if the number of unique combinations cannot be created.
+ *
+ * Characters used are: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,
+ */
+_PUBLIC_ char** generate_unique_strs(TALLOC_CTX *mem_ctx, size_t len,
+ uint32_t num);
+
+/* The following definitions come from lib/util/dprintf.c */
+
+_PUBLIC_ int d_fprintf(FILE *f, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
+_PUBLIC_ int d_printf(const char *format, ...) PRINTF_ATTRIBUTE(1,2);
+_PUBLIC_ void display_set_stderr(void);
+
+/* The following definitions come from lib/util/util_str.c */
+
+bool next_token_talloc(TALLOC_CTX *ctx,
+ const char **ptr,
+ char **pp_buff,
+ const char *sep);
+
+/**
+ * Get the next token from a string, return false if none found. Handles
+ * double-quotes. This version does not trim leading separator characters
+ * before looking for a token.
+ */
+bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
+ const char **ptr,
+ char **pp_buff,
+ const char *sep);
+
+
+/**
+ Trim the specified elements off the front and back of a string.
+**/
+_PUBLIC_ bool trim_string(char *s, const char *front, const char *back);
+
+/**
+ Find the number of 'c' chars in a string
+**/
+_PUBLIC_ _PURE_ size_t count_chars(const char *s, char c);
+
+/**
+ Routine to get hex characters and turn them into a 16 byte array.
+ the array can be variable length, and any non-hex-numeric
+ characters are skipped. "0xnn" or "0Xnn" is specially catered
+ for.
+
+ valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
+
+
+**/
+_PUBLIC_ size_t strhex_to_str(char *p, size_t p_len, const char *strhex, size_t strhex_len);
+
+/**
+ * Parse a hex string and return a data blob.
+ */
+_PUBLIC_ DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex) ;
+
+/**
+ * Parse a hex dump and return a data blob
+ */
+_PUBLIC_ DATA_BLOB hexdump_to_data_blob(TALLOC_CTX *mem_ctx, const char *hexdump, size_t len);
+
+/**
+ * Print a buf in hex. Assumes dst is at least (srclen*2)+1 large.
+ */
+_PUBLIC_ void hex_encode_buf(char *dst, const uint8_t *src, size_t srclen);
+
+/**
+ * talloc version of hex_encode_buf()
+ */
+_PUBLIC_ char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len);
+
+#include "substitute.h"
+
+/**
+ Unescape a URL encoded string, in place.
+**/
+_PUBLIC_ char *rfc1738_unescape(char *buf);
+
+/**
+ * rfc1738_escape_part
+ * Returns a static buffer that contains the RFC
+ * 1738 compliant, escaped version of the given url segment. (escapes
+ * unsafe, reserved and % chars) It would mangle the :// in http://,
+ * and mangle paths (because of /).
+ **/
+_PUBLIC_ char *rfc1738_escape_part(TALLOC_CTX *mem_ctx, const char *url);
+
+/**
+ variant of strcmp() that handles NULL ptrs
+**/
+_PUBLIC_ int strcmp_safe(const char *s1, const char *s2);
+
+/**
+return the number of bytes occupied by a buffer in ASCII format
+the result includes the null termination
+limited by 'n' bytes
+**/
+_PUBLIC_ size_t ascii_len_n(const char *src, size_t n);
+
+/**
+ Set a boolean variable from the text value stored in the passed string.
+ Returns true in success, false if the passed string does not correctly
+ represent a boolean.
+**/
+_PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean);
+
+/**
+ * Parse a string containing a boolean value.
+ *
+ * val will be set to the read value.
+ *
+ * @retval true if a boolean value was parsed, false otherwise.
+ */
+_PUBLIC_ bool conv_str_bool(const char * str, bool * val);
+
+/**
+ * Convert a size specification like 16K into an integral number of bytes.
+ **/
+_PUBLIC_ bool conv_str_size_error(const char * str, uint64_t * val);
+
+/**
+ * Parse a uint64_t value from a string
+ *
+ * val will be set to the value read.
+ *
+ * @retval true if parsing was successful, false otherwise
+ */
+_PUBLIC_ bool conv_str_u64(const char * str, uint64_t * val);
+
+/**
+ * @brief Constant time compare to memory regions.
+ *
+ * @param[in] s1 The first memory region to compare.
+ *
+ * @param[in] s2 The second memory region to compare.
+ *
+ * @param[in] n The length of the memory to compare.
+ *
+ * @return true when the memory regions are equal, false if not.
+ */
+_PUBLIC_ bool mem_equal_const_time(const void *s1, const void *s2, size_t n);
+
+/**
+Do a case-insensitive, whitespace-ignoring string compare.
+**/
+_PUBLIC_ int strwicmp(const char *psz1, const char *psz2);
+
+/**
+ String replace.
+**/
+_PUBLIC_ void string_replace(char *s, char oldc, char newc);
+
+/**
+ * Compare 2 strings.
+ *
+ * @note The comparison is case-insensitive.
+ **/
+_PUBLIC_ bool strequal(const char *s1, const char *s2);
+
+#include "util_strlist.h"
+
+/* The following definitions come from lib/util/util_strlist_v3.c */
+
+/**
+ * Needed for making an "unconst" list "const"
+ */
+_PUBLIC_ const char **const_str_list(char **list);
+
+/**
+ * str_list_make, v3 version. The v4 version does not
+ * look at quoted strings with embedded blanks, so
+ * do NOT merge this function please!
+ */
+char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
+ const char *sep);
+
+
+const char **str_list_make_v3_const(TALLOC_CTX *mem_ctx,
+ const char *string,
+ const char *sep);
+
+/* The following definitions come from lib/util/util_file.c */
+
+
+/**
+ * Read one line (data until next newline or eof) and allocate it
+ */
+_PUBLIC_ char *afdgets(int fd, TALLOC_CTX *mem_ctx, size_t hint);
+
+char *fgets_slash(TALLOC_CTX *mem_ctx, char *s2, size_t maxlen, FILE *f);
+
+/**
+load a file into memory from a fd.
+**/
+_PUBLIC_ char *fd_load(int fd, size_t *size, size_t maxsize, TALLOC_CTX *mem_ctx);
+
+
+char **file_lines_parse(const char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx);
+
+/**
+load a file into memory
+**/
+_PUBLIC_ char *file_load(const char *fname, size_t *size, size_t maxsize, TALLOC_CTX *mem_ctx);
+
+/**
+load a file into memory and return an array of pointers to lines in the file
+must be freed with talloc_free().
+**/
+_PUBLIC_ char **file_lines_load(const char *fname, int *numlines, size_t maxsize, TALLOC_CTX *mem_ctx);
+
+/**
+load a fd into memory and return an array of pointers to lines in the file
+must be freed with talloc_free(). If convert is true calls unix_to_dos on
+the list.
+**/
+_PUBLIC_ char **fd_lines_load(int fd, int *numlines, size_t maxsize, TALLOC_CTX *mem_ctx);
+
+_PUBLIC_ bool file_save_mode(const char *fname, const void *packet,
+ size_t length, mode_t mode);
+/**
+ save a lump of data into a file. Mostly used for debugging
+*/
+_PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length);
+_PUBLIC_ int vfdprintf(int fd, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0);
+_PUBLIC_ int fdprintf(int fd, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
+
+/*
+ compare two files, return true if the two files have the same content
+ */
+bool file_compare(const char *path1, const char *path2);
+
+/*
+ load from a pipe into memory.
+ */
+char *file_ploadv(char * const argl[], size_t *size);
+
+/* The following definitions come from lib/util/util.c */
+
+
+/**
+ Find a suitable temporary directory. The result should be copied immediately
+ as it may be overwritten by a subsequent call.
+**/
+_PUBLIC_ const char *tmpdir(void);
+
+/**
+ * Creates and immediately unlinks a file. Returns open file descriptor.
+ **/
+_PUBLIC_ int create_unlink_tmp(const char *dir);
+
+/**
+ Check if a file exists - call vfs_file_exist for samba files.
+**/
+_PUBLIC_ bool file_exist(const char *fname);
+
+/**
+ * @brief Return a files modification time.
+ *
+ * @param fname The name of the file.
+ *
+ * @param mt A pointer to store the modification time.
+ *
+ * @return 0 on success, errno otherwise.
+ */
+_PUBLIC_ int file_modtime(const char *fname, struct timespec *mt);
+
+/**
+ Check if a directory exists.
+**/
+_PUBLIC_ bool directory_exist(const char *dname);
+
+/**
+ Check file permissions.
+**/
+_PUBLIC_ bool file_check_permissions(const char *fname,
+ uid_t uid,
+ mode_t file_perms,
+ struct stat *pst);
+
+/**
+ * Try to create the specified directory if it didn't exist.
+ *
+ * @retval true if the directory already existed and has the right permissions
+ * or was successfully created.
+ */
+_PUBLIC_ bool directory_create_or_exist(const char *dname, mode_t dir_perms);
+
+/**
+ * @brief Try to create a specified directory and the parent directory if they
+ * don't exist.
+ *
+ * @param[in] dname The directory path to create.
+ *
+ * @param[in] dir_perms The permission of the directories.
+ *
+ * @return true on success, false otherwise.
+ */
+_PUBLIC_ bool directory_create_or_exists_recursive(
+ const char *dname,
+ mode_t dir_perms);
+
+_PUBLIC_ bool directory_create_or_exist_strict(const char *dname,
+ uid_t uid,
+ mode_t dir_perms);
+
+#include "blocking.h"
+
+/**
+ Sleep for a specified number of milliseconds.
+**/
+_PUBLIC_ void smb_msleep(unsigned int t);
+
+/**
+ Get my own name, return in talloc'ed storage.
+**/
+_PUBLIC_ char* get_myname(TALLOC_CTX *mem_ctx);
+
+/**
+ Check if a process exists. Does this work on all unixes?
+**/
+_PUBLIC_ bool process_exists_by_pid(pid_t pid);
+
+/**
+ Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
+ is dealt with in posix.c
+**/
+_PUBLIC_ bool fcntl_lock(int fd, int op, off_t offset, off_t count, int type);
+
+/**
+ * Write dump of binary data to the log file.
+ *
+ * The data is only written if the log level is at least level.
+ * 16 zero bytes in a row are omitted
+ */
+_PUBLIC_ void dump_data_skip_zeros(int level, const uint8_t *buf, int len);
+
+/**
+ malloc that aborts with smb_panic on fail or zero size.
+**/
+_PUBLIC_ void *smb_xmalloc(size_t size);
+
+/**
+ Memdup with smb_panic on fail.
+**/
+_PUBLIC_ void *smb_xmemdup(const void *p, size_t size);
+
+/**
+ strdup that aborts on malloc fail.
+**/
+_PUBLIC_ char *smb_xstrdup(const char *s);
+
+char *smb_xstrndup(const char *s, size_t n);
+
+/**
+ Like strdup but for memory.
+**/
+_PUBLIC_ void *smb_memdup(const void *p, size_t size);
+
+/**
+ * see if a range of memory is all zero. A NULL pointer is considered
+ * to be all zero
+ */
+_PUBLIC_ bool all_zero(const uint8_t *ptr, size_t size);
+
+/**
+ realloc an array, checking for integer overflow in the array size
+*/
+_PUBLIC_ void *realloc_array(void *ptr, size_t el_size, unsigned count, bool free_on_fail);
+
+void *malloc_array(size_t el_size, unsigned int count);
+
+void *memalign_array(size_t el_size, size_t align, unsigned int count);
+
+void *calloc_array(size_t size, size_t nmemb);
+
+/* The following definitions come from lib/util/fsusage.c */
+
+
+/**
+ * Retrieve amount of free disk space.
+ * this does all of the system specific guff to get the free disk space.
+ * It is derived from code in the GNU fileutils package, but has been
+ * considerably mangled for use here
+ *
+ * results are returned in *dfree and *dsize, in 512 byte units
+*/
+_PUBLIC_ int sys_fsusage(const char *path, uint64_t *dfree, uint64_t *dsize);
+
+/* The following definitions come from lib/util/ms_fnmatch.c */
+
+
+/**
+ * @file
+ * @brief MS-style Filename matching
+ */
+
+int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol,
+ bool is_case_sensitive);
+
+/** a generic fnmatch function - uses for non-CIFS pattern matching */
+int gen_fnmatch(const char *pattern, const char *string);
+
+#include "become_daemon.h"
+
+/**
+ * @brief Get a password from the console.
+ *
+ * You should make sure that the buffer is an empty string!
+ *
+ * You can also use this function to ask for a username. Then you can fill the
+ * buffer with the username and it is shows to the users. If the users just
+ * presses enter the buffer will be untouched.
+ *
+ * @code
+ * char username[128];
+ *
+ * snprintf(username, sizeof(username), "john");
+ *
+ * smb_getpass("Username:", username, sizeof(username), 1, 0);
+ * @endcode
+ *
+ * The prompt will look like this:
+ *
+ * Username: [john]
+ *
+ * If you press enter then john is used as the username, or you can type it in
+ * to change it.
+ *
+ * @param[in] prompt The prompt to show to ask for the password.
+ *
+ * @param[out] buf The buffer the password should be stored. It NEEDS to be
+ * empty or filled out.
+ *
+ * @param[in] len The length of the buffer.
+ *
+ * @param[in] echo Should we echo what you type.
+ *
+ * @param[in] verify Should we ask for the password twice.
+ *
+ * @return 0 on success, -1 on error.
+ */
+_PUBLIC_ int samba_getpass(const char *prompt, char *buf, size_t len,
+ bool echo, bool verify);
+
+/**
+ * Load a ini-style file.
+ */
+bool pm_process( const char *fileName,
+ bool (*sfunc)(const char *, void *),
+ bool (*pfunc)(const char *, const char *, void *),
+ void *userdata);
+bool pm_process_with_flags(const char *filename,
+ bool allow_empty_values,
+ bool (*sfunc)(const char *section, void *private_data),
+ bool (*pfunc)(const char *name, const char *value,
+ void *private_data),
+ void *private_data);
+
+void print_asc(int level, const uint8_t *buf,int len);
+void print_asc_cb(const uint8_t *buf, int len,
+ void (*cb)(const char *buf, void *private_data),
+ void *private_data);
+
+/**
+ * Add an id to an array of ids.
+ *
+ * num should be a pointer to an integer that holds the current
+ * number of elements in ids. It will be updated by this function.
+ */
+
+bool add_uid_to_array_unique(TALLOC_CTX *mem_ctx, uid_t uid,
+ uid_t **uids, uint32_t *num_uids);
+bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
+ gid_t **gids, uint32_t *num_gids);
+
+/**
+ * Allocate anonymous shared memory of the given size
+ */
+void *anonymous_shared_allocate(size_t bufsz);
+void *anonymous_shared_resize(void *ptr, size_t new_size, bool maymove);
+void anonymous_shared_free(void *ptr);
+
+/*
+ run a command as a child process, with a timeout.
+
+ any stdout/stderr from the child will appear in the Samba logs with
+ the specified log levels
+
+ If callback is set then the callback is called on completion
+ with the return code from the command
+ */
+struct tevent_context;
+struct tevent_req;
+struct tevent_req *samba_runcmd_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct timeval endtime,
+ int stdout_log_level,
+ int stderr_log_level,
+ const char * const *argv0, ...);
+int samba_runcmd_recv(struct tevent_req *req, int *perrno);
+int samba_runcmd_export_stdin(struct tevent_req *req);
+
+#ifdef DEVELOPER
+void samba_start_debugger(void);
+#endif
+
+/*
+ * Samba code should use samba_tevent_context_init() instead of
+ * tevent_context_init() in order to get the debug output.
+ */
+struct tevent_context *samba_tevent_context_init(TALLOC_CTX *mem_ctx);
+
+/*
+ * if same samba code needs to use a specific tevent backend
+ * it can use something like this:
+ *
+ * samba_tevent_set_debug(ev, "pysmb_tevent");
+ */
+void samba_tevent_set_debug(struct tevent_context *ev, const char *name);
+
+#endif /* _SAMBA_UTIL_H_ */
diff --git a/lib/util/select.c b/lib/util/select.c
new file mode 100644
index 0000000..dc79a27
--- /dev/null
+++ b/lib/util/select.c
@@ -0,0 +1,61 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+ Samba select/poll implementation
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/select.h"
+#include "lib/util/select.h"
+#include "lib/util/time.h"
+
+int sys_poll_intr(struct pollfd *fds, int num_fds, int timeout)
+{
+ int orig_timeout = timeout;
+ struct timespec start;
+ int ret;
+
+ clock_gettime_mono(&start);
+
+ while (true) {
+ struct timespec now;
+ int64_t elapsed;
+
+ ret = poll(fds, num_fds, timeout);
+ if (ret != -1) {
+ break;
+ }
+ if (errno != EINTR) {
+ break;
+ }
+ /* Infinite timeout, no need to adjust. */
+ if (timeout < 0) {
+ continue;
+ }
+ clock_gettime_mono(&now);
+ elapsed = nsec_time_diff(&now, &start) / 1000000;
+ timeout = orig_timeout - elapsed;
+ /* Unlikely, but might happen eg. when getting traced.
+ * Make sure we're not hanging in this case.
+ */
+ if (timeout < 0) {
+ timeout = 0;
+ }
+ };
+ return ret;
+}
diff --git a/lib/util/select.h b/lib/util/select.h
new file mode 100644
index 0000000..fa1970e
--- /dev/null
+++ b/lib/util/select.h
@@ -0,0 +1,29 @@
+/*
+ Unix SMB/Netbios implementation.
+ Samba select/poll implementation
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _select_h_
+#define _select_h_
+
+#include "system/select.h"
+
+/* The following definitions come from lib/util/select.c */
+
+int sys_poll_intr(struct pollfd *fds, int num_fds, int timeout);
+
+#endif
diff --git a/lib/util/server_id.c b/lib/util/server_id.c
new file mode 100644
index 0000000..690b9dd
--- /dev/null
+++ b/lib/util/server_id.c
@@ -0,0 +1,229 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Bartlett 2011
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "lib/util/debug.h"
+#include "lib/util/fault.h"
+#include "lib/util/server_id.h"
+#include "lib/util/byteorder.h"
+#include "librpc/gen_ndr/server_id.h"
+
+bool server_id_same_process(const struct server_id *p1,
+ const struct server_id *p2)
+{
+ return ((p1->pid == p2->pid) && (p1->vnn == p2->vnn));
+}
+
+int server_id_cmp(const struct server_id *p1, const struct server_id *p2)
+{
+ if (p1->vnn != p2->vnn) {
+ return (p1->vnn < p2->vnn) ? -1 : 1;
+ }
+ if (p1->pid != p2->pid) {
+ return (p1->pid < p2->pid) ? -1 : 1;
+ }
+ if (p1->task_id != p2->task_id) {
+ return (p1->task_id < p2->task_id) ? -1 : 1;
+ }
+ if (p1->unique_id != p2->unique_id) {
+ return (p1->unique_id < p2->unique_id) ? -1 : 1;
+ }
+ return 0;
+}
+
+bool server_id_equal(const struct server_id *p1, const struct server_id *p2)
+{
+ int cmp = server_id_cmp(p1, p2);
+ return (cmp == 0);
+}
+
+char *server_id_str_buf(struct server_id id, struct server_id_buf *dst)
+{
+ if (server_id_is_disconnected(&id)) {
+ strlcpy(dst->buf, "disconnected", sizeof(dst->buf));
+ } else if ((id.vnn == NONCLUSTER_VNN) && (id.task_id == 0)) {
+ snprintf(dst->buf, sizeof(dst->buf), "%llu",
+ (unsigned long long)id.pid);
+ } else if (id.vnn == NONCLUSTER_VNN) {
+ snprintf(dst->buf, sizeof(dst->buf), "%llu.%u",
+ (unsigned long long)id.pid, (unsigned)id.task_id);
+ } else if (id.task_id == 0) {
+ snprintf(dst->buf, sizeof(dst->buf), "%u:%llu",
+ (unsigned)id.vnn, (unsigned long long)id.pid);
+ } else {
+ snprintf(dst->buf, sizeof(dst->buf), "%u:%llu.%u",
+ (unsigned)id.vnn,
+ (unsigned long long)id.pid,
+ (unsigned)id.task_id);
+ }
+ return dst->buf;
+}
+
+size_t server_id_str_buf_unique(struct server_id id, char *buf, size_t buflen)
+{
+ struct server_id_buf idbuf;
+ char unique_buf[21]; /* 2^64 is 18446744073709551616, 20 chars */
+ size_t idlen, unique_len, needed;
+
+ server_id_str_buf(id, &idbuf);
+
+ idlen = strlen(idbuf.buf);
+ unique_len = snprintf(unique_buf, sizeof(unique_buf), "%"PRIu64,
+ id.unique_id);
+ needed = idlen + unique_len + 2;
+
+ if (buflen >= needed) {
+ memcpy(buf, idbuf.buf, idlen);
+ buf[idlen] = '/';
+ memcpy(buf + idlen + 1, unique_buf, unique_len+1);
+ }
+
+ return needed;
+}
+
+struct server_id server_id_from_string(uint32_t local_vnn,
+ const char *pid_string)
+{
+ struct server_id templ = {
+ .vnn = NONCLUSTER_VNN, .pid = UINT64_MAX
+ };
+ struct server_id result;
+ int ret;
+
+ /*
+ * We accept various forms with 1, 2 or 3 component forms
+ * because the server_id_str_buf() can print different forms, and
+ * we want backwards compatibility for scripts that may call
+ * smbclient.
+ */
+
+ result = templ;
+ ret = sscanf(pid_string, "%"SCNu32":%"SCNu64".%"SCNu32"/%"SCNu64,
+ &result.vnn, &result.pid, &result.task_id,
+ &result.unique_id);
+ if (ret == 4) {
+ return result;
+ }
+
+ result = templ;
+ ret = sscanf(pid_string, "%"SCNu32":%"SCNu64".%"SCNu32,
+ &result.vnn, &result.pid, &result.task_id);
+ if (ret == 3) {
+ return result;
+ }
+
+ result = templ;
+ ret = sscanf(pid_string, "%"SCNu32":%"SCNu64"/%"SCNu64,
+ &result.vnn, &result.pid, &result.unique_id);
+ if (ret == 3) {
+ return result;
+ }
+
+ result = templ;
+ ret = sscanf(pid_string, "%"SCNu32":%"SCNu64,
+ &result.vnn, &result.pid);
+ if (ret == 2) {
+ return result;
+ }
+
+ result = templ;
+ ret = sscanf(pid_string, "%"SCNu64".%"SCNu32"/%"SCNu64,
+ &result.pid, &result.task_id, &result.unique_id);
+ if (ret == 3) {
+ result.vnn = local_vnn;
+ return result;
+ }
+
+ result = templ;
+ ret = sscanf(pid_string, "%"SCNu64".%"SCNu32,
+ &result.pid, &result.task_id);
+ if (ret == 2) {
+ result.vnn = local_vnn;
+ return result;
+ }
+
+ result = templ;
+ ret = sscanf(pid_string, "%"SCNu64"/%"SCNu64,
+ &result.pid, &result.unique_id);
+ if (ret == 2) {
+ result.vnn = local_vnn;
+ return result;
+ }
+
+ result = templ;
+ ret = sscanf(pid_string, "%"SCNu64, &result.pid);
+ if (ret == 1) {
+ result.vnn = local_vnn;
+ return result;
+ }
+
+ if (strcmp(pid_string, "disconnected") == 0) {
+ server_id_set_disconnected(&result);
+ return result;
+ }
+
+ return templ;
+}
+
+/**
+ * Set the serverid to the special value that represents a disconnected
+ * client for (e.g.) durable handles.
+ */
+void server_id_set_disconnected(struct server_id *id)
+{
+ *id = (struct server_id) {
+ .pid = UINT64_MAX,
+ .task_id = UINT32_MAX,
+ .vnn = NONCLUSTER_VNN,
+ .unique_id = SERVERID_UNIQUE_ID_NOT_TO_VERIFY,
+ };
+}
+
+/**
+ * check whether a serverid is the special placeholder for
+ * a disconnected client
+ */
+bool server_id_is_disconnected(const struct server_id *id)
+{
+ struct server_id dis;
+
+ SMB_ASSERT(id != NULL);
+
+ server_id_set_disconnected(&dis);
+
+ return server_id_equal(id, &dis);
+}
+
+void server_id_put(uint8_t buf[SERVER_ID_BUF_LENGTH],
+ const struct server_id id)
+{
+ SBVAL(buf, 0, id.pid);
+ SIVAL(buf, 8, id.task_id);
+ SIVAL(buf, 12, id.vnn);
+ SBVAL(buf, 16, id.unique_id);
+}
+
+void server_id_get(struct server_id *id,
+ const uint8_t buf[SERVER_ID_BUF_LENGTH])
+{
+ id->pid = BVAL(buf, 0);
+ id->task_id = IVAL(buf, 8);
+ id->vnn = IVAL(buf, 12);
+ id->unique_id = BVAL(buf, 16);
+}
diff --git a/lib/util/server_id.h b/lib/util/server_id.h
new file mode 100644
index 0000000..5b723d5
--- /dev/null
+++ b/lib/util/server_id.h
@@ -0,0 +1,57 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Bartlett 2011
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LIB_UTIL_SERVER_ID_H__
+#define __LIB_UTIL_SERVER_ID_H__
+
+#include "replace.h"
+
+struct server_id;
+
+struct server_id_buf { char buf[48]; }; /* probably a bit too large ... */
+
+bool server_id_same_process(const struct server_id *p1,
+ const struct server_id *p2);
+int server_id_cmp(const struct server_id *p1, const struct server_id *p2);
+bool server_id_equal(const struct server_id *p1, const struct server_id *p2);
+char *server_id_str_buf(struct server_id id, struct server_id_buf *dst);
+size_t server_id_str_buf_unique(struct server_id id, char *buf, size_t buflen);
+
+struct server_id server_id_from_string(uint32_t local_vnn,
+ const char *pid_string);
+
+/**
+ * Set the serverid to the special value that represents a disconnected
+ * client for (e.g.) durable handles.
+ */
+void server_id_set_disconnected(struct server_id *id);
+
+/**
+ * check whether a serverid is the special placeholder for
+ * a disconnected client
+ */
+bool server_id_is_disconnected(const struct server_id *id);
+
+#define SERVER_ID_BUF_LENGTH 24
+void server_id_put(uint8_t buf[SERVER_ID_BUF_LENGTH],
+ const struct server_id id);
+void server_id_get(struct server_id *id,
+ const uint8_t buf[SERVER_ID_BUF_LENGTH]);
+
+#endif
diff --git a/lib/util/server_id_db.c b/lib/util/server_id_db.c
new file mode 100644
index 0000000..17b1577
--- /dev/null
+++ b/lib/util/server_id_db.c
@@ -0,0 +1,355 @@
+/*
+ * Map names to server_ids
+ *
+ * Copyright Volker Lendecke <vl@samba.org> 2014
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "lib/util/server_id.h"
+#include "lib/util/server_id_db.h"
+#include "lib/tdb_wrap/tdb_wrap.h"
+#include "lib/util/strv.h"
+#include "lib/util/util_tdb.h"
+#include "lib/util/samba_util.h"
+
+static TDB_DATA talloc_tdb_data(void *ptr)
+{
+ return (TDB_DATA) { .dptr = ptr, .dsize = talloc_get_size(ptr) };
+}
+
+struct server_id_db {
+ struct server_id pid;
+ struct tdb_wrap *tdb;
+ char *names;
+};
+
+static int server_id_db_destructor(struct server_id_db *db);
+
+struct server_id_db *server_id_db_init(TALLOC_CTX *mem_ctx,
+ struct server_id pid,
+ const char *base_path,
+ int hash_size, int tdb_flags)
+{
+ struct server_id_db *db;
+ size_t pathlen = strlen(base_path) + 11;
+ char path[pathlen];
+
+ db = talloc(mem_ctx, struct server_id_db);
+ if (db == NULL) {
+ return NULL;
+ }
+ db->pid = pid;
+ db->names = NULL;
+
+ snprintf(path, pathlen, "%s/names.tdb", base_path);
+
+ db->tdb = tdb_wrap_open(db, path, hash_size, tdb_flags,
+ O_RDWR|O_CREAT, 0660);
+ if (db->tdb == NULL) {
+ TALLOC_FREE(db);
+ return NULL;
+ }
+
+ talloc_set_destructor(db, server_id_db_destructor);
+
+ return db;
+}
+
+void server_id_db_reinit(struct server_id_db *db, struct server_id pid)
+{
+ db->pid = pid;
+ TALLOC_FREE(db->names);
+}
+
+struct server_id server_id_db_pid(struct server_id_db *db)
+{
+ return db->pid;
+}
+
+static int server_id_db_destructor(struct server_id_db *db)
+{
+ char *name = NULL;
+
+ while ((name = strv_next(db->names, name)) != NULL) {
+ server_id_db_remove(db, name);
+ }
+
+ return 0;
+}
+
+int server_id_db_add(struct server_id_db *db, const char *name)
+{
+ struct tdb_context *tdb = db->tdb->tdb;
+ TDB_DATA key;
+ char *n;
+ int ret;
+
+ n = strv_find(db->names, name);
+ if (n != NULL) {
+ return EEXIST;
+ }
+
+ ret = strv_add(db, &db->names, name);
+ if (ret != 0) {
+ return ret;
+ }
+
+ key = string_term_tdb_data(name);
+
+ {
+ size_t idlen = server_id_str_buf_unique(db->pid, NULL, 0);
+ char idbuf[idlen];
+
+ server_id_str_buf_unique(db->pid, idbuf, idlen);
+
+ ret = tdb_append(
+ tdb, key,
+ (TDB_DATA) { .dptr = (uint8_t *)idbuf, .dsize = idlen });
+ }
+
+ if (ret != 0) {
+ enum TDB_ERROR err = tdb_error(tdb);
+ strv_delete(&db->names, strv_find(db->names, name));
+ return map_unix_error_from_tdb(err);
+ }
+
+ return 0;
+}
+
+int server_id_db_prune_name(struct server_id_db *db, const char *name,
+ struct server_id server)
+{
+ struct tdb_context *tdb = db->tdb->tdb;
+ size_t idbuf_len = server_id_str_buf_unique(server, NULL, 0);
+ char idbuf[idbuf_len];
+ TDB_DATA key;
+ uint8_t *data;
+ size_t datalen;
+ char *ids, *id;
+ int ret;
+
+ key = string_term_tdb_data(name);
+ server_id_str_buf_unique(server, idbuf, idbuf_len);
+
+ ret = tdb_chainlock(tdb, key);
+ if (ret == -1) {
+ enum TDB_ERROR err = tdb_error(tdb);
+ return map_unix_error_from_tdb(err);
+ }
+
+ ret = tdb_fetch_talloc(tdb, key, db, &data);
+ if (ret != 0) {
+ tdb_chainunlock(tdb, key);
+ return ret;
+ }
+
+ datalen = talloc_get_size(data);
+ if ((datalen == 0) || (data[datalen-1] != '\0')) {
+ tdb_chainunlock(tdb, key);
+ TALLOC_FREE(data);
+ return EINVAL;
+ }
+
+ ids = (char *)data;
+
+ id = strv_find(ids, idbuf);
+ if (id == NULL) {
+ tdb_chainunlock(tdb, key);
+ TALLOC_FREE(data);
+ return ENOENT;
+ }
+
+ strv_delete(&ids, id);
+
+ if (talloc_get_size(ids) == 0) {
+ ret = tdb_delete(tdb, key);
+ } else {
+ ret = tdb_store(tdb, key, talloc_tdb_data(ids), TDB_MODIFY);
+ }
+ TALLOC_FREE(data);
+
+ tdb_chainunlock(tdb, key);
+
+ if (ret == -1) {
+ enum TDB_ERROR err = tdb_error(tdb);
+ return map_unix_error_from_tdb(err);
+ }
+
+ return 0;
+}
+
+int server_id_db_remove(struct server_id_db *db, const char *name)
+{
+ char *n;
+ int ret;
+
+ n = strv_find(db->names, name);
+ if (n == NULL) {
+ return ENOENT;
+ }
+
+ ret = server_id_db_prune_name(db, name, db->pid);
+ if (ret != 0) {
+ return ret;
+ }
+
+ strv_delete(&db->names, n);
+ return 0;
+}
+
+int server_id_db_lookup(struct server_id_db *db, const char *name,
+ TALLOC_CTX *mem_ctx, unsigned *pnum_servers,
+ struct server_id **pservers)
+{
+ struct tdb_context *tdb = db->tdb->tdb;
+ TDB_DATA key;
+ uint8_t *data;
+ size_t datalen;
+ char *ids, *id;
+ unsigned num_servers;
+ struct server_id *servers;
+ int i, ret;
+
+ key = string_term_tdb_data(name);
+
+ ret = tdb_fetch_talloc(tdb, key, mem_ctx, &data);
+ if (ret != 0) {
+ return ret;
+ }
+
+ datalen = talloc_get_size(data);
+ if ((datalen == 0) || (data[datalen-1] != '\0')) {
+ TALLOC_FREE(data);
+ return EINVAL;
+ }
+
+ ids = (char *)data;
+ num_servers = strv_count(ids);
+
+ servers = talloc_array(mem_ctx, struct server_id, num_servers);
+ if (servers == NULL) {
+ TALLOC_FREE(data);
+ return ENOMEM;
+ }
+
+ i = 0;
+
+ for (id = ids; id != NULL; id = strv_next(ids, id)) {
+ servers[i++] = server_id_from_string(NONCLUSTER_VNN, id);
+ }
+
+ TALLOC_FREE(data);
+
+ *pnum_servers = num_servers;
+ *pservers = servers;
+
+ return 0;
+}
+
+bool server_id_db_lookup_one(struct server_id_db *db, const char *name,
+ struct server_id *server)
+{
+ int ret;
+ unsigned num_servers;
+ struct server_id *servers;
+
+ ret = server_id_db_lookup(db, name, db, &num_servers, &servers);
+ if (ret != 0) {
+ return false;
+ }
+ if (num_servers == 0) {
+ TALLOC_FREE(servers);
+ return false;
+ }
+ *server = servers[0];
+ TALLOC_FREE(servers);
+ return true;
+}
+
+struct server_id_db_traverse_state {
+ TALLOC_CTX *mem_ctx;
+ int (*fn)(const char *name,
+ unsigned num_servers,
+ const struct server_id *servers,
+ void *private_data);
+ void *private_data;
+};
+
+static int server_id_db_traverse_fn(struct tdb_context *tdb,
+ TDB_DATA key, TDB_DATA data,
+ void *private_data)
+{
+ struct server_id_db_traverse_state *state = private_data;
+ const char *name;
+ char *ids, *id;
+ unsigned num_servers;
+ struct server_id *servers;
+ int i, ret;
+
+ if (key.dsize == 0) {
+ return 0;
+ }
+ if (key.dptr[key.dsize-1] != '\0') {
+ return 0;
+ }
+ name = (const char *)key.dptr;
+
+ ids = (char *)talloc_memdup(state->mem_ctx, data.dptr, data.dsize);
+ if (ids == NULL) {
+ return 0;
+ }
+
+ num_servers = strv_count(ids);
+ servers = talloc_array(ids, struct server_id, num_servers);
+
+ i = 0;
+
+ for (id = ids; id != NULL; id = strv_next(ids, id)) {
+ servers[i++] = server_id_from_string(NONCLUSTER_VNN, id);
+ }
+
+ ret = state->fn(name, num_servers, servers, state->private_data);
+
+ TALLOC_FREE(ids);
+
+ return ret;
+}
+
+int server_id_db_traverse_read(struct server_id_db *db,
+ int (*fn)(const char *name,
+ unsigned num_servers,
+ const struct server_id *servers,
+ void *private_data),
+ void *private_data)
+{
+ struct server_id_db_traverse_state state;
+ int ret;
+
+ state = (struct server_id_db_traverse_state) {
+ .fn = fn, .private_data = private_data,
+ .mem_ctx = talloc_new(db)
+ };
+
+ if (state.mem_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = tdb_traverse_read(db->tdb->tdb, server_id_db_traverse_fn,
+ &state);
+ TALLOC_FREE(state.mem_ctx);
+ return ret;
+}
diff --git a/lib/util/server_id_db.h b/lib/util/server_id_db.h
new file mode 100644
index 0000000..2dcce62
--- /dev/null
+++ b/lib/util/server_id_db.h
@@ -0,0 +1,50 @@
+/*
+ * Namedb
+ *
+ * Copyright Volker Lendecke <vl@samba.org> 2014
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SERVER_ID_DB_H_
+#define _SERVER_ID_DB_H_
+
+#include "talloc.h"
+#include "librpc/gen_ndr/server_id.h"
+
+struct server_id_db;
+
+struct server_id_db *server_id_db_init(TALLOC_CTX *mem_ctx,
+ struct server_id pid,
+ const char *base_path,
+ int hash_size, int tdb_flags);
+void server_id_db_reinit(struct server_id_db *db, struct server_id pid);
+struct server_id server_id_db_pid(struct server_id_db *db);
+int server_id_db_add(struct server_id_db *db, const char *name);
+int server_id_db_remove(struct server_id_db *db, const char *name);
+int server_id_db_prune_name(struct server_id_db *db, const char *name,
+ struct server_id server);
+int server_id_db_lookup(struct server_id_db *db, const char *name,
+ TALLOC_CTX *mem_ctx, unsigned *num_servers,
+ struct server_id **servers);
+bool server_id_db_lookup_one(struct server_id_db *db, const char *name,
+ struct server_id *server);
+int server_id_db_traverse_read(struct server_id_db *db,
+ int (*fn)(const char *name,
+ unsigned num_servers,
+ const struct server_id *servers,
+ void *private_data),
+ void *private_data);
+
+#endif
diff --git a/lib/util/setid.c b/lib/util/setid.c
new file mode 100644
index 0000000..1001461
--- /dev/null
+++ b/lib/util/setid.c
@@ -0,0 +1,249 @@
+/*
+ Unix SMB/CIFS implementation.
+ setXXid() functions for Samba.
+ Copyright (C) Jeremy Allison 2012
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef AUTOCONF_TEST
+#include "replace.h"
+#include "system/passwd.h"
+
+#include "../lib/util/setid.h"
+
+#else
+
+/* Inside autoconf test. */
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_PRIV_H
+#include <sys/priv.h>
+#endif
+#ifdef HAVE_SYS_ID_H
+#include <sys/id.h>
+#endif
+
+/* autoconf tests don't include setid.h */
+int samba_setresuid(uid_t ruid, uid_t euid, uid_t suid);
+int samba_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
+int samba_setreuid(uid_t ruid, uid_t euid);
+int samba_setregid(gid_t rgid, gid_t egid);
+int samba_seteuid(uid_t euid);
+int samba_setegid(gid_t egid);
+int samba_setuid(uid_t uid);
+int samba_setgid(gid_t gid);
+int samba_setuidx(int flags, uid_t uid);
+int samba_setgidx(int flags, gid_t gid);
+int samba_setgroups(size_t setlen, const gid_t *gidset);
+
+#endif
+
+#if defined(HAVE_LINUX_THREAD_CREDENTIALS)
+#if defined(HAVE_SYSCALL_H)
+#include <syscall.h>
+#endif
+
+#if defined(HAVE_SYS_SYSCALL_H)
+#include <sys/syscall.h>
+#endif
+
+/* Ensure we can't compile in a mixed syscall setup. */
+#if !defined(USE_LINUX_32BIT_SYSCALLS)
+#if defined(SYS_setresuid32) || defined(SYS_setresgid32) || defined(SYS_setreuid32) || defined(SYS_setregid32) || defined(SYS_setuid32) || defined(SYS_setgid32) || defined(SYS_setgroups32)
+#error Mixture of 32-bit Linux system calls and 64-bit calls.
+#endif
+#endif
+
+#endif
+
+/* All the setXX[ug]id functions and setgroups Samba uses. */
+int samba_setresuid(uid_t ruid, uid_t euid, uid_t suid)
+{
+#if defined(HAVE_LINUX_THREAD_CREDENTIALS)
+#if defined(USE_LINUX_32BIT_SYSCALLS)
+ return syscall(SYS_setresuid32, ruid, euid, suid);
+#else
+ return syscall(SYS_setresuid, ruid, euid, suid);
+#endif
+#elif defined(HAVE_SETRESUID)
+ return setresuid(ruid, euid, suid);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int samba_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
+{
+#if defined(HAVE_LINUX_THREAD_CREDENTIALS)
+#if defined(USE_LINUX_32BIT_SYSCALLS)
+ return syscall(SYS_setresgid32, rgid, egid, sgid);
+#else
+ return syscall(SYS_setresgid, rgid, egid, sgid);
+#endif
+#elif defined(HAVE_SETRESGID)
+ return setresgid(rgid, egid, sgid);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int samba_setreuid(uid_t ruid, uid_t euid)
+{
+#if defined(HAVE_LINUX_THREAD_CREDENTIALS)
+#if defined(USE_LINUX_32BIT_SYSCALLS)
+ return syscall(SYS_setreuid32, ruid, euid);
+#else
+ return syscall(SYS_setreuid, ruid, euid);
+#endif
+#elif defined(HAVE_SETREUID)
+ return setreuid(ruid, euid);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int samba_setregid(gid_t rgid, gid_t egid)
+{
+#if defined(HAVE_LINUX_THREAD_CREDENTIALS)
+#if defined(USE_LINUX_32BIT_SYSCALLS)
+ return syscall(SYS_setregid32, rgid, egid);
+#else
+ return syscall(SYS_setregid, rgid, egid);
+#endif
+#elif defined(HAVE_SETREGID)
+ return setregid(rgid, egid);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int samba_seteuid(uid_t euid)
+{
+#if defined(HAVE_LINUX_THREAD_CREDENTIALS)
+#if defined(USE_LINUX_32BIT_SYSCALLS)
+ /* seteuid is not a separate system call. */
+ return syscall(SYS_setresuid32, -1, euid, -1);
+#else
+ /* seteuid is not a separate system call. */
+ return syscall(SYS_setresuid, -1, euid, -1);
+#endif
+#elif defined(HAVE_SETEUID)
+ return seteuid(euid);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int samba_setegid(gid_t egid)
+{
+#if defined(HAVE_LINUX_THREAD_CREDENTIALS)
+#if defined(USE_LINUX_32BIT_SYSCALLS)
+ /* setegid is not a separate system call. */
+ return syscall(SYS_setresgid32, -1, egid, -1);
+#else
+ /* setegid is not a separate system call. */
+ return syscall(SYS_setresgid, -1, egid, -1);
+#endif
+#elif defined(HAVE_SETEGID)
+ return setegid(egid);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int samba_setuid(uid_t uid)
+{
+#if defined(HAVE_LINUX_THREAD_CREDENTIALS)
+#if defined(USE_LINUX_32BIT_SYSCALLS)
+ return syscall(SYS_setuid32, uid);
+#else
+ return syscall(SYS_setuid, uid);
+#endif
+#elif defined(HAVE_SETUID)
+ return setuid(uid);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int samba_setgid(gid_t gid)
+{
+#if defined(HAVE_LINUX_THREAD_CREDENTIALS)
+#if defined(USE_LINUX_32BIT_SYSCALLS)
+ return syscall(SYS_setgid32, gid);
+#else
+ return syscall(SYS_setgid, gid);
+#endif
+#elif defined(HAVE_SETGID)
+ return setgid(gid);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int samba_setuidx(int flags, uid_t uid)
+{
+#if defined(HAVE_SETUIDX)
+ return setuidx(flags, uid);
+#else
+ /* HAVE_LINUX_THREAD_CREDENTIALS doesn't have this. */
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int samba_setgidx(int flags, gid_t gid)
+{
+#if defined(HAVE_SETGIDX)
+ return setgidx(flags, gid);
+#else
+ /* HAVE_LINUX_THREAD_CREDENTIALS doesn't have this. */
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int samba_setgroups(size_t setlen, const gid_t *gidset)
+{
+#if defined(HAVE_LINUX_THREAD_CREDENTIALS)
+#if defined(USE_LINUX_32BIT_SYSCALLS)
+ return syscall(SYS_setgroups32, setlen, gidset);
+#else
+ return syscall(SYS_setgroups, setlen, gidset);
+#endif
+#elif defined(HAVE_SETGROUPS)
+ return setgroups(setlen, gidset);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
diff --git a/lib/util/setid.h b/lib/util/setid.h
new file mode 100644
index 0000000..59ae44c
--- /dev/null
+++ b/lib/util/setid.h
@@ -0,0 +1,43 @@
+/*
+ Unix SMB/CIFS implementation.
+ setXXid() functions for Samba.
+ Copyright (C) Jeremy Allison 2012
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SETID_H
+#define _SETID_H
+
+/*
+ * NB. We don't wrap initgroups although on some systems
+ * this can call setgroups. On systems with thread-specific
+ * credentials (Linux so far) we know they have getgrouplist()
+ * which doesn't make a system call.
+ */
+
+/* All the setXX[ug]id functions and setgroups Samba uses. */
+int samba_setresuid(uid_t ruid, uid_t euid, uid_t suid);
+int samba_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
+int samba_setreuid(uid_t ruid, uid_t euid);
+int samba_setregid(gid_t rgid, gid_t egid);
+int samba_seteuid(uid_t euid);
+int samba_setegid(gid_t egid);
+int samba_setuid(uid_t uid);
+int samba_setgid(gid_t gid);
+int samba_setuidx(int flags, uid_t uid);
+int samba_setgidx(int flags, gid_t gid);
+int samba_setgroups(size_t setlen, const gid_t *gidset);
+
+#endif
diff --git a/lib/util/signal.c b/lib/util/signal.c
new file mode 100644
index 0000000..3fc63b2
--- /dev/null
+++ b/lib/util/signal.c
@@ -0,0 +1,146 @@
+/*
+ Unix SMB/CIFS implementation.
+ signal handling functions
+
+ Copyright (C) Andrew Tridgell 1998
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/wait.h"
+#include "debug.h"
+#include "lib/util/signal.h" /* Avoid /usr/include/signal.h */
+
+/**
+ * @file
+ * @brief Signal handling
+ */
+
+/****************************************************************************
+ Catch child exits and reap the child zombie status.
+****************************************************************************/
+
+static void sig_cld(int signum)
+{
+ while (waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0)
+ ;
+
+ /*
+ * Turns out it's *really* important not to
+ * restore the signal handler here if we have real POSIX
+ * signal handling. If we do, then we get the signal re-delivered
+ * immediately - hey presto - instant loop ! JRA.
+ */
+
+#if !defined(HAVE_SIGACTION)
+ CatchSignal(SIGCLD, sig_cld);
+#endif
+}
+
+/****************************************************************************
+catch child exits - leave status;
+****************************************************************************/
+
+static void sig_cld_leave_status(int signum)
+{
+ /*
+ * Turns out it's *really* important not to
+ * restore the signal handler here if we have real POSIX
+ * signal handling. If we do, then we get the signal re-delivered
+ * immediately - hey presto - instant loop ! JRA.
+ */
+
+#if !defined(HAVE_SIGACTION)
+ CatchSignal(SIGCLD, sig_cld_leave_status);
+#endif
+}
+
+/**
+ Block sigs.
+**/
+
+void BlockSignals(bool block, int signum)
+{
+#ifdef HAVE_SIGPROCMASK
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set,signum);
+ sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
+#elif defined(HAVE_SIGBLOCK)
+ if (block) {
+ sigblock(sigmask(signum));
+ } else {
+ sigsetmask(siggetmask() & ~sigmask(signum));
+ }
+#else
+ /* yikes! This platform can't block signals? */
+ static int done;
+ if (!done) {
+ DEBUG(0,("WARNING: No signal blocking available\n"));
+ done=1;
+ }
+#endif
+}
+
+/**
+ Catch a signal. This should implement the following semantics:
+
+ 1) The handler remains installed after being called.
+ 2) The signal should be blocked during handler execution.
+**/
+
+void (*CatchSignal(int signum,void (*handler)(int )))(int)
+{
+#ifdef HAVE_SIGACTION
+ struct sigaction act;
+ struct sigaction oldact;
+
+ ZERO_STRUCT(act);
+
+ act.sa_handler = handler;
+#ifdef SA_RESTART
+ /*
+ * We *want* SIGALRM to interrupt a system call.
+ */
+ if(signum != SIGALRM)
+ act.sa_flags = SA_RESTART;
+#endif
+ sigemptyset(&act.sa_mask);
+ sigaddset(&act.sa_mask,signum);
+ sigaction(signum,&act,&oldact);
+ return oldact.sa_handler;
+#else /* !HAVE_SIGACTION */
+ /* FIXME: need to handle sigvec and systems with broken signal() */
+ return signal(signum, handler);
+#endif
+}
+
+/**
+ Ignore SIGCLD via whatever means is necessary for this OS.
+**/
+
+void (*CatchChild(void))(int)
+{
+ return CatchSignal(SIGCLD, sig_cld);
+}
+
+/**
+ Catch SIGCLD but leave the child around so it's status can be reaped.
+**/
+
+void (*CatchChildLeaveStatus(void))(int)
+{
+ return CatchSignal(SIGCLD, sig_cld_leave_status);
+}
diff --git a/lib/util/signal.h b/lib/util/signal.h
new file mode 100644
index 0000000..f662ee1
--- /dev/null
+++ b/lib/util/signal.h
@@ -0,0 +1,50 @@
+/*
+ Unix SMB/CIFS implementation.
+ signal handling functions
+
+ Copyright (C) Andrew Tridgell 1998
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_UTIL_SIGNAL_H_
+#define _SAMBA_UTIL_SIGNAL_H_
+
+#include <signal.h>
+#include <stdbool.h>
+
+/**
+ Block sigs.
+**/
+void BlockSignals(bool block, int signum);
+
+/**
+ Catch a signal. This should implement the following semantics:
+
+ 1) The handler remains installed after being called.
+ 2) The signal should be blocked during handler execution.
+**/
+void (*CatchSignal(int signum,void (*handler)(int )))(int);
+
+/**
+ Ignore SIGCLD via whatever means is necessary for this OS.
+**/
+void (*CatchChild(void))(int);
+
+/**
+ Catch SIGCLD but leave the child around so it's status can be reaped.
+**/
+void (*CatchChildLeaveStatus(void))(int);
+
+#endif /* _SAMBA_UTIL_SIGNAL_H_ */
diff --git a/lib/util/smb_strtox.c b/lib/util/smb_strtox.c
new file mode 100644
index 0000000..7a477dc
--- /dev/null
+++ b/lib/util/smb_strtox.c
@@ -0,0 +1,177 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) Swen Schillig 2019
+ *
+ * ** NOTE! The following LGPL license applies to this file.
+ * ** This does NOT imply that all of Samba is released
+ * ** under the LGPL
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "smb_strtox.h"
+
+/**
+ * Convert a string to an unsigned long integer
+ *
+ * @param nptr pointer to string which is to be converted
+ * @param endptr [optional] reference to remainder of the string
+ * @param base base of the numbering scheme
+ * @param err error occurred during conversion
+ * @flags controlling conversion feature
+ * @result result of the conversion as provided by strtoul
+ *
+ * The following flags are supported
+ * SMB_STR_STANDARD # raise error if negative or non-numeric
+ * SMB_STR_ALLOW_NEGATIVE # allow strings with a leading "-"
+ * SMB_STR_FULL_STR_CONV # entire string must be converted
+ * SMB_STR_ALLOW_NO_CONVERSION # allow empty strings or non-numeric
+ * SMB_STR_GLIBC_STANDARD # act exactly as the standard glibc strtoul
+ *
+ * The following errors are detected
+ * - wrong base
+ * - value overflow
+ * - string with a leading "-" indicating a negative number
+ * - no conversion due to empty string or not representing a number
+ */
+unsigned long int
+smb_strtoul(const char *nptr, char **endptr, int base, int *err, int flags)
+{
+ unsigned long int val;
+ int saved_errno = errno;
+ char *needle = NULL;
+ char *tmp_endptr = NULL;
+
+ errno = 0;
+ *err = 0;
+
+ val = strtoul(nptr, &tmp_endptr, base);
+
+ if (endptr != NULL) {
+ *endptr = tmp_endptr;
+ }
+
+ if (errno != 0) {
+ *err = errno;
+ errno = saved_errno;
+ return val;
+ }
+
+ if ((flags & SMB_STR_ALLOW_NO_CONVERSION) == 0) {
+ /* got an invalid number-string resulting in no conversion */
+ if (nptr == tmp_endptr) {
+ *err = EINVAL;
+ goto out;
+ }
+ }
+
+ if ((flags & SMB_STR_ALLOW_NEGATIVE ) == 0) {
+ /* did we convert a negative "number" ? */
+ needle = strchr(nptr, '-');
+ if (needle != NULL && needle < tmp_endptr) {
+ *err = EINVAL;
+ goto out;
+ }
+ }
+
+ if ((flags & SMB_STR_FULL_STR_CONV) != 0) {
+ /* did we convert the entire string ? */
+ if (tmp_endptr[0] != '\0') {
+ *err = EINVAL;
+ goto out;
+ }
+ }
+
+out:
+ errno = saved_errno;
+ return val;
+}
+
+/**
+ * Convert a string to an unsigned long long integer
+ *
+ * @param nptr pointer to string which is to be converted
+ * @param endptr [optional] reference to remainder of the string
+ * @param base base of the numbering scheme
+ * @param err error occurred during conversion
+ * @flags controlling conversion feature
+ * @result result of the conversion as provided by strtoull
+ *
+ * The following flags are supported
+ * SMB_STR_STANDARD # raise error if negative or non-numeric
+ * SMB_STR_ALLOW_NEGATIVE # allow strings with a leading "-"
+ * SMB_STR_FULL_STR_CONV # entire string must be converted
+ * SMB_STR_ALLOW_NO_CONVERSION # allow empty strings or non-numeric
+ * SMB_STR_GLIBC_STANDARD # act exactly as the standard glibc strtoul
+ *
+ * The following errors are detected
+ * - wrong base
+ * - value overflow
+ * - string with a leading "-" indicating a negative number
+ * - no conversion due to empty string or not representing a number
+ */
+unsigned long long int
+smb_strtoull(const char *nptr, char **endptr, int base, int *err, int flags)
+{
+ unsigned long long int val;
+ int saved_errno = errno;
+ char *needle = NULL;
+ char *tmp_endptr = NULL;
+
+ errno = 0;
+ *err = 0;
+
+ val = strtoull(nptr, &tmp_endptr, base);
+
+ if (endptr != NULL) {
+ *endptr = tmp_endptr;
+ }
+
+ if (errno != 0) {
+ *err = errno;
+ errno = saved_errno;
+ return val;
+ }
+
+ if ((flags & SMB_STR_ALLOW_NO_CONVERSION) == 0) {
+ /* got an invalid number-string resulting in no conversion */
+ if (nptr == tmp_endptr) {
+ *err = EINVAL;
+ goto out;
+ }
+ }
+
+ if ((flags & SMB_STR_ALLOW_NEGATIVE ) == 0) {
+ /* did we convert a negative "number" ? */
+ needle = strchr(nptr, '-');
+ if (needle != NULL && needle < tmp_endptr) {
+ *err = EINVAL;
+ goto out;
+ }
+ }
+
+ if ((flags & SMB_STR_FULL_STR_CONV) != 0) {
+ /* did we convert the entire string ? */
+ if (tmp_endptr[0] != '\0') {
+ *err = EINVAL;
+ goto out;
+ }
+ }
+
+out:
+ errno = saved_errno;
+ return val;
+}
diff --git a/lib/util/smb_strtox.h b/lib/util/smb_strtox.h
new file mode 100644
index 0000000..fcbedbe
--- /dev/null
+++ b/lib/util/smb_strtox.h
@@ -0,0 +1,40 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) Swen Schillig 2019
+ *
+ * ** NOTE! The following LGPL license applies to this file.
+ * ** This does NOT imply that all of Samba is released
+ * ** under the LGPL
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef SMB_STRTOX_H
+#define SMB_STRTOX_H
+
+#define SMB_STR_STANDARD 0x00
+#define SMB_STR_ALLOW_NEGATIVE 0x01
+#define SMB_STR_FULL_STR_CONV 0x02
+#define SMB_STR_ALLOW_NO_CONVERSION 0x04
+#define SMB_STR_GLIBC_STANDARD (SMB_STR_ALLOW_NO_CONVERSION | \
+ SMB_STR_ALLOW_NEGATIVE)
+
+unsigned long int
+smb_strtoul(const char *nptr, char **endptr, int base, int *err, int flags);
+
+unsigned long long int
+smb_strtoull(const char *nptr, char **endptr, int base, int *err, int flags);
+
+#endif
diff --git a/lib/util/smb_threads.c b/lib/util/smb_threads.c
new file mode 100644
index 0000000..421dac9
--- /dev/null
+++ b/lib/util/smb_threads.c
@@ -0,0 +1,206 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB client library implementation (thread interface functions).
+ Copyright (C) Jeremy Allison, 2009.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * This code is based in the ideas in openssl
+ * but somewhat simpler and expended to include
+ * thread local storage.
+ */
+
+#include "replace.h"
+#include "smb_threads.h"
+#include "smb_threads_internal.h"
+#include "lib/util/debug.h"
+#include "lib/util/fault.h"
+#include "lib/util/memory.h"
+
+/*********************************************************
+ Functions to vector the locking primitives used internally
+ by libsmbclient.
+*********************************************************/
+
+const struct smb_thread_functions *global_tfp;
+
+/*********************************************************
+ Dynamic lock array.
+*********************************************************/
+
+void **global_lock_array;
+
+/*********************************************************
+ Mutex used for our internal "once" function
+*********************************************************/
+
+static void *once_mutex = NULL;
+
+
+/*********************************************************
+ Function to set the locking primitives used by libsmbclient.
+*********************************************************/
+
+int smb_thread_set_functions(const struct smb_thread_functions *tf)
+{
+ int i;
+
+ global_tfp = tf;
+
+#if defined(PARANOID_MALLOC_CHECKER)
+#ifdef malloc
+#undef malloc
+#endif
+#endif
+
+ /* Here we initialize any static locks we're using. */
+ global_lock_array = (void **)malloc(sizeof(void *) *NUM_GLOBAL_LOCKS);
+
+#if defined(PARANOID_MALLOC_CHECKER)
+#define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
+#endif
+
+ if (global_lock_array == NULL) {
+ return ENOMEM;
+ }
+
+ for (i = 0; i < NUM_GLOBAL_LOCKS; i++) {
+ char *name = NULL;
+ if (asprintf(&name, "global_lock_%d", i) == -1) {
+ SAFE_FREE(global_lock_array);
+ return ENOMEM;
+ }
+ if (global_tfp->create_mutex(name,
+ &global_lock_array[i],
+ __location__)) {
+ smb_panic("smb_thread_set_functions: create mutexes failed");
+ }
+ SAFE_FREE(name);
+ }
+
+ /* Create the mutex we'll use for our "once" function */
+ if (SMB_THREAD_CREATE_MUTEX("smb_once", once_mutex) != 0) {
+ smb_panic("smb_thread_set_functions: failed to create 'once' mutex");
+ }
+
+ return 0;
+}
+
+/*******************************************************************
+ Call a function only once. We implement this ourselves
+ using our own mutex rather than using the thread implementation's
+ *_once() function because each implementation has its own
+ type for the variable which keeps track of whether the function
+ has been called, and there's no easy way to allocate the correct
+ size variable in code internal to Samba without knowing the
+ implementation's "once" type.
+********************************************************************/
+
+int smb_thread_once(smb_thread_once_t *ponce,
+ void (*init_fn)(void *pdata),
+ void *pdata)
+{
+ int ret;
+
+ /* Lock our "once" mutex in order to test and initialize ponce */
+ if (SMB_THREAD_LOCK(once_mutex) != 0) {
+ smb_panic("error locking 'once'");
+ }
+
+ /* Keep track of whether we ran their init function */
+ ret = ! *ponce;
+
+ /*
+ * See if another thread got here after we tested it initially but
+ * before we got our lock.
+ */
+ if (! *ponce) {
+ /* Nope, we need to run the initialization function */
+ (*init_fn)(pdata);
+
+ /* Now we can indicate that the function has been run */
+ *ponce = true;
+ }
+
+ /* Unlock the mutex */
+ if (SMB_THREAD_UNLOCK(once_mutex) != 0) {
+ smb_panic("error unlocking 'once'");
+ }
+
+ /*
+ * Tell 'em whether we ran their init function. If they passed a data
+ * pointer to the init function and the init function could change
+ * something in the pointed-to data, this will tell them whether that
+ * data is valid or not.
+ */
+ return ret;
+}
+
+
+#if 0
+/* Test. - pthread implementations. */
+#include <pthread.h>
+
+#ifdef malloc
+#undef malloc
+#endif
+
+SMB_THREADS_DEF_PTHREAD_IMPLEMENTATION(tf);
+
+static smb_thread_once_t ot = SMB_THREAD_ONCE_INIT;
+void *pkey = NULL;
+
+static void init_fn(void)
+{
+ int ret;
+
+ if (!global_tfp) {
+ /* Non-thread safe init case. */
+ if (ot) {
+ return;
+ }
+ ot = true;
+ }
+
+ if ((ret = SMB_THREAD_CREATE_TLS("test_tls", pkey)) != 0) {
+ printf("Create tls once error: %d\n", ret);
+ }
+}
+
+/* Test function. */
+int test_threads(void)
+{
+ int ret;
+ void *plock = NULL;
+ smb_thread_set_functions(&tf);
+
+ SMB_THREAD_ONCE(&ot, init_fn);
+
+ if ((ret = SMB_THREAD_CREATE_MUTEX("test", plock)) != 0) {
+ printf("Create lock error: %d\n", ret);
+ }
+ if ((ret = SMB_THREAD_LOCK(plock, SMB_THREAD_LOCK)) != 0) {
+ printf("lock error: %d\n", ret);
+ }
+ if ((ret = SMB_THREAD_LOCK(plock, SMB_THREAD_UNLOCK)) != 0) {
+ printf("unlock error: %d\n", ret);
+ }
+ SMB_THREAD_DESTROY_MUTEX(plock);
+ SMB_THREAD_DESTROY_TLS(pkey);
+
+ return 0;
+}
+#endif
diff --git a/lib/util/smb_threads.h b/lib/util/smb_threads.h
new file mode 100644
index 0000000..67d05b8
--- /dev/null
+++ b/lib/util/smb_threads.h
@@ -0,0 +1,137 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB thread interface functions.
+ Copyright (C) Jeremy Allison, 2009.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _smb_threads_h_
+#define _smb_threads_h_
+
+typedef bool smb_thread_once_t;
+#define SMB_THREAD_ONCE_INIT false
+
+enum smb_thread_lock_type {
+ SMB_THREAD_LOCK = 1,
+ SMB_THREAD_UNLOCK
+};
+
+struct smb_thread_functions {
+ /* Mutex and tls functions. */
+ int (*create_mutex)(const char *lockname,
+ void **pplock,
+ const char *location);
+ void (*destroy_mutex)(void *plock,
+ const char *location);
+ int (*lock_mutex)(void *plock,
+ int lock_type,
+ const char *location);
+
+ /* Thread local storage. */
+ int (*create_tls)(const char *keyname,
+ void **ppkey,
+ const char *location);
+ void (*destroy_tls)(void **pkey,
+ const char *location);
+ int (*set_tls)(void *pkey, const void *pval, const char *location);
+ void *(*get_tls)(void *pkey, const char *location);
+};
+
+int smb_thread_set_functions(const struct smb_thread_functions *tf);
+int smb_thread_once(smb_thread_once_t *ponce,
+ void (*init_fn)(void *pdata),
+ void *pdata);
+
+extern const struct smb_thread_functions *global_tfp;
+
+/* Define the pthread version of the functions. */
+
+#define SMB_THREADS_DEF_PTHREAD_IMPLEMENTATION(tf) \
+ \
+static int smb_create_mutex_pthread(const char *lockname, void **pplock, const char *location) \
+{ \
+ pthread_mutex_t *pmut = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); \
+ if (!pmut) { \
+ return ENOMEM; \
+ } \
+ pthread_mutex_init(pmut, NULL); \
+ *pplock = (void *)pmut; \
+ return 0; \
+} \
+ \
+static void smb_destroy_mutex_pthread(void *plock, const char *location) \
+{ \
+ pthread_mutex_destroy((pthread_mutex_t *)plock); \
+ free(plock); \
+} \
+ \
+static int smb_lock_pthread(void *plock, int lock_type, const char *location) \
+{ \
+ if (lock_type == SMB_THREAD_UNLOCK) { \
+ return pthread_mutex_unlock((pthread_mutex_t *)plock); \
+ } else { \
+ return pthread_mutex_lock((pthread_mutex_t *)plock); \
+ } \
+} \
+ \
+static int smb_create_tls_pthread(const char *keyname, void **ppkey, const char *location) \
+{ \
+ int ret; \
+ pthread_key_t *pkey; \
+ pkey = (pthread_key_t *)malloc(sizeof(pthread_key_t)); \
+ if (!pkey) { \
+ return ENOMEM; \
+ } \
+ ret = pthread_key_create(pkey, NULL); \
+ if (ret) { \
+ free(pkey); \
+ return ret; \
+ } \
+ *ppkey = (void *)pkey; \
+ return 0; \
+} \
+ \
+static void smb_destroy_tls_pthread(void **ppkey, const char *location) \
+{ \
+ if (*ppkey) { \
+ pthread_key_delete(*(pthread_key_t *)ppkey); \
+ free(*ppkey); \
+ *ppkey = NULL; \
+ } \
+} \
+ \
+static int smb_set_tls_pthread(void *pkey, const void *pval, const char *location) \
+{ \
+ return pthread_setspecific(*(pthread_key_t *)pkey, pval); \
+} \
+ \
+static void *smb_get_tls_pthread(void *pkey, const char *location) \
+{ \
+ if (pkey == NULL) { \
+ return NULL; \
+ } \
+ return pthread_getspecific(*(pthread_key_t *)pkey); \
+} \
+ \
+static const struct smb_thread_functions (tf) = { \
+ smb_create_mutex_pthread, \
+ smb_destroy_mutex_pthread, \
+ smb_lock_pthread, \
+ smb_create_tls_pthread, \
+ smb_destroy_tls_pthread, \
+ smb_set_tls_pthread, \
+ smb_get_tls_pthread }
+
+#endif
diff --git a/lib/util/smb_threads_internal.h b/lib/util/smb_threads_internal.h
new file mode 100644
index 0000000..afd7559
--- /dev/null
+++ b/lib/util/smb_threads_internal.h
@@ -0,0 +1,74 @@
+/*
+ SMB/CIFS implementation.
+ SMB thread interface internal macros.
+ Copyright (C) Jeremy Allison, 2009.
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _smb_threads_internal_h_
+#define _smb_threads_internal_h_
+
+#define SMB_THREAD_CREATE_MUTEX(name, lockvar) \
+ (global_tfp ? global_tfp->create_mutex((name), &(lockvar), __location__) : 0)
+
+#define SMB_THREAD_DESTROY_MUTEX(plock) \
+ do { \
+ if (global_tfp) { \
+ global_tfp->destroy_mutex(plock, __location__); \
+ }; \
+ } while (0)
+
+#define SMB_THREAD_LOCK_INTERNAL(plock, type, location) \
+ (global_tfp ? global_tfp->lock_mutex((plock), (type), location) : 0)
+
+#define SMB_THREAD_LOCK(plock) \
+ SMB_THREAD_LOCK_INTERNAL(plock, SMB_THREAD_LOCK, __location__)
+
+#define SMB_THREAD_UNLOCK(plock) \
+ SMB_THREAD_LOCK_INTERNAL(plock, SMB_THREAD_UNLOCK, __location__)
+
+#define SMB_THREAD_ONCE(ponce, init_fn, pdata) \
+ (global_tfp \
+ ? (! *(ponce) \
+ ? smb_thread_once((ponce), (init_fn), (pdata)) \
+ : 0) \
+ : ((init_fn(pdata)), *(ponce) = true, 1))
+
+#define SMB_THREAD_CREATE_TLS(keyname, key) \
+ (global_tfp ? global_tfp->create_tls((keyname), &(key), __location__) : 0)
+
+#define SMB_THREAD_DESTROY_TLS(key) \
+ do { \
+ if (global_tfp) { \
+ global_tfp->destroy_tls(&(key), __location__); \
+ }; \
+ } while (0)
+
+#define SMB_THREAD_SET_TLS(key, val) \
+ (global_tfp ? global_tfp->set_tls((key),(val),__location__) : \
+ ((key) = (val), 0))
+
+#define SMB_THREAD_GET_TLS(key) \
+ (global_tfp ? global_tfp->get_tls((key), __location__) : (key))
+
+/*
+ * Global thread lock list.
+ */
+
+#define NUM_GLOBAL_LOCKS 1
+
+#define GLOBAL_LOCK(locknum) (global_lock_array ? global_lock_array[(locknum)] : NULL)
+
+#endif
diff --git a/lib/util/stable_sort.c b/lib/util/stable_sort.c
new file mode 100644
index 0000000..47667c4
--- /dev/null
+++ b/lib/util/stable_sort.c
@@ -0,0 +1,250 @@
+/*
+ Stable sort routines
+
+ Copyright © Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
+
+ ** NOTE! The following LGPL license applies to this file which is used by
+ ** the ldb library. This does NOT imply that all of Samba is released
+ ** under the LGPL.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <talloc.h>
+#include "replace.h"
+#include "stable_sort.h"
+
+static void sort_few(char *array, char *aux,
+ size_t n,
+ size_t s,
+ samba_compare_with_context_fn_t cmpfn,
+ void *opaque)
+{
+ /* a kind of insertion sort for small n. */
+ int i, j, dist;
+ int cmp;
+ char *a, *b;
+
+ for (i = 1; i < n; i++) {
+ a = &array[i * s];
+ /* leftwards is sorted. look until we find this one's place */
+ for (j = i - 1; j >= 0; j--) {
+ b = &array[j * s];
+ cmp = cmpfn(a, b, opaque);
+ if (cmp >= 0) {
+ break;
+ }
+ }
+ dist = i - 1 - j;
+ if (dist == 0) {
+ /* a is already in the right place */
+ continue;
+ }
+
+ b = &array[(i - dist) * s];
+ memcpy(aux, a, s);
+ memmove(b + s, b, s * dist);
+ memcpy(b, aux, s);
+ }
+}
+
+
+static void merge(char *dest,
+ char *a, size_t alen,
+ char *b, size_t blen,
+ size_t s,
+ samba_compare_with_context_fn_t cmpfn,
+ void *opaque)
+{
+ size_t ai = 0;
+ size_t bi = 0;
+ size_t di = 0;
+ while (ai < alen && bi < blen) {
+ int cmp = cmpfn(&a[ai * s], &b[bi * s], opaque);
+ if (cmp <= 0) {
+ memcpy(&dest[di * s], &a[ai * s], s);
+ ai++;
+ } else {
+ memcpy(&dest[di * s], &b[bi * s], s);
+ bi++;
+ }
+ di++;
+ }
+ if (ai < alen) {
+ memcpy(&dest[di * s], &a[ai * s], s * (alen - ai));
+ } else if (bi < blen) {
+ memcpy(&dest[di * s], &b[bi * s], s * (blen - bi));
+ }
+}
+
+
+bool stable_sort_r(void *array, void *aux,
+ size_t n,
+ size_t s,
+ samba_compare_with_context_fn_t cmpfn,
+ void * opaque)
+{
+ char *src = array, *dest = aux, *tmp = NULL;
+ size_t i, j, k;
+ size_t runsize;
+ if (array == NULL || aux == NULL) {
+ return false;
+ }
+
+ if (n < 20) {
+ sort_few(array, aux, n, s, cmpfn, opaque);
+ return true;
+ }
+
+ if (n > SIZE_MAX / s) {
+ /*
+ * We will have an integer overflow if we continue.
+ *
+ * This means that the *supposed* size of the allocated buffer
+ * is greater than SIZE_MAX, which is not possible in theory
+ * or practice, and is a sign the caller has got very
+ * confused.
+ */
+ return false;
+ }
+
+ /*
+ * This is kind of a bottom-up merge sort.
+ *
+ * We start but sorting into a whole lot of little runs, using an
+ * insertion sort which is efficient for small numbers. Empirically,
+ * on 2 machines, a run size of around 8 seems optimal, but the peak
+ * is wide, and it seems worth adapting the size to avoid an
+ * unbalanced final merge at the top. That is, if we pick the right
+ * runsize now, we will finish with a merge of roughly n/2:n/2, and
+ * not have to follow that with an merge of roughly n:[a few], which
+ * we would sometimes do with a fixed size at the lowest level.
+ *
+ * The aim is a runsize of n / (a power of 2) rounded up, in the
+ * target range.
+ */
+
+ runsize = n;
+ while (runsize > 10) {
+ runsize++;
+ runsize >>= 1;
+ }
+
+ for (i = 0; i < n; i += runsize) {
+ size_t nn = MIN(n - i, runsize);
+ sort_few(&src[i * s], aux, nn, s, cmpfn, opaque);
+ }
+
+ while (runsize < n) {
+ for (i = 0; i < n; i += runsize * 2) {
+ j = i + runsize;
+ if (j >= n) {
+ /*
+ * first run doesn't fit, meaning this chunk
+ * is already sorted. We just need to copy
+ * it.
+ */
+ size_t nn = n - i;
+ memcpy(&dest[i * s], &src[i * s], nn * s);
+ break;
+ }
+ k = j + runsize;
+ if (k > n) {
+ merge(&dest[i * s],
+ &src[i * s], runsize,
+ &src[j * s], n - j,
+ s,
+ cmpfn, opaque);
+ } else {
+ merge(&dest[i * s],
+ &src[i * s], runsize,
+ &src[j * s], runsize,
+ s,
+ cmpfn, opaque);
+ }
+ }
+
+ tmp = src;
+ src = dest;
+ dest = tmp;
+ runsize *= 2;
+ }
+ /*
+ * We have sorted the array into src, which is either array or aux.
+ */
+ if (src != array) {
+ memcpy(array, src, n * s);
+ }
+ return true;
+}
+
+
+
+/*
+ * A wrapper that allocates (and frees) the temporary buffer if necessary.
+ *
+ * returns false on allocation error, true otherwise.
+ */
+
+bool stable_sort_talloc_r(TALLOC_CTX *mem_ctx,
+ void *array,
+ size_t n,
+ size_t s,
+ samba_compare_with_context_fn_t cmpfn,
+ void *opaque)
+{
+ bool ok;
+ char *mem = talloc_array_size(mem_ctx, s, n);
+ if (mem == NULL) {
+ return false;
+ }
+ ok = stable_sort_r(array, mem, n, s, cmpfn, opaque);
+ talloc_free(mem);
+ return ok;
+}
+
+
+bool stable_sort(void *array, void *aux,
+ size_t n,
+ size_t s,
+ samba_compare_fn_t cmpfn)
+{
+ /*
+ * What is this magic, casting cmpfn into a different type that takes
+ * an extra parameter? Is that allowed?
+ *
+ * A: Yes. It's fine. The extra argument will be passed on the stack
+ * or (more likely) a register, and the cmpfn will remain blissfully
+ * unaware.
+ */
+ return stable_sort_r(array, aux, n, s,
+ (samba_compare_with_context_fn_t)cmpfn,
+ NULL);
+}
+
+
+bool stable_sort_talloc(TALLOC_CTX *mem_ctx,
+ void *array,
+ size_t n,
+ size_t s,
+ samba_compare_fn_t cmpfn)
+{
+ return stable_sort_talloc_r(mem_ctx, array, n, s,
+ (samba_compare_with_context_fn_t)cmpfn,
+ NULL);
+}
diff --git a/lib/util/stable_sort.h b/lib/util/stable_sort.h
new file mode 100644
index 0000000..17329b8
--- /dev/null
+++ b/lib/util/stable_sort.h
@@ -0,0 +1,46 @@
+#ifndef HAVE_STABLE_SORT_H
+#define HAVE_STABLE_SORT_H 1
+
+#ifdef __COMPAR_FN_T
+typedef __compar_fn_t samba_compare_fn_t;
+
+#ifdef __USE_GNU
+/* glibc defines __compar_d_fn_t for qsort_r */
+typedef __compar_d_fn_t samba_compare_with_context_fn_t;
+#endif
+
+#else
+typedef int (*samba_compare_fn_t) (const void *, const void *);
+typedef int (*samba_compare_with_context_fn_t) (const void *, const void *, void *);
+#endif
+
+
+
+bool stable_sort_r(void *array, void *aux,
+ size_t n,
+ size_t s,
+ samba_compare_with_context_fn_t cmpfn,
+ void *opaque);
+
+bool stable_sort(void *array, void *aux,
+ size_t n,
+ size_t s,
+ samba_compare_fn_t cmpfn);
+
+
+bool stable_sort_talloc_r(TALLOC_CTX *mem_ctx,
+ void *array,
+ size_t n,
+ size_t s,
+ samba_compare_with_context_fn_t cmpfn,
+ void *opaque);
+
+
+bool stable_sort_talloc(TALLOC_CTX *mem_ctx,
+ void *array,
+ size_t n,
+ size_t s,
+ samba_compare_fn_t cmpfn);
+
+
+#endif /* HAVE_STABLE_SORT_H */
diff --git a/lib/util/string_wrappers.h b/lib/util/string_wrappers.h
new file mode 100644
index 0000000..7625cd0
--- /dev/null
+++ b/lib/util/string_wrappers.h
@@ -0,0 +1,99 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ string wrappers, for checking string sizes
+
+ Copyright (C) Andrew Tridgell 1994-2011
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _STRING_WRAPPERS_H
+#define _STRING_WRAPPERS_H
+
+#include "lib/replace/replace.h" /* for config symbols */
+
+#define strlcpy_base(dest, src, base, size) \
+do { \
+ const char *_strlcpy_base_src = (const char *)src; \
+ strlcpy((dest), _strlcpy_base_src? _strlcpy_base_src : "", (size)-PTR_DIFF((dest),(base))); \
+} while (0)
+
+/* String copy functions - macro hell below adds 'type checking' (limited,
+ but the best we can do in C) */
+
+#define fstrcpy(d,s) \
+do { \
+ const char *_fstrcpy_src = (const char *)(s); \
+ strlcpy((d),_fstrcpy_src ? _fstrcpy_src : "",sizeof(fstring)); \
+} while (0)
+
+#define fstrcat(d,s) \
+do { \
+ const char *_fstrcat_src = (const char *)(s); \
+ strlcat((d),_fstrcat_src ? _fstrcat_src : "",sizeof(fstring)); \
+} while (0)
+#define unstrcpy(d,s) \
+do { \
+ const char *_unstrcpy_src = (const char *)(s); \
+ strlcpy((d),_unstrcpy_src ? _unstrcpy_src : "",sizeof(unstring)); \
+} while (0)
+
+#ifdef HAVE_COMPILER_WILL_OPTIMIZE_OUT_FNS
+
+/* We need a number of different prototypes for our
+ non-existent functions */
+char * __unsafe_string_function_usage_here__(void);
+
+size_t __unsafe_string_function_usage_here_size_t__(void);
+
+NTSTATUS __unsafe_string_function_usage_here_NTSTATUS__(void);
+
+#define CHECK_STRING_SIZE(d, len) (sizeof(d) != (len) && sizeof(d) != sizeof(char *))
+
+/* if the compiler will optimize out function calls, then use this to tell if we are
+ have the correct types (this works only where sizeof() returns the size of the buffer, not
+ the size of the pointer). */
+
+#define push_string_check(dest, src, dest_len, flags) \
+ (CHECK_STRING_SIZE(dest, dest_len) \
+ ? __unsafe_string_function_usage_here_size_t__() \
+ : push_string_check_fn(dest, src, dest_len, flags))
+
+#define srvstr_push(base_ptr, smb_flags2, dest, src, dest_len, flags, ret_len) \
+ (CHECK_STRING_SIZE(dest, dest_len) \
+ ? __unsafe_string_function_usage_here_NTSTATUS__() \
+ : srvstr_push_fn(base_ptr, smb_flags2, dest, src, dest_len, flags, ret_len))
+
+/* This allows the developer to choose to check the arguments to
+ strlcpy. if the compiler will optimize out function calls, then
+ use this to tell if we are have the correct size buffer (this works only
+ where sizeof() returns the size of the buffer, not the size of the
+ pointer), so stack and static variables only */
+
+#define checked_strlcpy(dest, src, size) \
+ (sizeof(dest) != (size) \
+ ? __unsafe_string_function_usage_here_size_t__() \
+ : strlcpy(dest, src, size))
+
+#else
+
+#define push_string_check push_string_check_fn
+#define srvstr_push srvstr_push_fn
+#define checked_strlcpy strlcpy
+
+#endif
+
+#endif
diff --git a/lib/util/strv.c b/lib/util/strv.c
new file mode 100644
index 0000000..83d84d9
--- /dev/null
+++ b/lib/util/strv.c
@@ -0,0 +1,191 @@
+/*
+ * String Vector functions modeled after glibc argv_* functions
+ *
+ * Copyright Volker Lendecke <vl@samba.org> 2014
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "strv.h"
+#include "talloc.h"
+#include <string.h>
+
+static int _strv_append(TALLOC_CTX *mem_ctx, char **dst, const char *src,
+ size_t srclen)
+{
+ size_t dstlen = talloc_array_length(*dst);
+ size_t newlen = dstlen + srclen;
+ char *new_dst;
+
+ if ((newlen < srclen) || (newlen < dstlen)) {
+ return ERANGE;
+ }
+
+ new_dst = talloc_realloc(mem_ctx, *dst, char, newlen);
+ if (new_dst == NULL) {
+ return ENOMEM;
+ }
+ memcpy(&new_dst[dstlen], src, srclen);
+
+ *dst = new_dst;
+ return 0;
+}
+
+int strv_add(TALLOC_CTX *mem_ctx, char **strv, const char *string)
+{
+ return _strv_append(mem_ctx, strv, string, strlen(string)+1);
+}
+
+int strv_addn(TALLOC_CTX *mem_ctx, char **strv, const char *string, size_t n)
+{
+ char t[n+1];
+
+ memcpy(t, string, n);
+ t[n] = '\0';
+ return _strv_append(mem_ctx, strv, t, n+1);
+}
+
+int strv_append(TALLOC_CTX *mem_ctx, char **strv, const char *src)
+{
+ return _strv_append(mem_ctx, strv, src, talloc_array_length(src));
+}
+
+static bool strv_valid_entry(const char *strv, size_t strv_len,
+ const char *entry, size_t *entry_len)
+{
+ if (strv_len == 0) {
+ return false;
+ }
+ if (strv[strv_len-1] != '\0') {
+ return false;
+ }
+
+ if (entry < strv) {
+ return false;
+ }
+ if (entry >= (strv+strv_len)) {
+ return false;
+ }
+
+ if (entry_len != NULL) {
+ *entry_len = strlen(entry);
+ }
+
+ return true;
+}
+
+const char *strv_len_next(const char *strv, size_t strv_len,
+ const char *entry)
+{
+ size_t entry_len;
+
+ if (entry == NULL) {
+ if (strv_valid_entry(strv, strv_len, strv, NULL)) {
+ return strv;
+ }
+ return NULL;
+ }
+
+ if (!strv_valid_entry(strv, strv_len, entry, &entry_len)) {
+ return NULL;
+ }
+
+ entry += entry_len+1;
+
+ if (entry >= (strv + strv_len)) {
+ return NULL;
+ }
+ return entry;
+}
+
+char *strv_next(char *strv, const char *entry)
+{
+ size_t len = talloc_array_length(strv);
+ const char *result;
+
+ result = strv_len_next(strv, len, entry);
+ return discard_const_p(char, result);
+}
+
+size_t strv_count(char *strv)
+{
+ char *entry;
+ size_t count = 0;
+
+ for (entry = strv; entry != NULL; entry = strv_next(strv, entry)) {
+ count += 1;
+ }
+
+ return count;
+}
+
+char *strv_find(char *strv, const char *entry)
+{
+ char *e = NULL;
+
+ while ((e = strv_next(strv, e)) != NULL) {
+ if (strcmp(e, entry) == 0) {
+ return e;
+ }
+ }
+
+ return NULL;
+}
+
+void strv_delete(char **strv, char *entry)
+{
+ size_t len = talloc_array_length(*strv);
+ size_t entry_len;
+
+ if (entry == NULL) {
+ return;
+ }
+
+ if (!strv_valid_entry(*strv, len, entry, &entry_len)) {
+ return;
+ }
+ entry_len += 1;
+
+ memmove(entry, entry+entry_len,
+ len - entry_len - (entry - *strv));
+
+ *strv = talloc_realloc(NULL, *strv, char, len - entry_len);
+}
+
+char * const *strv_to_env(TALLOC_CTX *mem_ctx, char *strv)
+{
+ char **data;
+ char *next = NULL;
+ size_t i;
+ size_t count = strv_count(strv);
+
+ if (strv == NULL) {
+ return NULL;
+ }
+
+ data = talloc_array(mem_ctx, char *, count + 1);
+
+ if (data == NULL) {
+ return NULL;
+ }
+
+ for(i = 0; i < count; i++) {
+ next = strv_next(strv, next);
+ data[i] = next;
+ }
+ data[count] = NULL;
+
+ return data;
+}
diff --git a/lib/util/strv.h b/lib/util/strv.h
new file mode 100644
index 0000000..a6197e5
--- /dev/null
+++ b/lib/util/strv.h
@@ -0,0 +1,37 @@
+/*
+ * String Vector functions modeled after glibc argv_* functions
+ *
+ * Copyright Volker Lendecke <vl@samba.org> 2014
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _STRV_H_
+#define _STRV_H_
+
+#include "replace.h"
+#include <talloc.h>
+
+int strv_add(TALLOC_CTX *mem_ctx, char **strv, const char *string);
+int strv_addn(TALLOC_CTX *mem_ctx, char **strv, const char *src, size_t srclen);
+int strv_append(TALLOC_CTX *mem_ctx, char **strv, const char *src);
+char *strv_next(char *strv, const char *entry);
+const char *strv_len_next(const char *strv, size_t strv_len,
+ const char *entry);
+char *strv_find(char *strv, const char *entry);
+size_t strv_count(char *strv);
+void strv_delete(char **strv, char *entry);
+char * const *strv_to_env(TALLOC_CTX *mem_ctx, char *strv);
+
+#endif
diff --git a/lib/util/strv_util.c b/lib/util/strv_util.c
new file mode 100644
index 0000000..9da3eb2
--- /dev/null
+++ b/lib/util/strv_util.c
@@ -0,0 +1,61 @@
+/*
+ * strv-based utilities
+ *
+ * Copyright Martin Schwenke <martin@meltin.net> 2016
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+
+#include <string.h>
+#include <talloc.h>
+
+#include "strv.h"
+
+#include "strv_util.h"
+
+int strv_split(TALLOC_CTX *mem_ctx, char **strv,
+ const char *src, const char *sep)
+{
+ const char *s;
+
+ if (src == NULL) {
+ return 0;
+ }
+
+ s = src;
+ while (*s != '\0') {
+ size_t len;
+
+ /* Skip separators */
+ len = strspn(s, sep);
+ if (len != 0) {
+ s += len;
+ }
+
+ /* Find non-separator substring */
+ len = strcspn(s, sep);
+ if (len != 0) {
+ int ret = strv_addn(mem_ctx, strv, s, len);
+ if (ret != 0) {
+ TALLOC_FREE(*strv);
+ return ret;
+ }
+ s += len;
+ }
+ }
+
+ return 0;
+}
diff --git a/lib/util/strv_util.h b/lib/util/strv_util.h
new file mode 100644
index 0000000..9456d43
--- /dev/null
+++ b/lib/util/strv_util.h
@@ -0,0 +1,30 @@
+/*
+ * strv-based utilities
+ *
+ * Copyright Martin Schwenke <martin@meltin.net> 2016
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _STRV_UTIL_H_
+#define _STRV_UTIL_H_
+
+#include <talloc.h>
+
+/* Split string at characters in sep, adding non-separator words to
+ * *strv. On failure *strv is undefined. */
+int strv_split(TALLOC_CTX *mem_ctx, char **strv,
+ const char *string, const char *sep);
+
+#endif
diff --git a/lib/util/substitute.c b/lib/util/substitute.c
new file mode 100644
index 0000000..b7b5588
--- /dev/null
+++ b/lib/util/substitute.c
@@ -0,0 +1,280 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+
+ Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) Simo Sorce 2001-2002
+ Copyright (C) Martin Pool 2003
+ Copyright (C) James Peach 2005
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "debug.h"
+#ifndef SAMBA_UTIL_CORE_ONLY
+#include "charset/charset.h"
+#else
+#include "charset_compat.h"
+#endif
+#include "substitute.h"
+
+/**
+ * @file
+ * @brief Substitute utilities.
+ **/
+
+/**
+ Substitute a string for a pattern in another string. Make sure there is
+ enough room!
+
+ This routine looks for pattern in s and replaces it with
+ insert. It may do multiple replacements or just one.
+
+ Any of " ; ' $ or ` in the insert string are replaced with _
+ if len==0 then the string cannot be extended. This is different from the old
+ use of len==0 which was for no length checks to be done.
+**/
+
+static void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
+ bool remove_unsafe_characters, bool replace_once,
+ bool allow_trailing_dollar)
+{
+ char *p;
+ size_t ls, lp, li, i;
+
+ if (!insert || !pattern || !*pattern || !s)
+ return;
+
+ ls = strlen(s);
+ lp = strlen(pattern);
+ li = strlen(insert);
+
+ if (len == 0)
+ len = ls + 1; /* len is number of *bytes* */
+
+ while (lp <= ls && (p = strstr_m(s,pattern))) {
+ if (ls + li - lp >= len) {
+ DBG_ERR("ERROR: string overflow by "
+ "%zu in string_sub(%.50s, %zu)\n",
+ ls + li - lp + 1 - len,
+ pattern,
+ len);
+ break;
+ }
+ if (li != lp) {
+ memmove(p+li,p+lp,strlen(p+lp)+1);
+ }
+ for (i=0;i<li;i++) {
+ switch (insert[i]) {
+ case '$':
+ /* allow a trailing $
+ * (as in machine accounts) */
+ if (allow_trailing_dollar && (i == li - 1 )) {
+ p[i] = insert[i];
+ break;
+ }
+ FALL_THROUGH;
+ case '`':
+ case '"':
+ case '\'':
+ case ';':
+ case '%':
+ case '\r':
+ case '\n':
+ if ( remove_unsafe_characters ) {
+ p[i] = '_';
+ /* yes this break should be here
+ * since we want to fall throw if
+ * not replacing unsafe chars */
+ break;
+ }
+ FALL_THROUGH;
+ default:
+ p[i] = insert[i];
+ }
+ }
+ s = p + li;
+ ls = ls + li - lp;
+
+ if (replace_once)
+ break;
+ }
+}
+
+void string_sub(char *s,const char *pattern, const char *insert, size_t len)
+{
+ string_sub2( s, pattern, insert, len, true, false, false );
+}
+
+/**
+ Similar to string_sub() but allows for any character to be substituted.
+ Use with caution!
+ if len==0 then the string cannot be extended. This is different from the old
+ use of len==0 which was for no length checks to be done.
+**/
+
+_PUBLIC_ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
+{
+ char *p;
+ size_t ls,lp,li;
+
+ if (!insert || !pattern || !s)
+ return;
+
+ ls = strlen(s);
+ lp = strlen(pattern);
+ li = strlen(insert);
+
+ if (!*pattern)
+ return;
+
+ if (len == 0)
+ len = ls + 1; /* len is number of *bytes* */
+
+ while (lp <= ls && (p = strstr_m(s,pattern))) {
+ if (ls + li - lp >= len) {
+ DBG_ERR("ERROR: string overflow by "
+ "%zu in all_string_sub(%.50s, %zu)\n",
+ ls + li - lp + 1 - len,
+ pattern,
+ len);
+ break;
+ }
+ if (li != lp) {
+ memmove(p+li,p+lp,strlen(p+lp)+1);
+ }
+ memcpy(p, insert, li);
+ s = p + li;
+ ls = ls + li - lp;
+ }
+}
+
+/*
+ * Internal guts of talloc_string_sub and talloc_all_string_sub.
+ * talloc version of string_sub2.
+ */
+
+char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
+ const char *pattern,
+ const char *insert,
+ bool remove_unsafe_characters,
+ bool replace_once,
+ bool allow_trailing_dollar)
+{
+ char *p, *in;
+ char *s;
+ char *string;
+ ssize_t ls,lp,li,ld, i;
+
+ if (!insert || !pattern || !*pattern || !src) {
+ return NULL;
+ }
+
+ string = talloc_strdup(mem_ctx, src);
+ if (string == NULL) {
+ DEBUG(0, ("talloc_string_sub2: "
+ "talloc_strdup failed\n"));
+ return NULL;
+ }
+
+ s = string;
+
+ in = talloc_strdup(mem_ctx, insert);
+ if (!in) {
+ DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
+ talloc_free(string);
+ return NULL;
+ }
+ ls = (ssize_t)strlen(s);
+ lp = (ssize_t)strlen(pattern);
+ li = (ssize_t)strlen(insert);
+ ld = li - lp;
+
+ for (i=0;i<li;i++) {
+ switch (in[i]) {
+ case '$':
+ /* allow a trailing $
+ * (as in machine accounts) */
+ if (allow_trailing_dollar && (i == li - 1 )) {
+ break;
+ }
+
+ FALL_THROUGH;
+ case '`':
+ case '"':
+ case '\'':
+ case ';':
+ case '%':
+ case '\r':
+ case '\n':
+ if (remove_unsafe_characters) {
+ in[i] = '_';
+ break;
+ }
+
+ FALL_THROUGH;
+ default:
+ /* ok */
+ break;
+ }
+ }
+
+ while ((p = strstr_m(s,pattern))) {
+ if (ld > 0) {
+ int offset = PTR_DIFF(s,string);
+ string = (char *)talloc_realloc_size(mem_ctx, string,
+ ls + ld + 1);
+ if (!string) {
+ DEBUG(0, ("talloc_string_sub: out of "
+ "memory!\n"));
+ TALLOC_FREE(in);
+ return NULL;
+ }
+ p = string + offset + (p - s);
+ }
+ if (li != lp) {
+ memmove(p+li,p+lp,strlen(p+lp)+1);
+ }
+ memcpy(p, in, li);
+ s = p + li;
+ ls += ld;
+
+ if (replace_once) {
+ break;
+ }
+ }
+ TALLOC_FREE(in);
+ return string;
+}
+
+/* Same as string_sub, but returns a talloc'ed string */
+
+char *talloc_string_sub(TALLOC_CTX *mem_ctx,
+ const char *src,
+ const char *pattern,
+ const char *insert)
+{
+ return talloc_string_sub2(mem_ctx, src, pattern, insert,
+ true, false, false);
+}
+
+char *talloc_all_string_sub(TALLOC_CTX *ctx,
+ const char *src,
+ const char *pattern,
+ const char *insert)
+{
+ return talloc_string_sub2(ctx, src, pattern, insert,
+ false, false, false);
+}
diff --git a/lib/util/substitute.h b/lib/util/substitute.h
new file mode 100644
index 0000000..3134cfc
--- /dev/null
+++ b/lib/util/substitute.h
@@ -0,0 +1,64 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+
+ Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) Simo Sorce 2001-2002
+ Copyright (C) Martin Pool 2003
+ Copyright (C) James Peach 2005
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_SUBSTITUTE_H_
+#define _SAMBA_SUBSTITUTE_H_
+
+#include <talloc.h>
+
+/**
+ Substitute a string for a pattern in another string. Make sure there is
+ enough room!
+
+ This routine looks for pattern in s and replaces it with
+ insert. It may do multiple replacements.
+
+ Any of " ; ' $ or ` in the insert string are replaced with _
+ if len==0 then the string cannot be extended. This is different from the old
+ use of len==0 which was for no length checks to be done.
+**/
+void string_sub(char *s,const char *pattern, const char *insert, size_t len);
+
+/**
+ Similar to string_sub() but allows for any character to be substituted.
+ Use with caution!
+ if len==0 then the string cannot be extended. This is different from the old
+ use of len==0 which was for no length checks to be done.
+**/
+void all_string_sub(char *s,const char *pattern,const char *insert, size_t len);
+
+char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
+ const char *pattern,
+ const char *insert,
+ bool remove_unsafe_characters,
+ bool replace_once,
+ bool allow_trailing_dollar);
+char *talloc_string_sub(TALLOC_CTX *mem_ctx,
+ const char *src,
+ const char *pattern,
+ const char *insert);
+char *talloc_all_string_sub(TALLOC_CTX *ctx,
+ const char *src,
+ const char *pattern,
+ const char *insert);
+#endif /* _SAMBA_SUBSTITUTE_H_ */
diff --git a/lib/util/sys_popen.c b/lib/util/sys_popen.c
new file mode 100644
index 0000000..f62199b
--- /dev/null
+++ b/lib/util/sys_popen.c
@@ -0,0 +1,177 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba system utilities
+ * Copyright (C) Jeremy Allison 2000
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/wait.h"
+#include "system/filesys.h"
+#include <talloc.h>
+#include "lib/util/sys_popen.h"
+#include "lib/util/debug.h"
+
+/**************************************************************************
+ Wrapper for popen. Safer as it doesn't search a path.
+ Modified from the glibc sources.
+ modified by tridge to return a file descriptor. We must kick our FILE* habit
+****************************************************************************/
+
+typedef struct _popen_list
+{
+ int fd;
+ pid_t child_pid;
+ struct _popen_list *next;
+} popen_list;
+
+static popen_list *popen_chain;
+
+int sys_popenv(char * const argl[])
+{
+ int parent_end, child_end;
+ int pipe_fds[2];
+ popen_list *entry = NULL;
+ const char *command = NULL;
+ int ret;
+
+ if (argl == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ command = argl[0];
+
+ if (!*command) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ ret = pipe(pipe_fds);
+ if (ret < 0) {
+ DBG_ERR("error opening pipe: %s\n",
+ strerror(errno));
+ return -1;
+ }
+
+ parent_end = pipe_fds[0];
+ child_end = pipe_fds[1];
+
+ entry = talloc_zero(NULL, popen_list);
+ if (entry == NULL) {
+ DBG_ERR("talloc failed\n");
+ goto err_exit;
+ }
+
+ entry->child_pid = fork();
+
+ if (entry->child_pid == -1) {
+ DBG_ERR("fork failed: %s\n", strerror(errno));
+ goto err_exit;
+ }
+
+ if (entry->child_pid == 0) {
+
+ /*
+ * Child !
+ */
+
+ int child_std_end = STDOUT_FILENO;
+ popen_list *p;
+
+ close(parent_end);
+ if (child_end != child_std_end) {
+ dup2 (child_end, child_std_end);
+ close (child_end);
+ }
+
+ /*
+ * POSIX.2: "popen() shall ensure that any streams from previous
+ * popen() calls that remain open in the parent process are closed
+ * in the new child process."
+ */
+
+ for (p = popen_chain; p; p = p->next)
+ close(p->fd);
+
+ ret = execv(argl[0], argl);
+ if (ret == -1) {
+ DBG_ERR("ERROR executing command "
+ "'%s': %s\n", command, strerror(errno));
+ }
+ _exit (127);
+ }
+
+ /*
+ * Parent.
+ */
+
+ close (child_end);
+
+ /* Link into popen_chain. */
+ entry->next = popen_chain;
+ popen_chain = entry;
+ entry->fd = parent_end;
+
+ return entry->fd;
+
+err_exit:
+
+ TALLOC_FREE(entry);
+ close(pipe_fds[0]);
+ close(pipe_fds[1]);
+ return -1;
+}
+
+/**************************************************************************
+ Wrapper for pclose. Modified from the glibc sources.
+****************************************************************************/
+
+int sys_pclose(int fd)
+{
+ int wstatus;
+ popen_list **ptr = &popen_chain;
+ popen_list *entry = NULL;
+ pid_t wait_pid;
+ int status = -1;
+
+ /* Unlink from popen_chain. */
+ for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
+ if ((*ptr)->fd == fd) {
+ entry = *ptr;
+ *ptr = (*ptr)->next;
+ status = 0;
+ break;
+ }
+ }
+
+ if (status < 0 || close(entry->fd) < 0)
+ return -1;
+
+ /*
+ * As Samba is catching and eating child process
+ * exits we don't really care about the child exit
+ * code, a -1 with errno = ECHILD will do fine for us.
+ */
+
+ do {
+ wait_pid = waitpid (entry->child_pid, &wstatus, 0);
+ } while (wait_pid == -1 && errno == EINTR);
+
+ TALLOC_FREE(entry);
+
+ if (wait_pid == -1)
+ return -1;
+ return wstatus;
+}
diff --git a/lib/util/sys_popen.h b/lib/util/sys_popen.h
new file mode 100644
index 0000000..be43748
--- /dev/null
+++ b/lib/util/sys_popen.h
@@ -0,0 +1,26 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba system utilities
+ * Copyright (C) Jeremy Allison 2000
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIB_SYS_POPEN_H__
+#define __LIB_SYS_POPEN_H__
+
+int sys_popenv(char * const argl[]);
+int sys_pclose(int fd);
+
+#endif
diff --git a/lib/util/sys_rw.c b/lib/util/sys_rw.c
new file mode 100644
index 0000000..d25a42b
--- /dev/null
+++ b/lib/util/sys_rw.c
@@ -0,0 +1,295 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba system utilities
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Copyright (C) Jeremy Allison 1998-2005
+ * Copyright (C) Timur Bakeyev 2005
+ * Copyright (C) Bjoern Jacke 2006-2007
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "lib/util/sys_rw.h"
+#include <assert.h>
+
+bool sys_valid_io_range(off_t offset, size_t length)
+{
+ uint64_t last_byte_ofs;
+
+ if (offset < 0) {
+ return false;
+ }
+
+ if (offset > INT64_MAX) {
+ return false;
+ }
+
+ if (length > UINT32_MAX) {
+ return false;
+ }
+
+ last_byte_ofs = (uint64_t)offset + (uint64_t)length;
+ if (last_byte_ofs > INT64_MAX) {
+ return false;
+ }
+
+ return true;
+}
+
+bool sys_io_ranges_overlap(size_t c1, off_t o1,
+ size_t c2, off_t o2)
+{
+ if (c1 == 0 || c2 == 0) {
+ return false;
+ }
+ if (o2 < o1) {
+ /*
+ * o1
+ * |····c1····|
+ * o2
+ * |····c2···| ?
+ */
+ return (o2 + c2 > o1);
+ } else {
+ /*
+ * o1
+ * |····c1···|
+ * o2
+ * |····c2····| ?
+ */
+ return (o1 + c1 > o2);
+ }
+}
+
+off_t sys_block_align_truncate(off_t len, off_t align)
+{
+ assert(align > 1);
+ assert(((align - 1) & align) == 0);
+ return len & (~align + 1);
+}
+
+off_t sys_block_align(off_t len, off_t align)
+{
+ assert(align > 1);
+ assert(((align - 1) & align) == 0);
+ return (len + (align - 1)) & ~(align - 1);
+}
+
+/*******************************************************************
+A read wrapper that will deal with EINTR/EWOULDBLOCK
+********************************************************************/
+
+ssize_t sys_read(int fd, void *buf, size_t count)
+{
+ ssize_t ret;
+
+ do {
+ ret = read(fd, buf, count);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN ||
+ errno == EWOULDBLOCK));
+
+ return ret;
+}
+
+/**
+ * read wrapper, void variant:
+ * This is intended to be used as a void variant of
+ * read in situations where the caller wants to ignore
+ * the result. Hence not checking for EAGAIN|EWOULDBLOCK.
+ */
+void sys_read_v(int fd, void *buf, size_t count)
+{
+ ssize_t ret;
+
+ do {
+ ret = read(fd, buf, count);
+ } while (ret == -1 && errno == EINTR);
+}
+
+
+/*******************************************************************
+A write wrapper that will deal with EINTR/EWOULDBLOCK.
+********************************************************************/
+
+ssize_t sys_write(int fd, const void *buf, size_t count)
+{
+ ssize_t ret;
+
+ do {
+ ret = write(fd, buf, count);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN ||
+ errno == EWOULDBLOCK));
+
+ return ret;
+}
+
+/**
+ * write wrapper to deal with EINTR and friends.
+ * void-variant that ignores the number of bytes written.
+ * This is intended to be used as a void variant of
+ * write in situations where the caller wants to ignore
+ * the result. Hence not checking for EAGAIN|EWOULDBLOCK.
+ */
+void sys_write_v(int fd, const void *buf, size_t count)
+{
+ ssize_t ret;
+
+ do {
+ ret = write(fd, buf, count);
+ } while (ret == -1 && errno == EINTR);
+}
+
+
+/*******************************************************************
+A writev wrapper that will deal with EINTR.
+********************************************************************/
+
+ssize_t sys_writev(int fd, const struct iovec *iov, int iovcnt)
+{
+ ssize_t ret;
+
+ do {
+ ret = writev(fd, iov, iovcnt);
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN ||
+ errno == EWOULDBLOCK));
+
+ return ret;
+}
+
+/*******************************************************************
+A pread wrapper that will deal with EINTR
+********************************************************************/
+
+ssize_t sys_pread(int fd, void *buf, size_t count, off_t off)
+{
+ ssize_t ret;
+
+ do {
+ ret = pread(fd, buf, count, off);
+ } while (ret == -1 && errno == EINTR);
+ return ret;
+}
+
+/*******************************************************************
+ A pread wrapper that will deal with EINTR and never return a short
+ read unless pread returns zero meaning EOF.
+********************************************************************/
+
+ssize_t sys_pread_full(int fd, void *buf, size_t count, off_t off)
+{
+ ssize_t total_read = 0;
+ uint8_t *curr_buf = (uint8_t *)buf;
+ size_t curr_count = count;
+ off_t curr_off = off;
+ bool ok;
+
+ ok = sys_valid_io_range(off, count);
+ if (!ok) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ while (curr_count != 0) {
+ ssize_t ret = sys_pread(fd,
+ curr_buf,
+ curr_count,
+ curr_off);
+
+ if (ret == -1) {
+ return -1;
+ }
+ if (ret == 0) {
+ /* EOF */
+ break;
+ }
+
+ if (ret > curr_count) {
+ errno = EIO;
+ return -1;
+ }
+
+ curr_buf += ret;
+ curr_count -= ret;
+ curr_off += ret;
+
+ total_read += ret;
+ }
+
+ return total_read;
+}
+
+/*******************************************************************
+A write wrapper that will deal with EINTR
+********************************************************************/
+
+ssize_t sys_pwrite(int fd, const void *buf, size_t count, off_t off)
+{
+ ssize_t ret;
+
+ do {
+ ret = pwrite(fd, buf, count, off);
+ } while (ret == -1 && errno == EINTR);
+ return ret;
+}
+
+/*******************************************************************
+ A pwrite wrapper that will deal with EINTR and never allow a short
+ write unless the file system returns an error.
+********************************************************************/
+
+ssize_t sys_pwrite_full(int fd, const void *buf, size_t count, off_t off)
+{
+ ssize_t total_written = 0;
+ const uint8_t *curr_buf = (const uint8_t *)buf;
+ size_t curr_count = count;
+ off_t curr_off = off;
+ bool ok;
+
+ ok = sys_valid_io_range(off, count);
+ if (!ok) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ while (curr_count != 0) {
+ ssize_t ret = sys_pwrite(fd,
+ curr_buf,
+ curr_count,
+ curr_off);
+
+ if (ret == -1) {
+ return -1;
+ }
+ if (ret == 0) {
+ /* Ensure we can never spin. */
+ errno = ENOSPC;
+ return -1;
+ }
+
+ if (ret > curr_count) {
+ errno = EIO;
+ return -1;
+ }
+
+ curr_buf += ret;
+ curr_count -= ret;
+ curr_off += ret;
+
+ total_written += ret;
+ }
+
+ return total_written;
+}
diff --git a/lib/util/sys_rw.h b/lib/util/sys_rw.h
new file mode 100644
index 0000000..3812159
--- /dev/null
+++ b/lib/util/sys_rw.h
@@ -0,0 +1,45 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba system utilities
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Copyright (C) Jeremy Allison 1998-2005
+ * Copyright (C) Timur Bakeyev 2005
+ * Copyright (C) Bjoern Jacke 2006-2007
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIB_SYS_RW_H__
+#define __LIB_SYS_RW_H__
+
+#include <unistd.h>
+
+struct iovec;
+
+off_t sys_block_align_truncate(off_t len, off_t align);
+off_t sys_block_align(off_t len, off_t align);
+bool sys_valid_io_range(off_t offset, size_t length);
+bool sys_io_ranges_overlap(size_t c1, off_t o1,
+ size_t c2, off_t o2);
+ssize_t sys_read(int fd, void *buf, size_t count);
+void sys_read_v(int fd, void *buf, size_t count);
+ssize_t sys_write(int fd, const void *buf, size_t count);
+void sys_write_v(int fd, const void *buf, size_t count);
+ssize_t sys_writev(int fd, const struct iovec *iov, int iovcnt);
+ssize_t sys_pread(int fd, void *buf, size_t count, off_t off);
+ssize_t sys_pread_full(int fd, void *buf, size_t count, off_t off);
+ssize_t sys_pwrite(int fd, const void *buf, size_t count, off_t off);
+ssize_t sys_pwrite_full(int fd, const void *buf, size_t count, off_t off);
+
+#endif
diff --git a/lib/util/sys_rw_data.c b/lib/util/sys_rw_data.c
new file mode 100644
index 0000000..a0d69f7
--- /dev/null
+++ b/lib/util/sys_rw_data.c
@@ -0,0 +1,117 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba system utilities
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Copyright (C) Jeremy Allison 1998-2005
+ * Copyright (C) Timur Bakeyev 2005
+ * Copyright (C) Bjoern Jacke 2006-2007
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "lib/util/sys_rw_data.h"
+#include "lib/util/sys_rw.h"
+#include "lib/util/iov_buf.h"
+
+/****************************************************************************
+ Write all data from an iov array
+ NB. This can be called with a non-socket fd, don't add dependencies
+ on socket calls.
+****************************************************************************/
+
+ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
+{
+ ssize_t to_send;
+ ssize_t thistime;
+ size_t sent;
+ struct iovec iov_copy[iovcnt];
+ struct iovec *iov;
+
+ to_send = iov_buflen(orig_iov, iovcnt);
+ if (to_send == -1) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ thistime = sys_writev(fd, orig_iov, iovcnt);
+ if ((thistime <= 0) || (thistime == to_send)) {
+ return thistime;
+ }
+ sent = thistime;
+
+ /*
+ * We could not send everything in one call. Make a copy of iov that
+ * we can mess with.
+ */
+
+ memcpy(iov_copy, orig_iov, sizeof(struct iovec) * iovcnt);
+ iov = iov_copy;
+
+ while (sent < (size_t)to_send) {
+ bool ok;
+
+ ok = iov_advance(&iov, &iovcnt, thistime);
+ if (!ok) {
+ errno = EIO;
+ return -1;
+ }
+
+ thistime = sys_writev(fd, iov, iovcnt);
+ if (thistime <= 0) {
+ break;
+ }
+ sent += thistime;
+ }
+
+ return sent;
+}
+
+/****************************************************************************
+ Write data to a fd.
+ NB. This can be called with a non-socket fd, don't add dependencies
+ on socket calls.
+****************************************************************************/
+
+ssize_t write_data(int fd, const void *buffer, size_t n)
+{
+ struct iovec iov;
+
+ iov.iov_base = discard_const_p(void, buffer);
+ iov.iov_len = n;
+ return write_data_iov(fd, &iov, 1);
+}
+
+/*
+ * Blocking read n bytes from a fd
+ */
+
+ssize_t read_data(int fd, void *buffer, size_t n)
+{
+ ssize_t nread;
+
+ nread = 0;
+
+ while ((size_t)nread < n) {
+ ssize_t ret;
+ ret = sys_read(fd, ((char *)buffer) + nread, n - nread);
+ if (ret <= 0) {
+ return ret;
+ }
+ nread += ret;
+ }
+
+ return nread;
+}
diff --git a/lib/util/sys_rw_data.h b/lib/util/sys_rw_data.h
new file mode 100644
index 0000000..bda3795
--- /dev/null
+++ b/lib/util/sys_rw_data.h
@@ -0,0 +1,34 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba system utilities
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Copyright (C) Jeremy Allison 1998-2005
+ * Copyright (C) Timur Bakeyev 2005
+ * Copyright (C) Bjoern Jacke 2006-2007
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIB_SYS_RW_DATA_H__
+#define __LIB_SYS_RW_DATA_H__
+
+#include <unistd.h>
+
+struct iovec;
+
+ssize_t write_data_iov(int fd, const struct iovec *iov, int iovcnt);
+ssize_t write_data(int fd, const void *buffer, size_t n);
+ssize_t read_data(int fd, void *buffer, size_t n);
+
+#endif
diff --git a/lib/util/system.c b/lib/util/system.c
new file mode 100644
index 0000000..558aa5b
--- /dev/null
+++ b/lib/util/system.c
@@ -0,0 +1,65 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba system utilities
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 1998-2002
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "system/network.h"
+#include "system/filesys.h"
+
+#undef malloc
+
+/*
+ The idea is that this file will eventually have wrappers around all
+ important system calls in samba. The aims are:
+
+ - to enable easier porting by putting OS dependent stuff in here
+
+ - to allow for hooks into other "pseudo-filesystems"
+
+ - to allow easier integration of things like the japanese extensions
+
+ - to support the philosophy of Samba to expose the features of
+ the OS within the SMB model. In general whatever file/printer/variable
+ expansions/etc make sense to the OS should be acceptable to Samba.
+*/
+
+
+_PUBLIC_ int sys_getnameinfo(const struct sockaddr *psa,
+ int salen,
+ char *host,
+ size_t hostlen,
+ char *service,
+ size_t servlen,
+ int flags)
+{
+ /*
+ * For Solaris we must make sure salen is the
+ * correct length for the incoming sa_family.
+ */
+
+ if (salen == sizeof(struct sockaddr_storage)) {
+ salen = sizeof(struct sockaddr_in);
+#if defined(HAVE_IPV6)
+ if (psa->sa_family == AF_INET6) {
+ salen = sizeof(struct sockaddr_in6);
+ }
+#endif
+ }
+ return getnameinfo(psa, salen, host, hostlen, service, servlen, flags);
+}
diff --git a/lib/util/talloc_keep_secret.c b/lib/util/talloc_keep_secret.c
new file mode 100644
index 0000000..2104865
--- /dev/null
+++ b/lib/util/talloc_keep_secret.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019 Andreas Schneider <asn@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include <talloc.h>
+#include "lib/util/fault.h"
+#include "talloc_keep_secret.h"
+
+static int talloc_keep_secret_destructor(void *ptr)
+{
+ int ret;
+ size_t size = talloc_get_size(ptr);
+
+ if (unlikely(size == 0)) {
+ return 0;
+ }
+
+ ret = memset_s(ptr, size, 0, size);
+ if (unlikely(ret != 0)) {
+ char *msg = NULL;
+ int ret2;
+ ret2 = asprintf(&msg,
+ "talloc_keep_secret_destructor: memset_s() failed: %s",
+ strerror(ret));
+ if (ret2 != -1) {
+ smb_panic(msg);
+ } else {
+ smb_panic("talloc_keep_secret_destructor: memset_s() failed");
+ }
+ }
+
+ return 0;
+}
+
+void _talloc_keep_secret(void *ptr, const char *name)
+{
+ size_t size;
+
+ if (unlikely(ptr == NULL)) {
+#ifdef DEVELOPER
+ smb_panic("Invalid talloc pointer");
+#endif
+ return;
+ }
+
+ size = talloc_get_size(ptr);
+ if (unlikely(size == 0)) {
+ return;
+ }
+
+ talloc_set_name_const(ptr, name);
+ talloc_set_destructor(ptr, talloc_keep_secret_destructor);
+}
diff --git a/lib/util/talloc_keep_secret.h b/lib/util/talloc_keep_secret.h
new file mode 100644
index 0000000..44a26ae
--- /dev/null
+++ b/lib/util/talloc_keep_secret.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 Andreas Schneider <asn@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TALLOC_KEEP_SECRET_H
+#define _TALLOC_KEEP_SECRET_H
+
+#ifdef DOXYGEN
+/**
+ * @brief Keep the memory secret when freeing.
+ *
+ * This can be used to define memory as secret. For example memory which holds
+ * passwords or other secrets like session keys. The memory will be zeroed
+ * before is being freed.
+ *
+ * If you duplicate memory, e.g. using talloc_strdup() or talloc_asprintf() you
+ * need to call talloc_keep_secret() on the newly allocated memory too!
+ *
+ * @param[in] ptr The talloc chunk to mark as secure.
+ *
+ * @warning Do not use this in combination with talloc_realloc().
+ */
+void talloc_keep_secret(const void *ptr);
+#else
+#define talloc_keep_secret(ptr) _talloc_keep_secret(ptr, #ptr);
+void _talloc_keep_secret(void *ptr, const char *name);
+#endif
+
+#endif /* _TALLOC_KEEP_SECRET_H */
diff --git a/lib/util/talloc_report.c b/lib/util/talloc_report.c
new file mode 100644
index 0000000..0aec966
--- /dev/null
+++ b/lib/util/talloc_report.c
@@ -0,0 +1,184 @@
+/*
+ * talloc_report into a string
+ *
+ * Copyright Volker Lendecke <vl@samba.org> 2015
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "talloc_report.h"
+
+/*
+ * talloc_vasprintf into a buffer that doubles its size. The real string
+ * length is maintained in "pstr_len".
+ */
+
+static char *talloc_vasprintf_append_largebuf(char *buf, ssize_t *pstr_len,
+ const char *fmt, va_list ap)
+ PRINTF_ATTRIBUTE(3,0);
+
+static char *talloc_vasprintf_append_largebuf(char *buf, ssize_t *pstr_len,
+ const char *fmt, va_list ap)
+{
+ ssize_t str_len = *pstr_len;
+ size_t buflen, needed, space = 0;
+ char *start = NULL, *tmpbuf = NULL;
+ va_list ap2;
+ int printlen;
+
+ if (str_len == -1) {
+ return NULL;
+ }
+ if (buf == NULL) {
+ return NULL;
+ }
+ if (fmt == NULL) {
+ return NULL;
+ }
+ buflen = talloc_get_size(buf);
+
+ if (buflen > (size_t)str_len) {
+ start = buf + str_len;
+ space = buflen - str_len;
+ } else {
+ return NULL;
+ }
+
+ va_copy(ap2, ap);
+ printlen = vsnprintf(start, space, fmt, ap2);
+ va_end(ap2);
+
+ if (printlen < 0) {
+ goto fail;
+ }
+
+ needed = str_len + printlen + 1;
+
+ if (needed > buflen) {
+ buflen = MAX(128, buflen);
+
+ while (buflen < needed) {
+ buflen *= 2;
+ }
+
+ tmpbuf = talloc_realloc(NULL, buf, char, buflen);
+ if (tmpbuf == NULL) {
+ goto fail;
+ }
+ buf = tmpbuf;
+
+ va_copy(ap2, ap);
+ vsnprintf(buf + str_len, buflen - str_len, fmt, ap2);
+ va_end(ap2);
+ }
+ *pstr_len = (needed - 1);
+ return buf;
+fail:
+ *pstr_len = -1;
+ return buf;
+}
+
+static char *talloc_asprintf_append_largebuf(char *buf, ssize_t *pstr_len,
+ const char *fmt, ...)
+ PRINTF_ATTRIBUTE(3,4);
+
+static char *talloc_asprintf_append_largebuf(char *buf, ssize_t *pstr_len,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ buf = talloc_vasprintf_append_largebuf(buf, pstr_len, fmt, ap);
+ va_end(ap);
+ return buf;
+}
+
+struct talloc_report_str_state {
+ ssize_t str_len;
+ char *s;
+};
+
+static void talloc_report_str_helper(const void *ptr, int depth, int max_depth,
+ int is_ref, void *private_data)
+{
+ struct talloc_report_str_state *state = private_data;
+ const char *name = talloc_get_name(ptr);
+
+ if (ptr == state->s) {
+ return;
+ }
+
+ if (is_ref) {
+ state->s = talloc_asprintf_append_largebuf(
+ state->s, &state->str_len,
+ "%*sreference to: %s\n", depth*4, "", name);
+ return;
+ }
+
+ if (depth == 0) {
+ state->s = talloc_asprintf_append_largebuf(
+ state->s, &state->str_len,
+ "%stalloc report on '%s' "
+ "(total %6lu bytes in %3lu blocks)\n",
+ (max_depth < 0 ? "full " :""), name,
+ (unsigned long)talloc_total_size(ptr),
+ (unsigned long)talloc_total_blocks(ptr));
+ return;
+ }
+
+ if (strcmp(name, "char") == 0) {
+ /*
+ * Print out the first 50 bytes of the string
+ */
+ state->s = talloc_asprintf_append_largebuf(
+ state->s, &state->str_len,
+ "%*s%-30s contains %6lu bytes in %3lu blocks "
+ "(ref %zu): %*s\n", depth*4, "", name,
+ (unsigned long)talloc_total_size(ptr),
+ (unsigned long)talloc_total_blocks(ptr),
+ talloc_reference_count(ptr),
+ (int)MIN(50, talloc_get_size(ptr)),
+ (const char *)ptr);
+ return;
+ }
+
+ state->s = talloc_asprintf_append_largebuf(
+ state->s, &state->str_len,
+ "%*s%-30s contains %6lu bytes in %3lu blocks (ref %zu) %p\n",
+ depth*4, "", name,
+ (unsigned long)talloc_total_size(ptr),
+ (unsigned long)talloc_total_blocks(ptr),
+ talloc_reference_count(ptr), ptr);
+}
+
+char *talloc_report_str(TALLOC_CTX *mem_ctx, TALLOC_CTX *root)
+{
+ struct talloc_report_str_state state;
+
+ state.s = talloc_strdup(mem_ctx, "");
+ if (state.s == NULL) {
+ return NULL;
+ }
+ state.str_len = 0;
+
+ talloc_report_depth_cb(root, 0, -1, talloc_report_str_helper, &state);
+
+ if (state.str_len == -1) {
+ talloc_free(state.s);
+ return NULL;
+ }
+
+ return talloc_realloc(mem_ctx, state.s, char, state.str_len+1);
+}
diff --git a/lib/util/talloc_report.h b/lib/util/talloc_report.h
new file mode 100644
index 0000000..53d0385
--- /dev/null
+++ b/lib/util/talloc_report.h
@@ -0,0 +1,27 @@
+/*
+ * talloc_report into a string
+ *
+ * Copyright Volker Lendecke <vl@samba.org> 2015
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TALLOC_REPORT_H_
+#define _TALLOC_REPORT_H_
+
+#include <talloc.h>
+
+char *talloc_report_str(TALLOC_CTX *mem_ctx, TALLOC_CTX *root);
+
+#endif
diff --git a/lib/util/talloc_report_printf.c b/lib/util/talloc_report_printf.c
new file mode 100644
index 0000000..3011c62
--- /dev/null
+++ b/lib/util/talloc_report_printf.c
@@ -0,0 +1,134 @@
+/*
+ * talloc_report into a FILE
+ *
+ * Copyright Volker Lendecke <vl@samba.org> 2015
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "talloc_report_printf.h"
+
+static void talloc_report_printf_helper(
+ const void *ptr,
+ int depth,
+ int max_depth,
+ int is_ref,
+ void *private_data)
+{
+ FILE *f = private_data;
+ const char *name = talloc_get_name(ptr);
+
+ if (is_ref) {
+ fprintf(f,
+ "%*sreference to: %s\n",
+ depth*4,
+ "",
+ name);
+ return;
+ }
+
+ if (depth == 0) {
+ fprintf(f,
+ "%stalloc report on '%s' "
+ "(total %6zu bytes in %3zu blocks)\n",
+ (max_depth < 0 ? "full " :""), name,
+ talloc_total_size(ptr),
+ talloc_total_blocks(ptr));
+ return;
+ }
+
+ if (strcmp(name, "char") == 0) {
+ /*
+ * Print out the first 50 bytes of the string
+ */
+ fprintf(f,
+ "%*s%-30s contains %6zu bytes in %3zu blocks "
+ "(ref %zu): %*s\n", depth*4, "", name,
+ talloc_total_size(ptr),
+ talloc_total_blocks(ptr),
+ talloc_reference_count(ptr),
+ (int)MIN(50, talloc_get_size(ptr)),
+ (const char *)ptr);
+ return;
+ }
+
+ fprintf(f,
+ "%*s%-30s contains %6zu bytes in %3zu blocks (ref %zu) %p\n",
+ depth*4, "", name,
+ talloc_total_size(ptr),
+ talloc_total_blocks(ptr),
+ talloc_reference_count(ptr),
+ ptr);
+}
+
+void talloc_full_report_printf(TALLOC_CTX *root, FILE *f)
+{
+ talloc_report_depth_cb(root, 0, -1, talloc_report_printf_helper, f);
+#if defined(HAVE_MALLINFO2)
+ {
+ struct mallinfo2 mi2 = mallinfo2();
+
+ fprintf(f,
+ "mallinfo:\n"
+ " arena: %zu\n"
+ " ordblks: %zu\n"
+ " smblks: %zu\n"
+ " hblks: %zu\n"
+ " hblkhd: %zu\n"
+ " usmblks: %zu\n"
+ " fsmblks: %zu\n"
+ " uordblks: %zu\n"
+ " fordblks: %zu\n"
+ " keepcost: %zu\n",
+ mi2.arena,
+ mi2.ordblks,
+ mi2.smblks,
+ mi2.hblks,
+ mi2.hblkhd,
+ mi2.usmblks,
+ mi2.fsmblks,
+ mi2.uordblks,
+ mi2.fordblks,
+ mi2.keepcost);
+ }
+#elif defined(HAVE_MALLINFO)
+ {
+ struct mallinfo mi = mallinfo();
+
+ fprintf(f,
+ "mallinfo:\n"
+ " arena: %d\n"
+ " ordblks: %d\n"
+ " smblks: %d\n"
+ " hblks: %d\n"
+ " hblkhd: %d\n"
+ " usmblks: %d\n"
+ " fsmblks: %d\n"
+ " uordblks: %d\n"
+ " fordblks: %d\n"
+ " keepcost: %d\n",
+ mi.arena,
+ mi.ordblks,
+ mi.smblks,
+ mi.hblks,
+ mi.hblkhd,
+ mi.usmblks,
+ mi.fsmblks,
+ mi.uordblks,
+ mi.fordblks,
+ mi.keepcost);
+ }
+#endif /* HAVE_MALLINFO2 or HAVE_MALLINFO */
+}
diff --git a/lib/util/talloc_report_printf.h b/lib/util/talloc_report_printf.h
new file mode 100644
index 0000000..7881e65
--- /dev/null
+++ b/lib/util/talloc_report_printf.h
@@ -0,0 +1,29 @@
+/*
+ * talloc_report into a FILE
+ *
+ * Copyright Volker Lendecke <vl@samba.org> 2019
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TALLOC_REPORT_PRINTF_H_
+#define _TALLOC_REPORT_PRINTF_H_
+
+#include "replace.h"
+#include "system/filesys.h"
+#include <talloc.h>
+
+void talloc_full_report_printf(TALLOC_CTX *root, FILE *f);
+
+#endif
diff --git a/lib/util/talloc_stack.c b/lib/util/talloc_stack.c
new file mode 100644
index 0000000..fdd0a30
--- /dev/null
+++ b/lib/util/talloc_stack.c
@@ -0,0 +1,259 @@
+/*
+ Unix SMB/CIFS implementation.
+ Implement a stack of talloc contexts
+ Copyright (C) Volker Lendecke 2007
+ Copyright (C) Jeremy Allison 2009 - made thread safe.
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * Implement a stack of talloc frames.
+ *
+ * When a new talloc stackframe is allocated with talloc_stackframe(), then
+ * the TALLOC_CTX returned with talloc_tos() is reset to that new
+ * frame. Whenever that stack frame is TALLOC_FREE()'ed, then the reverse
+ * happens: The previous talloc_tos() is restored.
+ *
+ * This API is designed to be robust in the sense that if someone forgets to
+ * TALLOC_FREE() a stackframe, then the next outer one correctly cleans up and
+ * resets the talloc_tos().
+ *
+ * This robustness feature means that we can't rely on a linked list with
+ * talloc destructors because in a hierarchy of talloc destructors the parent
+ * destructor is called before its children destructors. The child destructor
+ * called after the parent would set the talloc_tos() to the wrong value.
+ */
+
+#include "replace.h"
+#include <talloc.h>
+#include "lib/util/talloc_stack.h"
+#include "lib/util/smb_threads.h"
+#include "lib/util/smb_threads_internal.h"
+#include "lib/util/fault.h"
+#include "lib/util/debug.h"
+
+struct talloc_stackframe {
+ int talloc_stacksize;
+ int talloc_stack_arraysize;
+ TALLOC_CTX **talloc_stack;
+};
+
+/*
+ * In the single threaded case this is a pointer
+ * to the global talloc_stackframe. In the MT-case
+ * this is the pointer to the thread-specific key
+ * used to look up the per-thread talloc_stackframe
+ * pointer.
+ */
+
+static void *global_ts;
+
+/* Variable to ensure TLS value is only initialized once. */
+static smb_thread_once_t ts_initialized = SMB_THREAD_ONCE_INIT;
+
+static void talloc_stackframe_init(void * unused)
+{
+ if (SMB_THREAD_CREATE_TLS("talloc_stackframe", global_ts)) {
+ smb_panic("talloc_stackframe_init create_tls failed");
+ }
+}
+
+static struct talloc_stackframe *talloc_stackframe_create(void)
+{
+#if defined(PARANOID_MALLOC_CHECKER)
+#ifdef calloc
+#undef calloc
+#endif
+#endif
+ struct talloc_stackframe *ts = (struct talloc_stackframe *)calloc(
+ 1, sizeof(struct talloc_stackframe));
+#if defined(PARANOID_MALLOC_CHECKER)
+#define calloc(n, s) __ERROR_DONT_USE_MALLOC_DIRECTLY
+#endif
+
+ if (!ts) {
+ smb_panic("talloc_stackframe_init malloc failed");
+ }
+
+ SMB_THREAD_ONCE(&ts_initialized, talloc_stackframe_init, NULL);
+
+ if (SMB_THREAD_SET_TLS(global_ts, ts)) {
+ smb_panic("talloc_stackframe_init set_tls failed");
+ }
+ return ts;
+}
+
+static int talloc_pop(TALLOC_CTX *frame)
+{
+ struct talloc_stackframe *ts =
+ (struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
+ size_t blocks;
+ int i;
+
+ /* Catch lazy frame-freeing. */
+ if (ts->talloc_stack[ts->talloc_stacksize-1] != frame) {
+ DEBUG(0, ("Freed frame %s, expected %s.\n",
+ talloc_get_name(frame),
+ talloc_get_name(ts->talloc_stack
+ [ts->talloc_stacksize-1])));
+#ifdef DEVELOPER
+ smb_panic("Frame not freed in order.");
+#endif
+ }
+
+ for (i=0; i<10; i++) {
+
+ /*
+ * We have to free our children first, calling all
+ * destructors. If a destructor hanging deeply off
+ * "frame" uses talloc_tos() itself while freeing the
+ * toplevel frame, we panic because that nested
+ * talloc_tos() in the destructor does not find a
+ * stackframe anymore.
+ *
+ * Do it in a loop up to 10 times as the destructors
+ * might use more of talloc_tos().
+ */
+
+ talloc_free_children(frame);
+
+ blocks = talloc_total_blocks(frame);
+ if (blocks == 1) {
+ break;
+ }
+ }
+
+ if (blocks != 1) {
+ DBG_WARNING("Left %zu blocks after %i "
+ "talloc_free_children(frame) calls\n",
+ blocks, i);
+ }
+
+ for (i=ts->talloc_stacksize-1; i>0; i--) {
+ if (frame == ts->talloc_stack[i]) {
+ break;
+ }
+ TALLOC_FREE(ts->talloc_stack[i]);
+ }
+
+ ts->talloc_stack[i] = NULL;
+ ts->talloc_stacksize = i;
+ return 0;
+}
+
+/*
+ * Create a new talloc stack frame.
+ *
+ * When free'd, it frees all stack frames that were created after this one and
+ * not explicitly freed.
+ */
+
+static TALLOC_CTX *talloc_stackframe_internal(const char *location,
+ size_t poolsize)
+{
+ TALLOC_CTX **tmp, *top;
+ struct talloc_stackframe *ts =
+ (struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
+
+ if (ts == NULL) {
+ ts = talloc_stackframe_create();
+ }
+
+ if (ts->talloc_stack_arraysize < ts->talloc_stacksize + 1) {
+ tmp = talloc_realloc(NULL, ts->talloc_stack, TALLOC_CTX *,
+ ts->talloc_stacksize + 1);
+ if (tmp == NULL) {
+ goto fail;
+ }
+ ts->talloc_stack = tmp;
+ ts->talloc_stack_arraysize = ts->talloc_stacksize + 1;
+ }
+
+ if (poolsize) {
+ top = talloc_pool(ts->talloc_stack, poolsize);
+ } else {
+ TALLOC_CTX *parent;
+ /* We chain parentage, so if one is a pool we draw from it. */
+ if (ts->talloc_stacksize == 0) {
+ parent = ts->talloc_stack;
+ } else {
+ parent = ts->talloc_stack[ts->talloc_stacksize-1];
+ }
+ top = talloc_new(parent);
+ }
+
+ if (top == NULL) {
+ goto fail;
+ }
+ talloc_set_name_const(top, location);
+ talloc_set_destructor(top, talloc_pop);
+
+ ts->talloc_stack[ts->talloc_stacksize++] = top;
+ return top;
+
+ fail:
+ smb_panic("talloc_stackframe failed");
+ return NULL;
+}
+
+TALLOC_CTX *_talloc_stackframe(const char *location)
+{
+ return talloc_stackframe_internal(location, 0);
+}
+
+TALLOC_CTX *_talloc_stackframe_pool(const char *location, size_t poolsize)
+{
+ return talloc_stackframe_internal(location, poolsize);
+}
+
+/*
+ * Get us the current top of the talloc stack.
+ */
+
+TALLOC_CTX *_talloc_tos(const char *location)
+{
+ struct talloc_stackframe *ts =
+ (struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
+
+ if (ts == NULL || ts->talloc_stacksize == 0) {
+ _talloc_stackframe(location);
+ ts = (struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
+ DEBUG(0, ("no talloc stackframe at %s, leaking memory\n",
+ location));
+#ifdef DEVELOPER
+ smb_panic("No talloc stackframe");
+#endif
+ }
+
+ return ts->talloc_stack[ts->talloc_stacksize-1];
+}
+
+/*
+ * return true if a talloc stackframe exists
+ * this can be used to prevent memory leaks for code that can
+ * optionally use a talloc stackframe (eg. nt_errstr())
+ */
+
+bool talloc_stackframe_exists(void)
+{
+ struct talloc_stackframe *ts =
+ (struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
+
+ if (ts == NULL || ts->talloc_stacksize == 0) {
+ return false;
+ }
+ return true;
+}
diff --git a/lib/util/talloc_stack.h b/lib/util/talloc_stack.h
new file mode 100644
index 0000000..fceb41f
--- /dev/null
+++ b/lib/util/talloc_stack.h
@@ -0,0 +1,66 @@
+/*
+ Unix SMB/CIFS implementation.
+ Implement a stack of talloc contexts
+ Copyright (C) Volker Lendecke 2007
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Implement a stack of talloc frames.
+ *
+ * When a new talloc stackframe is allocated with talloc_stackframe(), then
+ * the TALLOC_CTX returned with talloc_tos() is reset to that new
+ * frame. Whenever that stack frame is TALLOC_FREE()'ed, then the reverse
+ * happens: The previous talloc_tos() is restored.
+ *
+ * This API is designed to be robust in the sense that if someone forgets to
+ * TALLOC_FREE() a stackframe, then the next outer one correctly cleans up and
+ * resets the talloc_tos().
+ *
+ */
+
+#ifndef _TALLOC_STACK_H
+#define _TALLOC_STACK_H
+
+#include <talloc.h>
+
+/*
+ * Create a new talloc stack frame.
+ *
+ * When free'd, it frees all stack frames that were created after this one and
+ * not explicitly freed.
+ */
+
+#define talloc_stackframe() _talloc_stackframe(__location__)
+#define talloc_stackframe_pool(sz) _talloc_stackframe_pool(__location__, (sz))
+TALLOC_CTX *_talloc_stackframe(const char *location);
+TALLOC_CTX *_talloc_stackframe_pool(const char *location, size_t poolsize);
+
+/*
+ * Get us the current top of the talloc stack.
+ */
+
+#define talloc_tos() _talloc_tos(__location__)
+TALLOC_CTX *_talloc_tos(const char *location);
+
+/*
+ * return true if a talloc stackframe exists
+ * this can be used to prevent memory leaks for code that can
+ * optionally use a talloc stackframe (eg. nt_errstr())
+ */
+
+bool talloc_stackframe_exists(void);
+
+#endif
diff --git a/lib/util/tests/README b/lib/util/tests/README
new file mode 100644
index 0000000..c1337d5
--- /dev/null
+++ b/lib/util/tests/README
@@ -0,0 +1,22 @@
+tfork tests
+===========
+
+To run the tfork torture testsuite under valgrind with the helgrind or drd
+thread checkers, run valgrind with the --suppress option passing a suppressions
+file.
+
+For helgrind:
+
+$ valgrind \
+ --trace-children=yes \
+ --tool=helgrind \
+ --suppressions=lib/util/tests/tfork-helgrind.supp \
+ ./bin/smbtorture ncalrpc:localhost local.tfork.tfork_threads
+
+For drd:
+
+$ valgrind \
+ --trace-children=yes \
+ --tool=drd \
+ --suppressions=lib/util/tests/tfork-drd.supp \
+ ./bin/smbtorture ncalrpc:localhost local.tfork.tfork_threads
diff --git a/lib/util/tests/anonymous_shared.c b/lib/util/tests/anonymous_shared.c
new file mode 100644
index 0000000..512a53f
--- /dev/null
+++ b/lib/util/tests/anonymous_shared.c
@@ -0,0 +1,70 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ anonymous_shared testing
+
+ Copyright (C) Stefan Metzmacher 2011
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+
+static bool test_anonymous_shared_simple(struct torture_context *tctx)
+{
+ void *ptr;
+ size_t len;
+
+ torture_comment(tctx, "anonymous_shared_free(NULL)\n");
+ anonymous_shared_free(NULL);
+
+ len = 500;
+ torture_comment(tctx, "anonymous_shared_allocate(%llu)\n",
+ (unsigned long long)len);
+ ptr = anonymous_shared_allocate(len);
+ torture_assert(tctx, ptr, "valid pointer");
+ memset(ptr, 0xfe, len);
+ torture_comment(tctx, "anonymous_shared_free(ptr)\n");
+ anonymous_shared_free(ptr);
+
+ len = 50000;
+ torture_comment(tctx, "anonymous_shared_allocate(%llu)\n",
+ (unsigned long long)len);
+ ptr = anonymous_shared_allocate(len);
+ torture_assert(tctx, ptr, "valid pointer");
+ memset(ptr, 0xfe, len);
+ torture_comment(tctx, "anonymous_shared_free(ptr)\n");
+ anonymous_shared_free(ptr);
+
+ memset(&len, 0xFF, sizeof(len));
+ torture_comment(tctx, "anonymous_shared_allocate(%llu)\n",
+ (unsigned long long)len);
+ ptr = anonymous_shared_allocate(len);
+ torture_assert(tctx, ptr == NULL, "null pointer");
+
+ return true;
+}
+
+/* local.anonymous_shared test suite creation */
+struct torture_suite *torture_local_util_anonymous_shared(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "anonymous_shared");
+
+ torture_suite_add_simple_test(suite, "simple",
+ test_anonymous_shared_simple);
+
+ return suite;
+}
diff --git a/lib/util/tests/asn1_tests.c b/lib/util/tests/asn1_tests.c
new file mode 100644
index 0000000..f2bd163
--- /dev/null
+++ b/lib/util/tests/asn1_tests.c
@@ -0,0 +1,383 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ util_asn1 testing
+
+ Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 2009
+ Copyright (C) Volker Lendecke 2004
+ Copyright (C) Andrew Bartlett 2011
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+#include "../asn1.h"
+
+struct oid_data {
+ const char *oid; /* String OID */
+ const char *bin_oid; /* Binary OID represented as string */
+};
+
+/* Data for successful OIDs conversions */
+static const struct oid_data oid_data_ok[] = {
+ {
+ .oid = "2.5.4.0",
+ .bin_oid = "550400"
+ },
+ {
+ .oid = "2.5.4.1",
+ .bin_oid = "550401"
+ },
+ {
+ .oid = "2.5.4.130",
+ .bin_oid = "55048102"
+ },
+ {
+ .oid = "2.5.130.4",
+ .bin_oid = "55810204"
+ },
+ {
+ .oid = "2.5.4.16387",
+ .bin_oid = "5504818003"
+ },
+ {
+ .oid = "2.5.16387.4",
+ .bin_oid = "5581800304"
+ },
+ {
+ .oid = "2.5.2097155.4",
+ .bin_oid = "558180800304"
+ },
+ {
+ .oid = "2.5.4.130.16387.2097155.268435459",
+ .bin_oid = "55048102818003818080038180808003"
+ },
+};
+
+/* Data for successful OIDs conversions */
+static const char *oid_data_err[] = {
+ "", /* empty OID */
+ ".2.5.4.130", /* first sub-identifier is empty */
+ "2.5.4.130.", /* last sub-identifier is empty */
+ "2..5.4.130", /* second sub-identifier is empty */
+ "2.5..4.130", /* third sub-identifier is empty */
+ "2.abc.4.130", /* invalid sub-identifier */
+ "2.5abc.4.130", /* invalid sub-identifier (alphanumeric)*/
+};
+
+/* Data for successful Partial OIDs conversions */
+static const struct oid_data partial_oid_data_ok[] = {
+ {
+ .oid = "2.5.4.130:0x81",
+ .bin_oid = "5504810281"
+ },
+ {
+ .oid = "2.5.4.16387:0x8180",
+ .bin_oid = "55048180038180"
+ },
+ {
+ .oid = "2.5.4.16387:0x81",
+ .bin_oid = "550481800381"
+ },
+ {
+ .oid = "2.5.2097155.4:0x818080",
+ .bin_oid = "558180800304818080"
+ },
+ {
+ .oid = "2.5.2097155.4:0x8180",
+ .bin_oid = "5581808003048180"
+ },
+ {
+ .oid = "2.5.2097155.4:0x81",
+ .bin_oid = "55818080030481"
+ },
+};
+
+static const struct {
+ DATA_BLOB blob;
+ int value;
+} integer_tests[] = {
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x01\x00"), 3},
+ .value = 0
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x01\x7f"), 3},
+ .value = 127
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x02\x00\x80"), 4},
+ .value = 128
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x02\x01\x00"), 4},
+ .value = 256
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x01\x80"), 3},
+ .value = -128
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x02\xff\x7f"), 4},
+ .value = -129
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x01\xff"), 3},
+ .value = -1
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x02\xff\x01"), 4},
+ .value = -255
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x02\x00\xff"), 4},
+ .value = 255
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x04\x80\x00\x00\x00"), 6},
+ .value = 0x80000000
+ },
+ {
+ .blob = { discard_const_p(uint8_t, "\x02\x04\x7f\xff\xff\xff"), 6},
+ .value = 0x7fffffff
+ }
+};
+
+/* Testing ber_write_OID_String() function */
+static bool test_ber_write_OID_String(struct torture_context *tctx)
+{
+ int i;
+ char *hex_str;
+ DATA_BLOB blob;
+ TALLOC_CTX *mem_ctx;
+ const struct oid_data *data = oid_data_ok;
+
+ mem_ctx = talloc_new(tctx);
+
+ /* check for valid OIDs */
+ for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
+ torture_assert(tctx, ber_write_OID_String(mem_ctx, &blob, data[i].oid),
+ "ber_write_OID_String failed");
+
+ hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
+ torture_assert(tctx, hex_str, "No memory!");
+
+ torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
+ talloc_asprintf(mem_ctx,
+ "Failed: oid=%s, bin_oid:%s",
+ data[i].oid, data[i].bin_oid));
+ }
+
+ /* check for invalid OIDs */
+ for (i = 0; i < ARRAY_SIZE(oid_data_err); i++) {
+ torture_assert(tctx,
+ !ber_write_OID_String(mem_ctx, &blob, oid_data_err[i]),
+ talloc_asprintf(mem_ctx,
+ "Should fail for [%s] -> %s",
+ oid_data_err[i],
+ hex_encode_talloc(mem_ctx, blob.data, blob.length)));
+ }
+
+ talloc_free(mem_ctx);
+
+ return true;
+}
+
+/* Testing ber_read_OID_String() function */
+static bool test_ber_read_OID_String(struct torture_context *tctx)
+{
+ int i;
+ char *oid;
+ DATA_BLOB oid_blob;
+ TALLOC_CTX *mem_ctx;
+ const struct oid_data *data = oid_data_ok;
+
+ mem_ctx = talloc_new(tctx);
+
+ for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
+ oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
+
+ torture_assert(tctx, ber_read_OID_String(mem_ctx, oid_blob, &oid),
+ "ber_read_OID_String failed");
+
+ torture_assert(tctx, strequal(data[i].oid, oid),
+ talloc_asprintf(mem_ctx,
+ "Failed: oid=%s, bin_oid:%s",
+ data[i].oid, data[i].bin_oid));
+ }
+
+ talloc_free(mem_ctx);
+
+ return true;
+}
+
+/* Testing ber_write_partial_OID_String() function */
+static bool test_ber_write_partial_OID_String(struct torture_context *tctx)
+{
+ int i;
+ char *hex_str;
+ DATA_BLOB blob;
+ TALLOC_CTX *mem_ctx;
+ const struct oid_data *data = oid_data_ok;
+
+ mem_ctx = talloc_new(tctx);
+
+ /* ber_write_partial_OID_String() should work with not partial OIDs also */
+ for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
+ torture_assert(tctx, ber_write_partial_OID_String(mem_ctx, &blob, data[i].oid),
+ "ber_write_partial_OID_String failed");
+
+ hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
+ torture_assert(tctx, hex_str, "No memory!");
+
+ torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
+ talloc_asprintf(mem_ctx,
+ "Failed: oid=%s, bin_oid:%s",
+ data[i].oid, data[i].bin_oid));
+ }
+
+ /* ber_write_partial_OID_String() test with partial OIDs */
+ data = partial_oid_data_ok;
+ for (i = 0; i < ARRAY_SIZE(partial_oid_data_ok); i++) {
+ torture_assert(tctx, ber_write_partial_OID_String(mem_ctx, &blob, data[i].oid),
+ "ber_write_partial_OID_String failed");
+
+ hex_str = hex_encode_talloc(mem_ctx, blob.data, blob.length);
+ torture_assert(tctx, hex_str, "No memory!");
+
+ torture_assert(tctx, strequal(data[i].bin_oid, hex_str),
+ talloc_asprintf(mem_ctx,
+ "Failed: oid=%s, bin_oid:%s",
+ data[i].oid, data[i].bin_oid));
+ }
+
+ talloc_free(mem_ctx);
+
+ return true;
+}
+
+/* Testing ber_read_partial_OID_String() function */
+static bool test_ber_read_partial_OID_String(struct torture_context *tctx)
+{
+ int i;
+ char *oid;
+ DATA_BLOB oid_blob;
+ TALLOC_CTX *mem_ctx;
+ const struct oid_data *data = oid_data_ok;
+
+ mem_ctx = talloc_new(tctx);
+
+ /* ber_read_partial_OID_String() should work with not partial OIDs also */
+ for (i = 0; i < ARRAY_SIZE(oid_data_ok); i++) {
+ oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
+
+ torture_assert(tctx, ber_read_partial_OID_String(mem_ctx, oid_blob, &oid),
+ "ber_read_partial_OID_String failed");
+
+ torture_assert(tctx, strequal(data[i].oid, oid),
+ talloc_asprintf(mem_ctx,
+ "Failed: oid=%s, bin_oid:%s",
+ data[i].oid, data[i].bin_oid));
+ }
+
+ /* ber_read_partial_OID_String() test with partial OIDs */
+ data = partial_oid_data_ok;
+ for (i = 0; i < ARRAY_SIZE(partial_oid_data_ok); i++) {
+ oid_blob = strhex_to_data_blob(mem_ctx, data[i].bin_oid);
+
+ torture_assert(tctx, ber_read_partial_OID_String(mem_ctx, oid_blob, &oid),
+ "ber_read_partial_OID_String failed");
+
+ torture_assert(tctx, strequal(data[i].oid, oid),
+ talloc_asprintf(mem_ctx,
+ "Failed: oid=%s, bin_oid:%s",
+ data[i].oid, data[i].bin_oid));
+ }
+
+ talloc_free(mem_ctx);
+
+ return true;
+}
+
+/*
+ * Testing asn1_read_Integer and asn1_write_Integer functions,
+ * inspired by Love Hornquist Astrand
+ */
+
+static bool test_asn1_Integer(struct torture_context *tctx)
+{
+ int i;
+ TALLOC_CTX *mem_ctx;
+ bool ret = false;
+
+ mem_ctx = talloc_new(tctx);
+
+ for (i = 0; i < ARRAY_SIZE(integer_tests); i++) {
+ ASN1_DATA *data;
+ DATA_BLOB blob;
+ int val;
+
+ data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
+ if (!data) {
+ goto err;
+ }
+
+ if (!asn1_write_Integer(data, integer_tests[i].value)) goto err;
+
+ if (!asn1_blob(data, &blob)) {
+ goto err;
+ }
+
+ torture_assert_data_blob_equal(tctx, blob, integer_tests[i].blob, "asn1_write_Integer gave incorrect result");
+
+ if (!asn1_load(data, blob)) goto err;
+ torture_assert(tctx, asn1_read_Integer(data, &val), "asn1_write_Integer output could not be read by asn1_read_Integer()");
+
+ torture_assert_int_equal(tctx, val, integer_tests[i].value,
+ "readback of asn1_write_Integer output by asn1_read_Integer() failed");
+ }
+
+ ret = true;
+
+ err:
+
+ talloc_free(mem_ctx);
+ return ret;
+}
+
+
+/* LOCAL-ASN1 test suite creation */
+struct torture_suite *torture_local_util_asn1(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "asn1");
+
+ torture_suite_add_simple_test(suite, "ber_write_OID_String",
+ test_ber_write_OID_String);
+
+ torture_suite_add_simple_test(suite, "ber_read_OID_String",
+ test_ber_read_OID_String);
+
+ torture_suite_add_simple_test(suite, "ber_write_partial_OID_String",
+ test_ber_write_partial_OID_String);
+
+ torture_suite_add_simple_test(suite, "ber_read_partial_OID_String",
+ test_ber_read_partial_OID_String);
+
+ torture_suite_add_simple_test(suite, "asn1_Integer",
+ test_asn1_Integer);
+
+ return suite;
+}
diff --git a/lib/util/tests/binsearch.c b/lib/util/tests/binsearch.c
new file mode 100644
index 0000000..b3ecda1
--- /dev/null
+++ b/lib/util/tests/binsearch.c
@@ -0,0 +1,173 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Tests for binsearch.h macros.
+
+ Copyright Catalyst IT 2016.
+
+ Written by Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "lib/util/binsearch.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+
+static int int_cmp(int a, int b)
+{
+ return a - b;
+}
+
+static int int_cmp_p(int a, int *b)
+{
+ return a - *b;
+}
+
+static bool test_binsearch_v(struct torture_context *tctx)
+{
+ int array[] = { -11, -7, 0, 1, 723, 1000000};
+ int misses[] = { -121, 17, -10, 10, -1, -723, 1000002};
+ int i;
+ int *result = NULL;
+
+ for (i = 0; i < ARRAY_SIZE(misses); i++) {
+ BINARY_ARRAY_SEARCH_V(array, ARRAY_SIZE(array),
+ misses[i], int_cmp, result);
+ torture_comment(tctx, "looking for misses[%d] == %d\n", i, misses[i]);
+ torture_assert(tctx, result == NULL, "failed to miss");
+ }
+
+ for (i = 0; i < ARRAY_SIZE(array); i++) {
+ BINARY_ARRAY_SEARCH_V(array, ARRAY_SIZE(array),
+ array[i], int_cmp, result);
+ torture_comment(tctx, "looking for array[%d] == %d, %p; got %p\n",
+ i, array[i], &array[i], result);
+ torture_assert(tctx, result == &array[i],
+ "failed to find element");
+ }
+ return true;
+}
+
+static bool test_binsearch_gte(struct torture_context *tctx)
+{
+ int array[] = { -11, -7, -7, -7, -1, 0, 0, 1, 723, 723, 723,
+ 724, 724, 10000};
+ size_t a_len = ARRAY_SIZE(array);
+ int targets[] = { -121, -8, -7, -6, 17, -10, 10, -1, 723,
+ 724, 725, 10002, 10000, 0, -11, 1, 11};
+ int i, j, target;
+ int *result = NULL, *next = NULL;
+
+ for (i = 0; i < ARRAY_SIZE(targets); i++) {
+ target = targets[i];
+ torture_comment(tctx, "looking for targets[%d] %d\n",
+ i, target);
+
+ BINARY_ARRAY_SEARCH_GTE(array, a_len, target,
+ int_cmp_p, result, next);
+
+ if (result == NULL) {
+ /* we think there is no exact match */
+ for (j = 0; j < a_len; j++) {
+ if (target == array[j]) {
+ torture_comment(tctx,
+ "failed to find %d\n",
+ targets[i]);
+ torture_fail(tctx,
+ "result is wrongly NULL");
+ }
+ }
+ if (next != NULL) {
+ torture_assert(tctx, (next >= array &&
+ next < array + a_len),
+ "next is out of bounds");
+
+ torture_assert(tctx, *next > target,
+ "next <= target");
+ if (target <= array[0]) {
+ torture_assert(tctx, next == array,
+ "search before start failed");
+ }
+ if (next != array) {
+ torture_assert(tctx, next[-1] < target,
+ "next[-1] >= target");
+ }
+ }
+ else {
+ torture_assert(tctx, array[a_len - 1] < target,
+ "next was not found\n");
+ }
+ } else {
+ /* we think we found an exact match */
+ torture_assert(tctx, *result == target,
+ "result has wrong value");
+
+ torture_assert(tctx, (result >= array &&
+ result < array + a_len),
+ "result is out of bounds!");
+
+ torture_assert(tctx, next == NULL,
+ "next should be NULL on exact match\n");
+ if (result != array) {
+ torture_assert(tctx, result[-1] != target,
+ "didn't find first target\n");
+ }
+ }
+ if (target >= array[a_len - 1]) {
+ torture_assert(tctx, next == NULL,
+ "next is not NULL at array end\n");
+ }
+ }
+
+ /* try again, with result and next the same pointer */
+ for (i = 0; i < ARRAY_SIZE(targets); i++) {
+ target = targets[i];
+ torture_comment(tctx, "looking for targets[%d] %d\n",
+ i, target);
+
+ BINARY_ARRAY_SEARCH_GTE(array, a_len, target,
+ int_cmp_p, result, result);
+
+ if (result == NULL) {
+ /* we think the target is greater than all elements */
+ torture_assert(tctx, array[a_len - 1] < target,
+ "element >= target not found\n");
+ } else {
+ /* we think an element is >= target */
+ torture_assert(tctx, *result >= target,
+ "result has wrong value");
+
+ torture_assert(tctx, (result >= array &&
+ result < array + a_len),
+ "result is out of bounds!");
+
+ if (result != array) {
+ torture_assert(tctx, result[-1] < target,
+ "didn't find first target\n");
+ }
+ }
+ }
+
+ return true;
+}
+
+struct torture_suite *torture_local_util_binsearch(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "binsearch");
+ torture_suite_add_simple_test(suite, "binsearch_v", test_binsearch_v);
+ torture_suite_add_simple_test(suite, "binsearch_gte", test_binsearch_gte);
+ return suite;
+}
diff --git a/lib/util/tests/data_blob.c b/lib/util/tests/data_blob.c
new file mode 100644
index 0000000..e1e8129
--- /dev/null
+++ b/lib/util/tests/data_blob.c
@@ -0,0 +1,172 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ data blob testing
+
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+
+static bool test_string(struct torture_context *tctx)
+{
+ DATA_BLOB blob = data_blob_string_const("bla");
+
+ torture_assert_int_equal(tctx, blob.length, 3, "blob length");
+ torture_assert_str_equal(tctx, (char *)blob.data, "bla", "blob data");
+
+ return true;
+}
+
+static bool test_string_null(struct torture_context *tctx)
+{
+ DATA_BLOB blob = data_blob_string_const_null("bla");
+
+ torture_assert_int_equal(tctx, blob.length, 4, "blob length");
+ torture_assert_str_equal(tctx, (char *)blob.data, "bla", "blob data");
+
+ return true;
+}
+
+static bool test_zero(struct torture_context *tctx)
+{
+ int i;
+ DATA_BLOB z = data_blob_talloc_zero(tctx, 4);
+ torture_assert_int_equal(tctx, z.length, 4, "length");
+ for (i = 0; i < z.length; i++)
+ torture_assert_int_equal(tctx, z.data[i], 0, "contents");
+ data_blob_free(&z);
+ return true;
+}
+
+
+static bool test_clear(struct torture_context *tctx)
+{
+ int i;
+ DATA_BLOB z = data_blob("lalala", 6);
+ torture_assert_int_equal(tctx, z.length, 6, "length");
+ data_blob_clear(&z);
+ for (i = 0; i < z.length; i++)
+ torture_assert_int_equal(tctx, z.data[i], 0, "contents");
+ data_blob_free(&z);
+ return true;
+}
+
+static bool test_cmp(struct torture_context *tctx)
+{
+ DATA_BLOB a = data_blob_string_const("bla");
+ DATA_BLOB b = data_blob_string_const("blae");
+ torture_assert(tctx, data_blob_cmp(&a, &b) != 0, "cmp different");
+ torture_assert(tctx, data_blob_cmp(&a, &a) == 0, "cmp self");
+ return true;
+}
+
+static bool test_equal_const_time(struct torture_context *tctx)
+{
+ const char *test_string = "foobarfoo";
+
+ DATA_BLOB null = data_blob_const(NULL, 0);
+ DATA_BLOB foobar = data_blob_const(test_string, 6);
+ DATA_BLOB bar = data_blob_const(test_string + 3, 3);
+
+ /* These data blobs both contain 'foo', but at different addresses. */
+ DATA_BLOB foo_same = data_blob_const(test_string, 3);
+ DATA_BLOB foo_other = data_blob_const(test_string + 6, 3);
+
+ /* Test all equality combinations behave as expected. */
+ torture_assert(tctx, data_blob_equal_const_time(&null, &null), "null == null");
+ torture_assert(tctx, !data_blob_equal_const_time(&null, &foobar), "null != 'foobar'");
+ torture_assert(tctx, !data_blob_equal_const_time(&null, &bar), "null != 'bar'");
+ torture_assert(tctx, !data_blob_equal_const_time(&null, &foo_same), "null != 'foo'");
+ torture_assert(tctx, !data_blob_equal_const_time(&null, &foo_other), "null != 'foo'");
+
+ torture_assert(tctx, !data_blob_equal_const_time(&foobar, &null), "'foobar' != null");
+ torture_assert(tctx, data_blob_equal_const_time(&foobar, &foobar), "'foobar' == 'foobar'");
+ torture_assert(tctx, !data_blob_equal_const_time(&foobar, &bar), "'foobar' != 'bar'");
+ torture_assert(tctx, !data_blob_equal_const_time(&foobar, &foo_same), "'foobar' != 'foo'");
+ torture_assert(tctx, !data_blob_equal_const_time(&foobar, &foo_other), "'foobar' != 'foo'");
+
+ torture_assert(tctx, !data_blob_equal_const_time(&foo_same, &null), "'foo' != null");
+ torture_assert(tctx, !data_blob_equal_const_time(&foo_same, &foobar), "'foo' != 'foobar'");
+ torture_assert(tctx, !data_blob_equal_const_time(&foo_same, &bar), "'foo' != 'bar'");
+ torture_assert(tctx, data_blob_equal_const_time(&foo_same, &foo_same), "'foo' == 'foo'");
+ torture_assert(tctx, data_blob_equal_const_time(&foo_same, &foo_other), "'foo' == 'foo'");
+
+ torture_assert(tctx, !data_blob_equal_const_time(&foo_other, &null), "'foo' != null");
+ torture_assert(tctx, !data_blob_equal_const_time(&foo_other, &foobar), "'foo' != 'foobar'");
+ torture_assert(tctx, !data_blob_equal_const_time(&foo_other, &bar), "'foo' != 'bar'");
+ torture_assert(tctx, data_blob_equal_const_time(&foo_other, &foo_same), "'foo' == 'foo'");
+ torture_assert(tctx, data_blob_equal_const_time(&foo_other, &foo_other), "'foo' == 'foo'");
+
+ torture_assert(tctx, !data_blob_equal_const_time(&bar, &null), "'bar' != null");
+ torture_assert(tctx, !data_blob_equal_const_time(&bar, &foobar), "'bar' != 'foobar'");
+ torture_assert(tctx, data_blob_equal_const_time(&bar, &bar), "'bar' == 'bar'");
+ torture_assert(tctx, !data_blob_equal_const_time(&bar, &foo_same), "'bar' != 'foo'");
+ torture_assert(tctx, !data_blob_equal_const_time(&bar, &foo_other), "'bar' != 'foo'");
+
+ return true;
+}
+
+static bool test_hex_string(struct torture_context *tctx)
+{
+ DATA_BLOB a = data_blob_string_const("\xC\xA\xF\xE");
+ torture_assert_str_equal(tctx, data_blob_hex_string_lower(tctx, &a), "0c0a0f0e", "hex string");
+ torture_assert_str_equal(tctx, data_blob_hex_string_upper(tctx, &a), "0C0A0F0E", "hex string");
+ return true;
+}
+
+static bool test_append_NULL_0(struct torture_context *tctx)
+{
+ DATA_BLOB z = data_blob_talloc_zero(tctx, 0);
+ torture_assert_int_equal(tctx, z.length, 0, "length");
+ torture_assert(tctx, z.data == NULL, "data");
+ torture_assert(tctx, data_blob_append(NULL, &z, NULL, 0), "append NULL,0");
+ torture_assert(tctx, data_blob_append(NULL, &z, "", 0), "append '',0");
+ torture_assert_int_equal(tctx, z.length, 0, "length");
+ torture_assert(tctx, z.data == NULL, "data");
+ return true;
+}
+
+static bool test_append_empty_0(struct torture_context *tctx)
+{
+ DATA_BLOB e = data_blob_talloc(tctx, "", 0);
+ torture_assert_int_equal(tctx, e.length, 0, "length");
+ torture_assert(tctx, e.data != NULL, "data");
+ torture_assert(tctx, data_blob_append(NULL, &e, NULL, 0), "append NULL,0");
+ torture_assert(tctx, data_blob_append(NULL, &e, "", 0), "append '',0");
+ torture_assert_int_equal(tctx, e.length, 0, "length");
+ torture_assert(tctx, e.data != NULL, "data");
+ return true;
+}
+
+struct torture_suite *torture_local_util_data_blob(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "datablob");
+
+ torture_suite_add_simple_test(suite, "string", test_string);
+ torture_suite_add_simple_test(suite, "string_null", test_string_null);
+ torture_suite_add_simple_test(suite, "zero", test_zero);;
+ torture_suite_add_simple_test(suite, "clear", test_clear);
+ torture_suite_add_simple_test(suite, "cmp", test_cmp);
+ torture_suite_add_simple_test(suite, "equal_const_time", test_equal_const_time);
+ torture_suite_add_simple_test(suite, "hex string", test_hex_string);
+ torture_suite_add_simple_test(suite, "append_NULL_0", test_append_NULL_0);
+ torture_suite_add_simple_test(suite, "append_empty_0", test_append_empty_0);
+
+ return suite;
+}
diff --git a/lib/util/tests/dlinklist.c b/lib/util/tests/dlinklist.c
new file mode 100644
index 0000000..50adab3
--- /dev/null
+++ b/lib/util/tests/dlinklist.c
@@ -0,0 +1,131 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ local testing of DLIST_*() macros
+
+ Copyright (C) Andrew Tridgell 2010
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+#include "lib/util/dlinklist.h"
+
+struct listel {
+ struct listel *next, *prev;
+};
+
+static bool torture_local_dlinklist_simple(struct torture_context *tctx)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ struct listel *l1 = NULL, *l2 = NULL, *el, *el2;
+ int i;
+
+ torture_comment(tctx, "add 5 elements at front\n");
+ for (i=0; i<5; i++) {
+ el = talloc(mem_ctx, struct listel);
+ DLIST_ADD(l1, el);
+ }
+
+ torture_comment(tctx, "add 5 elements at end\n");
+ for (i=0; i<5; i++) {
+ el = talloc(mem_ctx, struct listel);
+ DLIST_ADD_END(l1, el);
+ }
+
+ torture_comment(tctx, "delete 3 from front\n");
+ for (i=0; i < 3; i++) {
+ el = l1;
+ DLIST_REMOVE(l1, l1);
+ DLIST_ADD(l2, el);
+ }
+
+ torture_comment(tctx, "delete 3 from back\n");
+ for (i=0; i < 3; i++) {
+ el = DLIST_TAIL(l1);
+ DLIST_REMOVE(l1, el);
+ DLIST_ADD_END(l2, el);
+ }
+
+ torture_comment(tctx, "count forward\n");
+ for (i=0,el=l1; el; el=el->next) i++;
+ torture_assert_int_equal(tctx, i, 4, "should have 4 elements");
+
+ torture_comment(tctx, "count backwards\n");
+ for (i=0,el=DLIST_TAIL(l1); el; el=DLIST_PREV(el)) i++;
+ torture_assert_int_equal(tctx, i, 4, "should have 4 elements");
+
+ torture_comment(tctx, "check DLIST_HEAD\n");
+ el = DLIST_TAIL(l1);
+ DLIST_HEAD(el, el2);
+ torture_assert(tctx, el2 == l1, "should find head");
+
+ torture_comment(tctx, "check DLIST_ADD_AFTER\n");
+ el = talloc(mem_ctx, struct listel);
+ el2 = talloc(mem_ctx, struct listel);
+ DLIST_ADD_AFTER(l1, el, l1);
+ DLIST_ADD_AFTER(l1, el2, el);
+ torture_assert(tctx, l1->next == el, "2nd in list");
+ torture_assert(tctx, el->next == el2, "3rd in list");
+
+ torture_comment(tctx, "check DLIST_PROMOTE\n");
+ DLIST_PROMOTE(l1, el2);
+ torture_assert(tctx, el2==l1, "1st in list");
+ torture_assert(tctx, el2->next->next == el, "3rd in list");
+
+ torture_comment(tctx, "check DLIST_DEMOTE\n");
+ DLIST_DEMOTE(l1, el);
+ torture_assert(tctx, el->next == NULL, "last in list");
+ torture_assert(tctx, el2->prev == el, "backlink from head");
+
+ torture_comment(tctx, "count forward\n");
+ for (i=0,el=l1; el; el=el->next) i++;
+ torture_assert_int_equal(tctx, i, 6, "should have 6 elements");
+
+ torture_comment(tctx, "count backwards\n");
+ for (i=0,el=DLIST_TAIL(l1); el; el=DLIST_PREV(el)) i++;
+ torture_assert_int_equal(tctx, i, 6, "should have 6 elements");
+
+ torture_comment(tctx, "check DLIST_CONCATENATE\n");
+ DLIST_CONCATENATE(l1, l2);
+ torture_comment(tctx, "count forward\n");
+ for (i=0,el=l1; el; el=el->next) i++;
+ torture_assert_int_equal(tctx, i, 12, "should have 12 elements");
+
+ torture_comment(tctx, "count backwards\n");
+ for (i=0,el=DLIST_TAIL(l1); el; el=DLIST_PREV(el)) i++;
+ torture_assert_int_equal(tctx, i, 12, "should have 12 elements");
+
+ torture_comment(tctx, "free forwards\n");
+ for (el=l1; el; el=el2) {
+ el2 = el->next;
+ DLIST_REMOVE(l1, el);
+ talloc_free(el);
+ }
+
+ torture_assert(tctx, l1 == NULL, "list empty");
+ torture_assert_int_equal(tctx, talloc_total_blocks(mem_ctx), 1, "1 block");
+
+ talloc_free(mem_ctx);
+ return true;
+}
+
+struct torture_suite *torture_local_dlinklist(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "dlinklist");
+ torture_suite_add_simple_test(suite, "dlinklist", torture_local_dlinklist_simple);
+ return suite;
+}
diff --git a/lib/util/tests/file.c b/lib/util/tests/file.c
new file mode 100644
index 0000000..3501c7e
--- /dev/null
+++ b/lib/util/tests/file.c
@@ -0,0 +1,291 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ util_file testing
+
+ Copyright (C) Jelmer Vernooij 2005
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "system/filesys.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+
+#define TEST_FILENAME "utilfile.test"
+#define TEST_LINE1 "This is list line 1..."
+#define TEST_LINE2 ".. and this is line 2"
+#define TEST_LINE3 "and end of the file"
+
+#define TEST_DATA TEST_LINE1 "\n" TEST_LINE2 "\n" TEST_LINE3
+
+static bool test_file_load_save(struct torture_context *tctx)
+{
+ size_t len;
+ char *data;
+ TALLOC_CTX *mem_ctx = tctx;
+
+ torture_assert(tctx, file_save(TEST_FILENAME, TEST_DATA, strlen(TEST_DATA)),
+ "saving file");
+
+ torture_assert_file_contains_text(tctx, TEST_FILENAME, TEST_DATA,
+ "file contents");
+
+ data = file_load(TEST_FILENAME, &len, 0, mem_ctx);
+ torture_assert(tctx, data, "loading file");
+
+ torture_assert_int_equal(tctx, len, strlen(TEST_DATA), "Length");
+
+ torture_assert_mem_equal(tctx, data, TEST_DATA, len, "Contents");
+
+ data = file_load(TEST_FILENAME, &len, 5, mem_ctx);
+
+ torture_assert_int_equal(tctx, len, 5, "Length");
+
+ torture_assert_mem_equal(tctx, data, TEST_DATA, len, "Contents");
+
+ unlink(TEST_FILENAME);
+ return true;
+}
+
+#define TEST_DATA_WITH_NEWLINE TEST_DATA "\n"
+#define TEST_DATA_NO_NEWLINE TEST_DATA
+#define TEST_DATA_EMPTY ""
+#define TEST_DATA_BLANKS_ONLY "\n\n\n\n\n"
+#define TEST_DATA_WITH_TRAILING_BLANKS TEST_DATA TEST_DATA_BLANKS_ONLY
+
+static bool test_file_lines_load(struct torture_context *tctx)
+{
+ char **lines;
+ int numlines;
+ TALLOC_CTX *mem_ctx = tctx;
+
+ /*
+ * Last line has trailing whitespace
+ */
+
+ torture_assert(tctx,
+ file_save(TEST_FILENAME,
+ TEST_DATA_WITH_NEWLINE,
+ strlen(TEST_DATA_WITH_NEWLINE)),
+ "saving file");
+
+ lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
+
+ torture_assert_int_equal(tctx, numlines, 3, "Lines");
+
+ torture_assert_mem_equal(tctx,
+ lines[0],
+ TEST_LINE1,
+ strlen(TEST_LINE1),
+ "Line 1");
+
+ torture_assert_mem_equal(tctx,
+ lines[1],
+ TEST_LINE2,
+ strlen(TEST_LINE2),
+ "Line 2");
+
+ torture_assert_mem_equal(tctx,
+ lines[2],
+ TEST_LINE3,
+ strlen(TEST_LINE3),
+ "Line 3");
+
+ unlink(TEST_FILENAME);
+
+ /*
+ * Last line has NO trailing whitespace
+ */
+
+ torture_assert(tctx,
+ file_save(TEST_FILENAME,
+ TEST_DATA_NO_NEWLINE,
+ strlen(TEST_DATA_NO_NEWLINE)),
+ "saving file");
+
+ lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
+
+ torture_assert_int_equal(tctx, numlines, 3, "Lines");
+
+ torture_assert_mem_equal(tctx,
+ lines[0],
+ TEST_LINE1,
+ strlen(TEST_LINE1),
+ "Line 1");
+
+ torture_assert_mem_equal(tctx,
+ lines[1],
+ TEST_LINE2,
+ strlen(TEST_LINE2),
+ "Line 2");
+
+ torture_assert_mem_equal(tctx,
+ lines[2],
+ TEST_LINE3,
+ strlen(TEST_LINE3),
+ "Line 3");
+
+ unlink(TEST_FILENAME);
+
+ /*
+ * Empty file
+ */
+
+ torture_assert(tctx,
+ file_save(TEST_FILENAME,
+ TEST_DATA_EMPTY,
+ strlen(TEST_DATA_EMPTY)),
+ "saving file");
+
+ (void)file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
+
+ torture_assert_int_equal(tctx, numlines, 0, "Lines");
+
+ unlink(TEST_FILENAME);
+
+ /*
+ * Just blank lines
+ */
+
+ torture_assert(tctx,
+ file_save(TEST_FILENAME,
+ TEST_DATA_BLANKS_ONLY,
+ strlen(TEST_DATA_BLANKS_ONLY)),
+ "saving file");
+
+ lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
+
+ torture_assert_int_equal(tctx, numlines, 0, "Lines");
+
+ unlink(TEST_FILENAME);
+
+ /*
+ * Several trailing blank lines
+ */
+
+ torture_assert(tctx,
+ file_save(TEST_FILENAME,
+ TEST_DATA_WITH_TRAILING_BLANKS,
+ strlen(TEST_DATA_WITH_TRAILING_BLANKS)),
+ "saving file");
+
+ lines = file_lines_load(TEST_FILENAME, &numlines, 0, mem_ctx);
+
+ torture_assert_int_equal(tctx, numlines, 3, "Lines");
+
+ torture_assert_mem_equal(tctx,
+ lines[0],
+ TEST_LINE1,
+ strlen(TEST_LINE1),
+ "Line 1");
+
+ torture_assert_mem_equal(tctx,
+ lines[1],
+ TEST_LINE2,
+ strlen(TEST_LINE2),
+ "Line 2");
+
+ torture_assert_mem_equal(tctx,
+ lines[2],
+ TEST_LINE3,
+ strlen(TEST_LINE3),
+ "Line 3");
+
+ unlink(TEST_FILENAME);
+
+ return true;
+}
+
+static bool test_afdgets(struct torture_context *tctx)
+{
+ int fd;
+ char *line;
+ TALLOC_CTX *mem_ctx = tctx;
+ bool ret = false;
+
+ torture_assert(tctx, file_save(TEST_FILENAME, (const void *)TEST_DATA,
+ strlen(TEST_DATA)),
+ "saving file");
+
+ fd = open(TEST_FILENAME, O_RDONLY);
+
+ torture_assert(tctx, fd != -1, "opening file");
+
+ line = afdgets(fd, mem_ctx, 8);
+ torture_assert_goto(tctx, strcmp(line, TEST_LINE1) == 0, ret, done,
+ "line 1 mismatch");
+
+ line = afdgets(fd, mem_ctx, 8);
+ torture_assert_goto(tctx, strcmp(line, TEST_LINE2) == 0, ret, done,
+ "line 2 mismatch");
+
+ line = afdgets(fd, mem_ctx, 8);
+ torture_assert_goto(tctx, strcmp(line, TEST_LINE3) == 0, ret, done,
+ "line 3 mismatch");
+ ret = true;
+done:
+ close(fd);
+
+ unlink(TEST_FILENAME);
+ return ret;
+}
+
+static bool test_file_lines_parse(struct torture_context *tctx)
+{
+ char **lines;
+ int numlines;
+ TALLOC_CTX *mem_ctx = tctx;
+ char *buf;
+ size_t size;
+
+ torture_assert(tctx, file_save(TEST_FILENAME,
+ (const void *)TEST_DATA,
+ strlen(TEST_DATA)),
+ "saving file");
+
+ buf = file_load(TEST_FILENAME, &size, 0, mem_ctx);
+ torture_assert(tctx, buf, "failed to load file");
+ unlink(TEST_FILENAME);
+
+ lines = file_lines_parse(buf,
+ size,
+ &numlines,
+ mem_ctx);
+ torture_assert(tctx, lines, "failed to parse lines");
+
+ TALLOC_FREE(lines);
+ TALLOC_FREE(buf);
+ return true;
+}
+
+struct torture_suite *torture_local_util_file(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "file");
+
+ torture_suite_add_simple_test(suite, "file_load_save",
+ test_file_load_save);
+
+ torture_suite_add_simple_test(suite,
+ "file_lines_load",
+ test_file_lines_load);
+
+ torture_suite_add_simple_test(suite, "afdgets", test_afdgets);
+
+ torture_suite_add_simple_test(suite, "file_lines_parse",
+ test_file_lines_parse);
+
+ return suite;
+}
diff --git a/lib/util/tests/genrand.c b/lib/util/tests/genrand.c
new file mode 100644
index 0000000..3987c33
--- /dev/null
+++ b/lib/util/tests/genrand.c
@@ -0,0 +1,61 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ local testing of random data routines.
+
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org>
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+
+static bool test_check_password_quality(struct torture_context *tctx)
+{
+ torture_assert(tctx, !check_password_quality(""), "empty password");
+ torture_assert(tctx, !check_password_quality("a"), "one char password");
+ torture_assert(tctx, !check_password_quality("aaaaaaaaaaaa"), "same char password");
+ torture_assert(tctx, !check_password_quality("BLA"), "multiple upcases password");
+ torture_assert(tctx, !check_password_quality("123"), "digits only");
+ torture_assert(tctx, !check_password_quality("matthiéu"), "not enough high symbols");
+ torture_assert(tctx, !check_password_quality("abcdééàçè"), "only lower case");
+ torture_assert(tctx, !check_password_quality("abcdééàçè+"), "only lower and symbols");
+ torture_assert(tctx, check_password_quality("abcdééàçè+ढ"), "valid");
+ torture_assert(tctx, check_password_quality("ç+ढ"), "valid");
+ torture_assert(tctx, check_password_quality("A2e"), "valid");
+ torture_assert(tctx, check_password_quality("BA2eLi443"), "valid");
+ return true;
+}
+
+static bool test_generate_random_str(struct torture_context *tctx)
+{
+ TALLOC_CTX *mem_ctx = talloc_init(__FUNCTION__);
+ char *r = generate_random_str(mem_ctx, 10);
+ torture_assert_int_equal(tctx, strlen(r), 10, "right length generated");
+ r = generate_random_str(mem_ctx, 5);
+ torture_assert_int_equal(tctx, strlen(r), 5, "right length generated");
+
+ TALLOC_FREE(mem_ctx);
+ return true;
+}
+
+struct torture_suite *torture_local_genrand(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "genrand");
+ torture_suite_add_simple_test(suite, "check_password_quality", test_check_password_quality);
+ torture_suite_add_simple_test(suite, "generate_random_str", test_generate_random_str);
+ return suite;
+}
diff --git a/lib/util/tests/genrandperf.c b/lib/util/tests/genrandperf.c
new file mode 100644
index 0000000..32d19ab
--- /dev/null
+++ b/lib/util/tests/genrandperf.c
@@ -0,0 +1,39 @@
+/*
+ Unix SMB/CIFS implementation.
+ local testing of random data routines.
+ Copyright (C) Volker Lendecke <vl@samba.org> 2015
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "lib/util/genrand.h"
+
+int main(int argc, const char *argv[])
+{
+ int i, num;
+ uint64_t val;
+
+ if (argc != 2) {
+ fprintf(stderr, "genrandperf <num>\n");
+ exit(1);
+ }
+ num = atoi(argv[1]);
+
+ for(i=0; i<num; i++) {
+ generate_random_buffer((uint8_t *)&val, sizeof(val));
+ }
+ printf("%"PRIu64"\n", val);
+ return 0;
+}
diff --git a/lib/util/tests/idtree.c b/lib/util/tests/idtree.c
new file mode 100644
index 0000000..d54ab27
--- /dev/null
+++ b/lib/util/tests/idtree.c
@@ -0,0 +1,123 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ local testing of idtree routines.
+
+ Copyright (C) Andrew Tridgell 2004
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+#include "lib/util/idtree.h"
+
+static bool torture_local_idtree_simple(struct torture_context *tctx)
+{
+ struct idr_context *idr;
+ int i, ret;
+ int *ids;
+ int *present;
+ extern int torture_numops;
+ int n = torture_numops;
+ TALLOC_CTX *mem_ctx = tctx;
+
+ idr = idr_init(mem_ctx);
+
+ ids = talloc_zero_array(mem_ctx, int, n);
+ present = talloc_zero_array(mem_ctx, int, n);
+
+ for (i=0;i<n;i++) {
+ ids[i] = -1;
+ }
+
+ for (i=0;i<n;i++) {
+ int ii = random() % n;
+ void *p = idr_find(idr, ids[ii]);
+ if (present[ii]) {
+ if (p != &ids[ii]) {
+ torture_fail(tctx, talloc_asprintf(tctx,
+ "wrong ptr at %d - %p should be %p",
+ ii, p, &ids[ii]));
+ }
+ if (random() % 7 == 0) {
+ if (idr_remove(idr, ids[ii]) != 0) {
+ torture_fail(tctx, talloc_asprintf(tctx,
+ "remove failed at %d (id=%d)",
+ i, ids[ii]));
+ }
+ present[ii] = 0;
+ ids[ii] = -1;
+ }
+ } else {
+ if (p != NULL) {
+ torture_fail(tctx,
+ talloc_asprintf(tctx,
+ "non-present at %d gave %p (would be %d)",
+ ii, p,
+ (int)((((char *)p) - (char *)(&ids[0])) / sizeof(int))));
+ }
+ if (random() % 5) {
+ ids[ii] = idr_get_new(idr, &ids[ii], n);
+ if (ids[ii] < 0) {
+ torture_fail(tctx, talloc_asprintf(tctx,
+ "alloc failure at %d (ret=%d)",
+ ii, ids[ii]));
+ } else {
+ present[ii] = 1;
+ }
+ }
+ }
+ }
+
+ torture_comment(tctx, "done %d random ops\n", i);
+
+ for (i=0;i<n;i++) {
+ if (present[i]) {
+ if (idr_remove(idr, ids[i]) != 0) {
+ torture_fail(tctx, talloc_asprintf(tctx,
+ "delete failed on cleanup at %d (id=%d)",
+ i, ids[i]));
+ }
+ }
+ }
+
+ /* now test some limits */
+ for (i=0;i<25000;i++) {
+ ret = idr_get_new_above(idr, &ids[0], random() % 25000, 0x10000-3);
+ torture_assert(tctx, ret != -1, "idr_get_new_above failed");
+ }
+
+ ret = idr_get_new_above(idr, &ids[0], 0x10000-2, 0x10000);
+ torture_assert_int_equal(tctx, ret, 0x10000-2, "idr_get_new_above failed");
+ ret = idr_get_new_above(idr, &ids[0], 0x10000-1, 0x10000);
+ torture_assert_int_equal(tctx, ret, 0x10000-1, "idr_get_new_above failed");
+ ret = idr_get_new_above(idr, &ids[0], 0x10000, 0x10000);
+ torture_assert_int_equal(tctx, ret, 0x10000, "idr_get_new_above failed");
+ ret = idr_get_new_above(idr, &ids[0], 0x10000+1, 0x10000);
+ torture_assert_int_equal(tctx, ret, -1, "idr_get_new_above succeeded above limit");
+ ret = idr_get_new_above(idr, &ids[0], 0x10000+2, 0x10000);
+ torture_assert_int_equal(tctx, ret, -1, "idr_get_new_above succeeded above limit");
+
+ torture_comment(tctx, "cleaned up\n");
+ return true;
+}
+
+struct torture_suite *torture_local_idtree(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "idtree");
+ torture_suite_add_simple_test(suite, "idtree", torture_local_idtree_simple);
+ return suite;
+}
diff --git a/lib/util/tests/rfc1738.c b/lib/util/tests/rfc1738.c
new file mode 100644
index 0000000..4f7eced
--- /dev/null
+++ b/lib/util/tests/rfc1738.c
@@ -0,0 +1,411 @@
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdint.h>
+#include <cmocka.h>
+#include "lib/replace/replace.h"
+
+#include <errno.h>
+#include <unistd.h>
+#include <talloc.h>
+#include <ctype.h>
+#include <string.h>
+#include "lib/util/samba_util.h"
+
+/* These flags say what can be asserted about a relationship between a string
+ and its supposedly escaped equivalent.
+
+ The first part of the flag name indicates the direction of transformation;
+ the second part is the expected result. For example, ESCAPE_EQ means the
+ escape is expected to succeed and result is expected to be equal to the
+ given answer. ESCAPE_EQ_CASECMP is only equal when compared
+ case-insensitively. UNESCAPE_ERR means unescaping the escaped string should
+ result in an error.
+*/
+#define UNESCAPE_ERR 1
+#define ESCAPE_ERR 2
+#define ESCAPE_EQ 4
+#define UNESCAPE_EQ 8
+#define ESCAPE_NE 16
+#define UNESCAPE_NE 32
+#define ESCAPE_EQ_CASECMP 64
+
+struct rfc1738_test {
+ const char *escaped; /* original for unescape; result for escape */
+ const char *unescaped; /* result in unescape; original for escape */
+ uint32_t flags; /* see above */
+ int unesc_len; /* end - start will be this */
+ int unesc_strlen; /* strlen() will say this */
+ int esc_len; /* escaped string length */
+};
+
+/* unreserved = ALPHA DIGIT - . _ ~ */
+
+char spectrum[255 + 1];
+char spectrum_escaped[255 * 3 + 1];
+
+struct rfc1738_test examples[] = {
+
+#define SIMPLE1 "this_is_a_simple-string._With_no_escapes~" /* maps to self */
+ {
+ SIMPLE1,
+ SIMPLE1,
+ ESCAPE_EQ | UNESCAPE_EQ, /* round trip should work */
+ sizeof(SIMPLE1) - 1,
+ sizeof(SIMPLE1) - 1,
+ sizeof(SIMPLE1) - 1,
+ },
+#define SIMPLE2 "no escapes, but\n non-printables \xc5\x8d\x99"
+#define SIMPLE2_ESC "no%20escapes%2C%20but%0A%20non-printables%20%C5%8D%99"
+ {
+ SIMPLE2_ESC,
+ SIMPLE2,
+ ESCAPE_EQ | UNESCAPE_EQ,
+ sizeof(SIMPLE2) - 1,
+ sizeof(SIMPLE2) - 1,
+ sizeof(SIMPLE2_ESC) - 1,
+ },
+#define SIMPLE3 "this @#$^&*()_+{}:;"
+#define SIMPLE3_ESC "this%20%40%23%24%5E%26%2A%28%29_%2B%7B%7D%3A%3B"
+ {
+ SIMPLE3_ESC,
+ SIMPLE3,
+ ESCAPE_EQ | UNESCAPE_EQ,
+ sizeof(SIMPLE3) - 1,
+ sizeof(SIMPLE3) - 1,
+ sizeof(SIMPLE3_ESC) - 1,
+ },
+
+#define ESCAPE1 "%/\x06this string has expected escapes"
+#define ESCAPE1_ESC "%25%2F%06this%20string%20has%20expected%20escapes"
+#define ESCAPE1_ESC_ESC "%2525%252F%2506this%2520string%2520has%2520expected"\
+ "%2520escapes"
+ {
+ ESCAPE1_ESC,
+ ESCAPE1,
+ ESCAPE_EQ | UNESCAPE_EQ,
+ sizeof(ESCAPE1) - 1,
+ sizeof(ESCAPE1) - 1,
+ sizeof(ESCAPE1_ESC) - 1,
+ },
+ {
+ ESCAPE1_ESC_ESC, /*re-escaping */
+ ESCAPE1_ESC,
+ ESCAPE_EQ | UNESCAPE_EQ,
+ sizeof(ESCAPE1_ESC) - 1,
+ sizeof(ESCAPE1_ESC) - 1,
+ sizeof(ESCAPE1_ESC_ESC) - 1,
+ },
+#define ESCAPE2 "%25%2f%06-this-string-has-expected-lowercase-escapes-%ab"
+#define ESCAPE2_UNESC "%/\x06-this-string-has-expected-lowercase-escapes-\xab"
+ {
+ ESCAPE2,
+ ESCAPE2_UNESC,
+ ESCAPE_EQ_CASECMP | UNESCAPE_EQ, /* escape won't match case */
+ sizeof(ESCAPE2_UNESC) - 1,
+ sizeof(ESCAPE2_UNESC) - 1,
+ sizeof(ESCAPE2) - 1,
+ },
+#define ESCAPE3 "%25%2f%06 %32 %44 %6a%AA THIS string h%61s random escapes %ab"
+#define ESCAPE3_UNESC "%/\x06 2 D j\xAA THIS string has random escapes \xab"
+ {
+ ESCAPE3,
+ ESCAPE3_UNESC,
+ ESCAPE_NE | UNESCAPE_EQ, /* escape will have escaped spaces */
+ sizeof(ESCAPE3_UNESC) - 1,
+ sizeof(ESCAPE3_UNESC) - 1,
+ sizeof(ESCAPE3) - 1,
+ },
+#define ESCAPE4 "%25%25%25" /* */
+#define ESCAPE4_UNESC "%%%" /* */
+#define ESCAPE4_ESC "%2525%2525%2525"
+ {
+ ESCAPE4,
+ ESCAPE4_UNESC,
+ ESCAPE_EQ | UNESCAPE_EQ,
+ sizeof(ESCAPE4_UNESC) - 1,
+ sizeof(ESCAPE4_UNESC) - 1,
+ sizeof(ESCAPE4) - 1,
+ },
+ {
+ ESCAPE4_ESC,
+ ESCAPE4,
+ ESCAPE_EQ | UNESCAPE_EQ,
+ sizeof(ESCAPE4) - 1,
+ sizeof(ESCAPE4) - 1,
+ sizeof(ESCAPE4_ESC) - 1,
+ },
+#define BAD1 "trailing percent is bad %"
+#define BAD1_ESC "trailing%20percent%20is%20bad%20%25"
+ {
+ BAD1_ESC,
+ BAD1,
+ UNESCAPE_EQ |ESCAPE_EQ,
+ sizeof(BAD1) - 1,
+ sizeof(BAD1) - 1,
+ sizeof(BAD1_ESC) - 1,
+ },
+ {
+ BAD1,
+ NULL,
+ UNESCAPE_ERR,
+ 0,
+ 0,
+ sizeof(BAD1) - 1,
+ },
+#define BAD2 "trailing percent is bad %1"
+#define BAD3 "bad characters %1 "
+ {
+ BAD2,
+ NULL,
+ UNESCAPE_ERR,
+ 0,
+ 0,
+ sizeof(BAD2) - 1,
+ },
+ {
+ BAD3,
+ NULL,
+ UNESCAPE_ERR,
+ 0,
+ 0,
+ sizeof(BAD3) - 1,
+ },
+#define BAD4 "bad characters %1 "
+ {
+ BAD4,
+ NULL,
+ UNESCAPE_ERR,
+ 0,
+ 0,
+ sizeof(BAD4) - 1,
+ },
+#define BAD5 "bad characters %1- "
+ {
+ BAD5,
+ NULL,
+ UNESCAPE_ERR,
+ 0,
+ 0,
+ sizeof(BAD5) - 1,
+ },
+#define BAD6 "bad characters %1G "
+ {
+ BAD6,
+ NULL,
+ UNESCAPE_ERR,
+ 0,
+ 0,
+ sizeof(BAD6) - 1,
+ },
+#define BAD7 "bad characters %%1 "
+ {
+ BAD7,
+ NULL,
+ UNESCAPE_ERR,
+ 0,
+ 0,
+ sizeof(BAD7) - 1,
+ },
+#define BAD8 "bad characters %sb "
+ {
+ BAD8,
+ NULL,
+ UNESCAPE_ERR,
+ 0,
+ 0,
+ sizeof(BAD8) - 1,
+ },
+#define BAD_SSCANF "sscanf would be happy with this\n"
+#define BAD_SSCANF_ESC "sscanf would be happy with this% a"
+ {
+ BAD_SSCANF_ESC,
+ BAD_SSCANF,
+ ESCAPE_NE | UNESCAPE_ERR,
+ sizeof(BAD_SSCANF) - 1,
+ sizeof(BAD_SSCANF) - 1,
+ sizeof(BAD_SSCANF_ESC) - 1,
+ },
+ /* now try some with zeros in. escaping can't see past zeros, and the result is truncated */
+#define ZERO "%00"
+#define ZERO_UNESC "\0"
+ {
+ ESCAPE4 ZERO ESCAPE4,
+ ESCAPE4_UNESC ZERO_UNESC ESCAPE4_UNESC,
+ ESCAPE_NE | UNESCAPE_EQ,
+ sizeof(ESCAPE4_UNESC ZERO_UNESC ESCAPE4_UNESC) - 1,
+ sizeof(ESCAPE4_UNESC) - 1,
+ sizeof(ESCAPE4 ZERO ESCAPE4) - 1,
+ },
+ {
+ ZERO ESCAPE4,
+ ZERO_UNESC ESCAPE4_UNESC,
+ ESCAPE_NE | UNESCAPE_EQ,
+ sizeof(ZERO_UNESC ESCAPE4_UNESC) - 1,
+ 0,
+ sizeof(ZERO ESCAPE4) - 1,
+ },
+ {
+ ZERO,
+ ZERO_UNESC,
+ ESCAPE_NE | UNESCAPE_EQ,
+ sizeof(ZERO_UNESC) - 1,
+ 0,
+ sizeof(ZERO) - 1,
+ },
+ {
+ spectrum_escaped,
+ spectrum,
+ ESCAPE_EQ | UNESCAPE_EQ,
+ 255,
+ 255,
+ 255 * 3,
+ },
+};
+
+static struct rfc1738_test * dup_test(struct rfc1738_test *src)
+{
+ struct rfc1738_test *dest = malloc(sizeof(*dest));
+ char *esc = NULL, *unesc = NULL;
+ if (dest == NULL) {
+ return NULL;
+ }
+ *dest = *src;
+ if (src->esc_len) {
+ esc = malloc(src->esc_len + 1);
+ if (esc == NULL) {
+ free(dest);
+ return NULL;
+ }
+ memcpy(esc, src->escaped, src->esc_len + 1);
+ dest->escaped = esc;
+ }
+
+ if (src->unesc_len) {
+ unesc = malloc(src->unesc_len + 1);
+ if (unesc == NULL) {
+ free(esc);
+ free(dest);
+ return NULL;
+ }
+ memcpy(unesc, src->unescaped, src->unesc_len + 1);
+ dest->unescaped = unesc;
+ }
+
+ return dest;
+}
+
+static void free_test(struct rfc1738_test *t)
+{
+ free(discard_const_p(char, t->escaped));
+ free(discard_const_p(char, t->unescaped));
+ free(t);
+}
+
+
+static void test_unescape(void **state)
+{
+ uint i;
+ char *s, *e;
+ struct rfc1738_test *test, *orig;
+ for (i = 0; i < ARRAY_SIZE(examples); i++) {
+ orig = &examples[i];
+ if ((orig->flags & (UNESCAPE_ERR |
+ UNESCAPE_EQ |
+ UNESCAPE_NE)) == 0) {
+ continue;
+ }
+ test = dup_test(&examples[i]);
+ s = discard_const_p(char, test->escaped);
+ e = rfc1738_unescape(s);
+ if (test->flags & UNESCAPE_ERR) {
+ assert_null(e);
+ free_test(test);
+ continue;
+ }
+ assert_non_null(e);
+ assert_int_equal(e - s, test->unesc_len);
+
+ if (test->flags & UNESCAPE_EQ) {
+ assert_memory_equal(s,
+ orig->unescaped,
+ orig->unesc_len);
+ assert_int_equal(strlen(s),
+ orig->unesc_strlen);
+ } else {
+ assert_memory_not_equal(s,
+ orig->unescaped,
+ orig->unesc_len);
+ assert_int_equal(strlen(s),
+ orig->unesc_strlen);
+ }
+ free_test(test);
+ }
+}
+
+static void test_escape(void **state)
+{
+ uint i;
+ char *s, *e;
+ struct rfc1738_test *test, *orig;
+ for (i = 0; i < ARRAY_SIZE(examples); i++) {
+ orig = &examples[i];
+ if ((orig->flags & (ESCAPE_EQ |
+ ESCAPE_EQ_CASECMP |
+ ESCAPE_NE)) == 0) {
+ continue;
+ }
+ test = dup_test(&examples[i]);
+ s = discard_const_p(char, test->unescaped);
+ e = rfc1738_escape_part(NULL, s);
+ if (test->flags & ESCAPE_EQ) {
+ assert_memory_equal(e, test->escaped,
+ test->esc_len + 1);
+ } else if (test->flags & ESCAPE_EQ_CASECMP) {
+ int cmp = strcasecmp(e, test->escaped);
+ assert_int_equal(cmp, 0);
+ assert_string_not_equal(e, test->escaped);
+ } else {
+ assert_string_not_equal(e, test->escaped);
+ }
+ free_test(test);
+ }
+}
+
+
+static void gen_spectrum(void)
+{
+ int i, j = 0;
+ const char *lut = "0123456789ABCDEF";
+ for (i = 1; i < 256; i++) {
+ spectrum[i - 1] = i;
+ if (isalnum(i) ||
+ i == '-' ||
+ i == '.' ||
+ i == '_' ||
+ i == '-' ||
+ i == '~') {
+ spectrum_escaped[j] = i;
+ j++;
+ } else {
+ spectrum_escaped[j] = '%';
+ spectrum_escaped[j + 1] = lut[i >> 4];
+ spectrum_escaped[j + 2] = lut[i & 15];
+ j += 3;
+ }
+ }
+ spectrum[i - 1] = '\0';
+ spectrum_escaped[j] = '\0';
+}
+
+int main(int argc, const char **argv)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_escape),
+ cmocka_unit_test(test_unescape),
+ };
+
+ gen_spectrum();
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/lib/util/tests/str.c b/lib/util/tests/str.c
new file mode 100644
index 0000000..41a2836
--- /dev/null
+++ b/lib/util/tests/str.c
@@ -0,0 +1,180 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ util_str testing
+
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+
+static bool test_string_sub_simple(struct torture_context *tctx)
+{
+ char tmp[100];
+ strlcpy(tmp, "foobar", sizeof(tmp));
+ string_sub(tmp, "foo", "bar", sizeof(tmp));
+ torture_assert_str_equal(tctx, tmp, "barbar", "invalid sub");
+ return true;
+}
+
+static bool test_string_sub_multiple(struct torture_context *tctx)
+{
+ char tmp[100];
+ strlcpy(tmp, "fooblafoo", sizeof(tmp));
+ string_sub(tmp, "foo", "bar", sizeof(tmp));
+ torture_assert_str_equal(tctx, tmp, "barblabar", "invalid sub");
+ return true;
+}
+
+static bool test_string_sub_longer(struct torture_context *tctx)
+{
+ char tmp[100];
+ strlcpy(tmp, "foobla", sizeof(tmp));
+ string_sub(tmp, "foo", "blie", sizeof(tmp));
+ torture_assert_str_equal(tctx, tmp, "bliebla", "invalid sub");
+ return true;
+}
+
+static bool test_string_sub_shorter(struct torture_context *tctx)
+{
+ char tmp[100];
+ strlcpy(tmp, "foobla", sizeof(tmp));
+ string_sub(tmp, "foo", "bl", sizeof(tmp));
+ torture_assert_str_equal(tctx, tmp, "blbla", "invalid sub");
+ return true;
+}
+
+static bool test_string_sub_special_char(struct torture_context *tctx)
+{
+ char tmp[100];
+ strlcpy(tmp, "foobla", sizeof(tmp));
+ string_sub(tmp, "foo", "%b;l", sizeof(tmp));
+ torture_assert_str_equal(tctx, tmp, "_b_lbla", "invalid sub");
+ return true;
+}
+
+static bool test_talloc_string_sub_simple(struct torture_context *tctx)
+{
+ char *t;
+
+ t = talloc_string_sub(tctx, "foobla", "foo", "bl");
+
+ torture_assert_str_equal(tctx, t, "blbla", "invalid sub");
+
+ return true;
+}
+
+static bool test_talloc_string_sub_multiple(struct torture_context *tctx)
+{
+ char *t;
+
+ t = talloc_string_sub(tctx, "fooblafoo", "foo", "aapnootmies");
+
+ torture_assert_str_equal(tctx, t, "aapnootmiesblaaapnootmies",
+ "invalid sub");
+
+ return true;
+}
+
+/*
+ * with these next three tests, the failure is that the pattern looks like
+ * "+++" because the \x.. bytes encode a zero byte in UTF-8. If we are not
+ * careful with these strings we will see crashes instead of failures.
+ */
+
+static bool test_talloc_string_sub_tricky_utf8_4(struct torture_context *tctx)
+{
+ const char string[] = "++++--\xD8\xBB";
+ const char pattern[] = "+++\xF0\x80\x80\x80++";
+ const char replace[] = "...";
+
+ char *t = talloc_string_sub(tctx, string, pattern, replace);
+ torture_assert_str_equal(tctx, t, string,
+ "should reject 4 byte NUL char");
+ talloc_free(t);
+ return true;
+}
+
+static bool test_talloc_string_sub_tricky_utf8_3(struct torture_context *tctx)
+{
+ const char string[] = "++++--\xD8\xBB";
+ const char pattern[] = "+++\xE0\x80\x80++";
+ const char replace[] = "...";
+
+ char *t = talloc_string_sub(tctx, string, pattern, replace);
+ torture_assert_str_equal(tctx, t, string,
+ "should reject 3 byte NUL char");
+ talloc_free(t);
+ return true;
+}
+
+static bool test_talloc_string_sub_tricky_utf8_2(struct torture_context *tctx)
+{
+ const char string[] = "++++--\xD8\xBB";
+ const char pattern[] = "+++\xC0\x80++";
+ const char replace[] = "...";
+
+ char *t = talloc_string_sub(tctx, string, pattern, replace);
+ torture_assert_str_equal(tctx, t, string,
+ "should reject 2 byte NUL char");
+ talloc_free(t);
+ return true;
+}
+
+
+
+
+struct torture_suite *torture_local_util_str(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "str");
+
+ torture_suite_add_simple_test(suite, "string_sub_simple",
+ test_string_sub_simple);
+
+ torture_suite_add_simple_test(suite, "string_sub_multiple",
+ test_string_sub_multiple);
+
+ torture_suite_add_simple_test(suite, "string_sub_shorter",
+ test_string_sub_shorter);
+
+ torture_suite_add_simple_test(suite, "string_sub_longer",
+ test_string_sub_longer);
+
+ torture_suite_add_simple_test(suite, "string_sub_special_chars",
+ test_string_sub_special_char);
+
+ torture_suite_add_simple_test(suite, "talloc_string_sub_simple",
+ test_talloc_string_sub_simple);
+
+ torture_suite_add_simple_test(suite, "string_sub_talloc_multiple",
+ test_talloc_string_sub_multiple);
+
+ torture_suite_add_simple_test(suite,
+ "test_talloc_string_sub_tricky_utf8_4",
+ test_talloc_string_sub_tricky_utf8_4);
+
+ torture_suite_add_simple_test(suite,
+ "test_talloc_string_sub_tricky_utf8_3",
+ test_talloc_string_sub_tricky_utf8_3);
+
+ torture_suite_add_simple_test(suite,
+ "test_talloc_string_sub_tricky_utf8_2",
+ test_talloc_string_sub_tricky_utf8_2);
+
+ return suite;
+}
diff --git a/lib/util/tests/strlist.c b/lib/util/tests/strlist.c
new file mode 100644
index 0000000..a9306b8
--- /dev/null
+++ b/lib/util/tests/strlist.c
@@ -0,0 +1,558 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ util_strlist testing
+
+ Copyright (C) Jelmer Vernooij 2005
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+#include "param/param.h"
+
+struct test_list_element {
+ const char *list_as_string;
+ const char *separators;
+ const char *list[5];
+};
+
+const struct test_list_element test_lists_strings[] = {
+ {
+ .list_as_string = "",
+ .list = { NULL }
+ },
+ {
+ .list_as_string = "foo",
+ .list = { "foo", NULL }
+ },
+ {
+ .list_as_string = "foo bar",
+ .list = { "foo", "bar", NULL }
+ },
+ {
+ .list_as_string = "foo bar",
+ .list = { "foo bar", NULL },
+ .separators = ";"
+ },
+ {
+ .list_as_string = "\"foo bar\"",
+ .list = { "\"foo", "bar\"", NULL }
+ },
+ {
+ .list_as_string = "\"foo bar\",comma\ttab",
+ .list = { "\"foo", "bar\"", "comma", "tab", NULL }
+ },
+ {
+ .list_as_string = "\"foo bar\",comma;semicolon",
+ .list = { "\"foo bar\",comma", "semicolon", NULL },
+ .separators = ";"
+ }
+};
+
+const struct test_list_element test_lists_shell_strings[] = {
+ {
+ .list_as_string = "",
+ .list = { NULL }
+ },
+ {
+ .list_as_string = "foo",
+ .list = { "foo", NULL }
+ },
+ {
+ .list_as_string = "foo bar",
+ .list = { "foo", "bar", NULL }
+ },
+ {
+ .list_as_string = "foo bar",
+ .list = { "foo bar", NULL },
+ .separators = ";"
+ },
+ {
+ .list_as_string = "\"foo bar\"",
+ .list = { "foo bar", NULL }
+ },
+ {
+ .list_as_string = "foo bar \"bla \"",
+ .list = { "foo", "bar", "bla ", NULL }
+ },
+ {
+ .list_as_string = "foo \"\" bla",
+ .list = { "foo", "", "bla", NULL },
+ },
+ {
+ .list_as_string = "bla \"\"\"\" blie",
+ .list = { "bla", "", "", "blie", NULL },
+ }
+};
+
+static bool test_lists_shell(struct torture_context *tctx, const void *data)
+{
+ const struct test_list_element *element = data;
+
+ char **ret1, **ret2, *tmp;
+ bool match = true;
+ TALLOC_CTX *mem_ctx = tctx;
+
+ ret1 = str_list_make_shell(mem_ctx, element->list_as_string, element->separators);
+
+ torture_assert(tctx, ret1, "str_list_make_shell() must not return NULL");
+ tmp = str_list_join_shell(mem_ctx, discard_const_p(const char *, ret1),
+ element->separators ? *element->separators : ' ');
+ ret2 = str_list_make_shell(mem_ctx, tmp, element->separators);
+
+ if ((ret1 == NULL || ret2 == NULL) && ret2 != ret1) {
+ match = false;
+ } else {
+ int j;
+ for (j = 0; ret1[j] && ret2[j]; j++) {
+ if (strcmp(ret1[j], ret2[j]) != 0) {
+ match = false;
+ break;
+ }
+ }
+
+ if (ret1[j] || ret2[j])
+ match = false;
+ }
+
+ torture_assert(tctx, match, talloc_asprintf(tctx,
+ "str_list_{make,join}_shell: Error double parsing, first run:\n%s\nSecond run: \n%s", element->list_as_string, tmp));
+ torture_assert(tctx, str_list_equal((const char * const *) ret1,
+ element->list),
+ talloc_asprintf(tctx,
+ "str_list_make_shell(%s) failed to create correct list",
+ element->list_as_string));
+
+ return true;
+}
+
+static bool test_list_make(struct torture_context *tctx, const void *data)
+{
+ const struct test_list_element *element = data;
+
+ char **result;
+ result = str_list_make(tctx, element->list_as_string, element->separators);
+ torture_assert(tctx, result, "str_list_make() must not return NULL");
+ torture_assert(tctx, str_list_equal((const char * const *) result,
+ element->list),
+ talloc_asprintf(tctx,
+ "str_list_make(%s) failed to create correct list",
+ element->list_as_string));
+ return true;
+}
+
+static bool test_list_copy(struct torture_context *tctx)
+{
+ const char **result;
+ const char *list[] = { "foo", "bar", NULL };
+ const char *empty_list[] = { NULL };
+ const char **null_list = NULL;
+ char **l;
+
+ l = str_list_copy(tctx, list);
+ result = discard_const_p(const char *, l);
+ torture_assert_int_equal(tctx, str_list_length(result), 2, "list length");
+ torture_assert_str_equal(tctx, result[0], "foo", "element 0");
+ torture_assert_str_equal(tctx, result[1], "bar", "element 1");
+ torture_assert_str_equal(tctx, result[2], NULL, "element 2");
+
+ l = str_list_copy(tctx, empty_list);
+ result = discard_const_p(const char *, l);
+ torture_assert_int_equal(tctx, str_list_length(result), 0, "list length");
+ torture_assert_str_equal(tctx, result[0], NULL, "element 0");
+
+ l = str_list_copy(tctx, null_list);
+ result = discard_const_p(const char *, l);
+ torture_assert(tctx, result == NULL, "result NULL");
+
+ return true;
+}
+
+static bool test_list_make_empty(struct torture_context *tctx)
+{
+ char **result;
+
+ result = str_list_make_empty(tctx);
+ torture_assert(tctx, result, "str_list_make_empty() must not return NULL");
+ torture_assert(tctx, result[0] == NULL, "first element in str_list_make_empty() result must be NULL");
+
+ result = str_list_make(tctx, NULL, NULL);
+ torture_assert(tctx, result, "str_list_make() must not return NULL");
+ torture_assert(tctx, result[0] == NULL, "first element in str_list_make(ctx, NULL, NULL) result must be NULL");
+
+ result = str_list_make(tctx, "", NULL);
+ torture_assert(tctx, result, "str_list_make() must not return NULL");
+ torture_assert(tctx, result[0] == NULL, "first element in str_list_make(ctx, "", NULL) result must be NULL");
+
+ return true;
+}
+
+static bool test_list_make_single(struct torture_context *tctx)
+{
+ char **result;
+
+ result = str_list_make_single(tctx, "foo");
+
+ torture_assert(tctx, result, "str_list_make_single() must not return NULL");
+ torture_assert_str_equal(tctx, result[0], "foo", "element 0");
+ torture_assert(tctx, result[1] == NULL, "second element in result must be NULL");
+
+ return true;
+}
+
+static bool test_list_copy_const(struct torture_context *tctx)
+{
+ const char **result;
+ const char *list[] = {
+ "element_0",
+ "element_1",
+ "element_2",
+ "element_3",
+ NULL
+ };
+ result = str_list_copy_const(tctx, list);
+ torture_assert(tctx, result, "str_list_copy() must not return NULL");
+ torture_assert(tctx, str_list_equal(result, list),
+ "str_list_copy() failed");
+
+ return true;
+}
+
+static bool test_list_length(struct torture_context *tctx)
+{
+ const char *list[] = {
+ "element_0",
+ "element_1",
+ "element_2",
+ "element_3",
+ NULL
+ };
+ const char *list2[] = {
+ NULL
+ };
+ torture_assert_int_equal(tctx, str_list_length(list), 4,
+ "str_list_length() failed");
+
+ torture_assert_int_equal(tctx, str_list_length(list2), 0,
+ "str_list_length() failed");
+
+ torture_assert_int_equal(tctx, str_list_length(NULL), 0,
+ "str_list_length() failed");
+
+ return true;
+}
+
+static bool test_list_add(struct torture_context *tctx)
+{
+ const char **result, **result2;
+ const char *list[] = {
+ "element_0",
+ "element_1",
+ "element_2",
+ "element_3",
+ NULL
+ };
+ char **l;
+
+ l = str_list_make(tctx, "element_0, element_1, element_2", NULL);
+ result = discard_const_p(const char *, l);
+ torture_assert(tctx, result, "str_list_make() must not return NULL");
+ result2 = str_list_add(result, "element_3");
+ torture_assert(tctx, result2, "str_list_add() must not return NULL");
+ torture_assert(tctx, str_list_equal(result2, list),
+ "str_list_add() failed");
+
+ return true;
+}
+
+static bool test_list_add_const(struct torture_context *tctx)
+{
+ const char **result, **result2;
+ const char *list[] = {
+ "element_0",
+ "element_1",
+ "element_2",
+ "element_3",
+ NULL
+ };
+ char **l;
+
+ l = str_list_make(tctx, "element_0, element_1, element_2", NULL);
+ result = discard_const_p(const char *, l);
+ torture_assert(tctx, result, "str_list_make() must not return NULL");
+ result2 = str_list_add_const(result, "element_3");
+ torture_assert(tctx, result2, "str_list_add_const() must not return NULL");
+ torture_assert(tctx, str_list_equal(result2, list),
+ "str_list_add() failed");
+
+ return true;
+}
+
+static bool test_list_remove(struct torture_context *tctx)
+{
+ const char **result;
+ const char *list[] = {
+ "element_0",
+ "element_1",
+ "element_3",
+ NULL
+ };
+ char **l;
+
+ l = str_list_make(tctx, "element_0, element_1, element_2, element_3", NULL);
+ result = discard_const_p(const char *, l);
+ torture_assert(tctx, result, "str_list_make() must not return NULL");
+ str_list_remove(result, "element_2");
+ torture_assert(tctx, str_list_equal(result, list),
+ "str_list_remove() failed");
+
+ return true;
+}
+
+static bool test_list_check(struct torture_context *tctx)
+{
+ const char *list[] = {
+ "element_0",
+ "element_1",
+ "element_2",
+ NULL
+ };
+ torture_assert(tctx, str_list_check(list, "element_1"),
+ "str_list_check() failed");
+
+ return true;
+}
+
+static bool test_list_check_ci(struct torture_context *tctx)
+{
+ const char *list[] = {
+ "element_0",
+ "element_1",
+ "element_2",
+ NULL
+ };
+ torture_assert(tctx, str_list_check_ci(list, "ELEMENT_1"),
+ "str_list_check_ci() failed");
+
+ return true;
+}
+
+static bool test_list_unique(struct torture_context *tctx)
+{
+ const char **result;
+ const char *list[] = {
+ "element_0",
+ "element_1",
+ "element_2",
+ NULL
+ };
+ const char *list_dup[] = {
+ "element_0",
+ "element_1",
+ "element_2",
+ "element_0",
+ "element_2",
+ "element_1",
+ "element_1",
+ "element_2",
+ NULL
+ };
+ char **l;
+
+ l = str_list_copy(tctx, list_dup);
+ result = discard_const_p(const char *, l);
+ /* We must copy the list, as str_list_unique does a talloc_realloc() on it's parameter */
+ result = str_list_unique(result);
+ torture_assert(tctx, result, "str_list_unique() must not return NULL");
+
+ torture_assert(tctx, str_list_equal(list, result),
+ "str_list_unique() failed");
+
+ return true;
+}
+
+static bool test_list_unique_2(struct torture_context *tctx)
+{
+ int i;
+ int count, num_dups;
+ const char **result;
+ char **l1 = str_list_make_empty(tctx);
+ char **l2 = str_list_make_empty(tctx);
+ const char **list = discard_const_p(const char *, l1);
+ const char **list_dup = discard_const_p(const char *, l2);
+ char **l;
+
+ count = lpcfg_parm_int(tctx->lp_ctx, NULL, "list_unique", "count", 9);
+ num_dups = lpcfg_parm_int(tctx->lp_ctx, NULL, "list_unique", "dups", 7);
+ torture_comment(tctx, "test_list_unique_2() with %d elements and %d dups\n", count, num_dups);
+
+ for (i = 0; i < count; i++) {
+ list = str_list_add_const(list, (const char *)talloc_asprintf(tctx, "element_%03d", i));
+ }
+
+ for (i = 0; i < num_dups; i++) {
+ list_dup = str_list_append(list_dup, list);
+ }
+
+ l = str_list_copy(tctx, list_dup);
+ result = discard_const_p(const char *, l);
+ /* We must copy the list, as str_list_unique does a talloc_realloc() on it's parameter */
+ result = str_list_unique(result);
+ torture_assert(tctx, result, "str_list_unique() must not return NULL");
+
+ torture_assert(tctx, str_list_equal(list, result),
+ "str_list_unique() failed");
+
+ return true;
+}
+
+static bool test_list_append(struct torture_context *tctx)
+{
+ const char **result;
+ const char *list[] = {
+ "element_0",
+ "element_1",
+ "element_2",
+ NULL
+ };
+ const char *list2[] = {
+ "element_3",
+ "element_4",
+ "element_5",
+ NULL
+ };
+ const char *list_combined[] = {
+ "element_0",
+ "element_1",
+ "element_2",
+ "element_3",
+ "element_4",
+ "element_5",
+ NULL
+ };
+ char **l;
+ l = str_list_copy(tctx, list);
+ result = discard_const_p(const char *, l);
+ torture_assert(tctx, result, "str_list_copy() must not return NULL");
+ result = str_list_append(result, list2);
+ torture_assert(tctx, result, "str_list_append() must not return NULL");
+ torture_assert(tctx, str_list_equal(list_combined, result),
+ "str_list_unique() failed");
+
+ return true;
+}
+
+static bool test_list_append_const(struct torture_context *tctx)
+{
+ const char **result;
+ const char *list[] = {
+ "element_0",
+ "element_1",
+ "element_2",
+ NULL
+ };
+ const char *list2[] = {
+ "element_3",
+ "element_4",
+ "element_5",
+ NULL
+ };
+ const char *list_combined[] = {
+ "element_0",
+ "element_1",
+ "element_2",
+ "element_3",
+ "element_4",
+ "element_5",
+ NULL
+ };
+ char **l;
+ l = str_list_copy(tctx, list);
+ result = discard_const_p(const char *, l);
+ torture_assert(tctx, result, "str_list_copy() must not return NULL");
+ result = str_list_append_const(result, list2);
+ torture_assert(tctx, result, "str_list_append_const() must not return NULL");
+ torture_assert(tctx, str_list_equal(list_combined, result),
+ "str_list_unique() failed");
+
+ return true;
+}
+
+static bool test_list_add_printf_NULL(struct torture_context *tctx)
+{
+ char **list = NULL;
+ str_list_add_printf(&list, "x=%d", 1);
+ torture_assert(tctx, list==NULL, "str_list_add_printf must keep NULL");
+ return true;
+}
+
+static bool test_list_add_printf(struct torture_context *tctx)
+{
+ const char *list2[] = { "foo", "bar=baz", NULL };
+ char **list = str_list_make_empty(tctx);
+ str_list_add_printf(&list, "foo");
+ str_list_add_printf(&list, "bar=%s", "baz");
+ torture_assert(
+ tctx,
+ str_list_equal((const char * const *)list, list2),
+ "str_list_add_printf failed");
+ TALLOC_FREE(list);
+ return true;
+}
+
+struct torture_suite *torture_local_util_strlist(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "strlist");
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(test_lists_shell_strings); i++) {
+ char *name;
+ name = talloc_asprintf(suite, "lists_shell(%s)",
+ test_lists_shell_strings[i].list_as_string);
+ torture_suite_add_simple_tcase_const(suite, name,
+ test_lists_shell, &test_lists_shell_strings[i]);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(test_lists_strings); i++) {
+ char *name;
+ name = talloc_asprintf(suite, "list_make(%s)",
+ test_lists_strings[i].list_as_string);
+ torture_suite_add_simple_tcase_const(suite, name,
+ test_list_make, &test_lists_strings[i]);
+ }
+
+ torture_suite_add_simple_test(suite, "list_copy", test_list_copy);
+ torture_suite_add_simple_test(suite, "make_empty", test_list_make_empty);
+ torture_suite_add_simple_test(suite, "make_single", test_list_make_single);
+ torture_suite_add_simple_test(suite, "list_copy_const", test_list_copy_const);
+ torture_suite_add_simple_test(suite, "list_length", test_list_length);
+ torture_suite_add_simple_test(suite, "list_add", test_list_add);
+ torture_suite_add_simple_test(suite, "list_add_const", test_list_add_const);
+ torture_suite_add_simple_test(suite, "list_remove", test_list_remove);
+ torture_suite_add_simple_test(suite, "list_check", test_list_check);
+ torture_suite_add_simple_test(suite, "list_check_ci", test_list_check_ci);
+ torture_suite_add_simple_test(suite, "list_unique", test_list_unique);
+ torture_suite_add_simple_test(suite, "list_unique_2", test_list_unique_2);
+ torture_suite_add_simple_test(suite, "list_append", test_list_append);
+ torture_suite_add_simple_test(suite, "list_append_const", test_list_append_const);
+ torture_suite_add_simple_test(
+ suite, "list_add_printf_NULL", test_list_add_printf_NULL);
+ torture_suite_add_simple_test(
+ suite, "list_add_printf", test_list_add_printf);
+ return suite;
+}
diff --git a/lib/util/tests/strv.c b/lib/util/tests/strv.c
new file mode 100644
index 0000000..c79ed5c
--- /dev/null
+++ b/lib/util/tests/strv.c
@@ -0,0 +1,201 @@
+/*
+ * Tests for strv
+ *
+ * Copyright Martin Schwenke <martin@meltin.net> 2016
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <talloc.h>
+
+#include "replace.h"
+
+#include "libcli/util/ntstatus.h"
+#include "torture/torture.h"
+#include "lib/util/data_blob.h"
+#include "torture/local/proto.h"
+
+#include "lib/util/strv.h"
+
+static bool test_strv_empty(struct torture_context *tctx)
+{
+ /* NULL strv contains 0 entries */
+ torture_assert_int_equal(tctx,
+ strv_count(NULL),
+ 0,
+ "strv_count() on NULL failed");
+
+ /* NULL strv has no next entry */
+ torture_assert(tctx,
+ strv_next(NULL, NULL) == NULL,
+ "strv_next() on NULL failed");
+
+ return true;
+}
+
+static bool test_strv_single(struct torture_context *tctx)
+{
+ const char *data = "foo";
+ char *strv = NULL;
+ char *t;
+ int ret;
+
+ /* Add an item */
+ ret = strv_add(tctx, &strv, data);
+ torture_assert(tctx, ret == 0, "strv_add() failed");
+
+ /* Is there 1 item? */
+ torture_assert_int_equal(tctx,
+ strv_count(strv), 1,
+ "strv_count() failed");
+
+ /* Is the expected item the first one? */
+ t = strv_next(strv, NULL);
+ torture_assert(tctx,
+ strcmp(t, data) == 0,
+ "strv_next() failed");
+
+ /* Can the expected item be found? */
+ t = strv_find(strv, data);
+ torture_assert(tctx,
+ strcmp(t, data) == 0,
+ "strv_next() failed");
+
+ /* Delete it */
+ strv_delete(&strv, t);
+
+ /* Should have no items */
+ torture_assert_int_equal(tctx,
+ strv_count(strv), 0,
+ "strv_count() failed");
+ return true;
+}
+
+static bool test_strv_multi(struct torture_context *tctx)
+{
+ const char *data[] = { "foo", "bar", "", "samba", "x"};
+ char *strv = NULL;
+ char *t;
+ int i, ret;
+ const int num = ARRAY_SIZE(data);
+
+ /* Add items */
+ for (i = 0; i < num; i++) {
+ ret = strv_add(tctx, &strv, data[i]);
+ torture_assert(tctx, ret == 0, "strv_add() failed");
+ }
+
+ torture_assert_int_equal(tctx,
+ strv_count(strv), num,
+ "strv_count() failed");
+
+ /* Check that strv_next() finds the expected values */
+ t = NULL;
+ for (i = 0; i < num; i++) {
+ t = strv_next(strv, t);
+ torture_assert(tctx,
+ strcmp(t, data[i]) == 0,
+ "strv_next() failed");
+ }
+
+
+ /* Check that strv_next() finds the expected values */
+ t = NULL;
+ for (i = 0; i < num; i++) {
+ t = strv_next(strv, t);
+ torture_assert(tctx,
+ strcmp(t, data[i]) == 0,
+ "strv_next() failed");
+ }
+
+ /* Find each item, delete it, check count */
+ for (i = 0; i < num; i++) {
+ t = strv_find(strv, data[i]);
+ torture_assert(tctx,
+ strcmp(t, data[i]) == 0,
+ "strv_next() failed");
+ strv_delete(&strv, t);
+ torture_assert_int_equal(tctx,
+ strv_count(strv), num - i - 1,
+ "strv_delete() failed");
+ }
+
+ /* Add items */
+ for (i = 0; i < num; i++) {
+ ret = strv_add(tctx, &strv, data[i]);
+ torture_assert(tctx, ret == 0, "strv_add() failed");
+ }
+
+ torture_assert_int_equal(tctx,
+ strv_count(strv), num,
+ "strv_count() failed");
+
+ /* Find items in reverse, delete, check count */
+ for (i = num - 1; i >= 0; i--) {
+ t = strv_find(strv, data[i]);
+ torture_assert(tctx,
+ strcmp(t, data[i]) == 0,
+ "strv_next() failed");
+ strv_delete(&strv, t);
+ torture_assert_int_equal(tctx,
+ strv_count(strv), i,
+ "strv_delete() failed");
+ }
+
+ return true;
+}
+
+/* Similar to above but only add/check first 2 chars of each string */
+static bool test_strv_addn(struct torture_context *tctx)
+{
+ const char *data[] = { "foo", "bar", "samba" };
+ char *strv = NULL;
+ char *t;
+ int i, ret;
+ const int num = ARRAY_SIZE(data);
+
+ /* Add first 2 chars of each item */
+ for (i = 0; i < num; i++) {
+ ret = strv_addn(tctx, &strv, data[i], 2);
+ torture_assert(tctx, ret == 0, "strv_add() failed");
+ }
+
+ torture_assert_int_equal(tctx,
+ strv_count(strv), num,
+ "strv_count() failed");
+
+ /* Check that strv_next() finds the expected values */
+ t = NULL;
+ for (i = 0; i < num; i++) {
+ t = strv_next(strv, t);
+ torture_assert(tctx,
+ strncmp(t, data[i], 2) == 0,
+ "strv_next() failed");
+ }
+
+ return true;
+}
+
+struct torture_suite *torture_local_util_strv(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "strv");
+
+ torture_suite_add_simple_test(suite, "strv_empty", test_strv_empty);
+ torture_suite_add_simple_test(suite, "strv_single", test_strv_single);
+ torture_suite_add_simple_test(suite, "strv_multi", test_strv_multi);
+ torture_suite_add_simple_test(suite, "strv_addn", test_strv_addn);
+
+ return suite;
+}
diff --git a/lib/util/tests/strv_util.c b/lib/util/tests/strv_util.c
new file mode 100644
index 0000000..b1496c7
--- /dev/null
+++ b/lib/util/tests/strv_util.c
@@ -0,0 +1,150 @@
+/*
+ * Tests for strv_util
+ *
+ * Copyright Martin Schwenke <martin@meltin.net> 2016
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <talloc.h>
+
+#include "replace.h"
+
+#include "libcli/util/ntstatus.h"
+#include "torture/torture.h"
+#include "lib/util/data_blob.h"
+#include "torture/local/proto.h"
+
+#include "lib/util/strv.h"
+#include "lib/util/strv_util.h"
+
+static bool test_strv_split_none(struct torture_context *tctx)
+{
+ char *strv = NULL;
+ int ret;
+
+ /* NULL has 0 entries */
+ ret = strv_split(tctx, &strv, NULL, " ");
+ torture_assert(tctx, ret == 0, "strv_split() on NULL failed");
+ torture_assert_int_equal(tctx,
+ strv_count(strv),
+ 0,
+ "strv_split() on NULL failed");
+ TALLOC_FREE(strv);
+
+ /* Empty string has 0 entries */
+ ret = strv_split(tctx, &strv, "", " ");
+ torture_assert(tctx, ret == 0, "strv_split() on NULL failed");
+ torture_assert_int_equal(tctx,
+ strv_count(strv),
+ 0,
+ "strv_split() on \"\" failed");
+ TALLOC_FREE(strv);
+
+ /* String containing only separators has 0 entries */
+ ret = strv_split(tctx, &strv, "abcabcabc", "cba ");
+ torture_assert(tctx, ret == 0, "strv_split() on NULL failed");
+ torture_assert_int_equal(tctx,
+ strv_count(strv),
+ 0,
+ "strv_split() on seps-only failed");
+ TALLOC_FREE(strv);
+
+ return true;
+}
+
+struct test_str_split_data {
+ const char *in;
+ const char *sep;
+ const char *out[10]; /* Hardcoded maximum! */
+};
+
+static bool test_strv_split_some(struct torture_context *tctx)
+{
+ const struct test_str_split_data data[] = {
+ {
+ /* Single string */
+ .in = "foo",
+ .sep = " \t",
+ .out = { "foo" }
+ },
+ {
+ /* Single string, single leading separator */
+ .in = " foo",
+ .sep = " \t",
+ .out = { "foo" }
+ },
+ {
+ /* Single string, single trailing separator */
+ .in = " foo",
+ .sep = " \t",
+ .out = { "foo" }
+ },
+ {
+ /* Single string, lots of separators */
+ .in = " \t foo\t ",
+ .sep = " \t",
+ .out = { "foo" }
+ },
+ {
+ /* Multiple strings, many separators */
+ .in = " \t foo bar\t\tx\t samba\t ",
+ .sep = " \t",
+ .out = { "foo", "bar", "x", "samba" }
+ },
+ };
+ const char *t;
+ char *strv = NULL;
+ size_t j;
+
+ for (j = 0; j < ARRAY_SIZE(data); j++) {
+ size_t i, num;
+ int ret;
+ const struct test_str_split_data *d = &data[j];
+
+ num = 0;
+ while (num < ARRAY_SIZE(d->out) && d->out[num] != NULL) {
+ num++;
+ }
+ ret = strv_split(tctx, &strv, d->in, d->sep);
+ torture_assert(tctx, ret == 0, "strv_split() on NULL failed");
+ torture_assert_int_equal(tctx,
+ strv_count(strv),
+ num,
+ "strv_split() failed");
+ t = NULL;
+ for (i = 0; i < num; i++) {
+ t = strv_next(strv, t);
+ torture_assert(tctx,
+ strcmp(t, d->out[i]) == 0,
+ "strv_split() failed");
+ }
+ TALLOC_FREE(strv);
+ }
+ return true;
+}
+
+struct torture_suite *torture_local_util_strv_util(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite =
+ torture_suite_create(mem_ctx, "strv_util");
+
+ torture_suite_add_simple_test(suite,
+ "strv_split_none",
+ test_strv_split_none);
+ torture_suite_add_simple_test(suite,
+ "strv_split_some",
+ test_strv_split_some);
+ return suite;
+}
diff --git a/lib/util/tests/test_bytearray.c b/lib/util/tests/test_bytearray.c
new file mode 100644
index 0000000..fcf63d8
--- /dev/null
+++ b/lib/util/tests/test_bytearray.c
@@ -0,0 +1,435 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2018-2019 Andreas Schneider <asn@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "lib/replace/replace.h"
+#include "lib/util/bytearray.h"
+
+static void torture_pull_le_u8(void **state)
+{
+ uint8_t data[2] = {0};
+ uint8_t result;
+
+ (void)state;
+
+ result = PULL_LE_U8(data, 0);
+ assert_int_equal(result, 0);
+
+ data[0] = 0x2a;
+ result = PULL_LE_U8(data, 0);
+ assert_int_equal(result, 42);
+
+
+ data[0] = 0xf;
+ result = PULL_LE_U8(data, 0);
+ assert_int_equal(result, 0xf);
+
+ data[0] = 0xff;
+ result = PULL_LE_U8(data, 0);
+ assert_int_equal(result, 0xff);
+
+ data[1] = 0x2a;
+ result = PULL_LE_U8(data, 1);
+ assert_int_equal(result, 42);
+}
+
+static void torture_pull_le_u16(void **state)
+{
+ uint8_t data[2] = {0, 0};
+ uint16_t result;
+
+ (void)state;
+
+ result = PULL_LE_U16(data, 0);
+ assert_int_equal(result, 0);
+
+ data[0] = 0x2a;
+ data[1] = 0x00;
+ result = PULL_LE_U16(data, 0);
+ assert_int_equal(result, 42);
+
+ data[0] = 0xff;
+ data[1] = 0x00;
+ result = PULL_LE_U16(data, 0);
+ assert_int_equal(result, 0x00ff);
+
+ data[0] = 0x00;
+ data[1] = 0xff;
+ result = PULL_LE_U16(data, 0);
+ assert_int_equal(result, 0xff00);
+
+ data[0] = 0xff;
+ data[1] = 0xff;
+ result = PULL_LE_U16(data, 0);
+ assert_int_equal(result, 0xffff);
+}
+
+static void torture_pull_le_u32(void **state)
+{
+ uint8_t data[4] = {0, 0, 0, 0};
+ uint32_t result;
+
+ (void)state;
+
+ result = PULL_LE_U32(data, 0);
+ assert_int_equal(result, 0);
+
+ data[0] = 0x2a;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ result = PULL_LE_U32(data, 0);
+ assert_int_equal(result, 42);
+
+ data[0] = 0xff;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ result = PULL_LE_U32(data, 0);
+ assert_int_equal(result, 0x00ff);
+
+ data[0] = 0x00;
+ data[1] = 0xff;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ result = PULL_LE_U32(data, 0);
+ assert_int_equal(result, 0xff00);
+
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0xff;
+ data[3] = 0x00;
+ result = PULL_LE_U32(data, 0);
+ assert_int_equal(result, 0xff0000);
+
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0xff;
+ result = PULL_LE_U32(data, 0);
+ assert_int_equal(result, 0xff000000);
+
+ data[0] = 0xff;
+ data[1] = 0xff;
+ data[2] = 0xff;
+ data[3] = 0xff;
+ result = PULL_LE_U32(data, 0);
+ assert_int_equal(result, 0xffffffff);
+}
+
+static void torture_push_le_u8(void **state)
+{
+ uint8_t data[4] = {0, 0, 0, 0};
+ uint8_t data2[4] = {42, 42, 42, 42};
+
+ (void)state;
+
+ PUSH_LE_U8(data, 0, 42);
+ PUSH_LE_U8(data, 1, 42);
+ PUSH_LE_U8(data, 2, 42);
+ PUSH_LE_U8(data, 3, 42);
+ assert_memory_equal(data, data2, sizeof(data));
+}
+
+static void torture_push_le_u16(void **state)
+{
+ uint8_t data[4] = {0, 0, 0, 0};
+ uint8_t data2[4] = {0xa6, 0x7f, 0x2a, 0x00};
+ uint16_t result;
+
+ (void)state;
+
+ PUSH_LE_U16(data, 0, 32678);
+ PUSH_LE_U16(data, 2, 42);
+ assert_memory_equal(data, data2, sizeof(data));
+
+ result = PULL_LE_U16(data, 2);
+ assert_int_equal(result, 42);
+
+ result = PULL_LE_U16(data, 0);
+ assert_int_equal(result, 32678);
+}
+
+static void torture_push_le_u32(void **state)
+{
+ uint8_t data[8] = {0};
+ uint8_t data2[8] = {0xa6, 0x7f, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00};
+ uint32_t result;
+
+ (void)state;
+
+ PUSH_LE_U32(data, 0, 32678);
+ PUSH_LE_U32(data, 4, 42);
+ assert_memory_equal(data, data2, sizeof(data));
+
+ result = PULL_LE_U32(data, 4);
+ assert_int_equal(result, 42);
+
+ result = PULL_LE_U32(data, 0);
+ assert_int_equal(result, 32678);
+
+ PUSH_LE_U32(data, 0, 0xfffefffe);
+ result = PULL_LE_U32(data, 0);
+ assert_int_equal(result, 0xfffefffe);
+}
+
+static void torture_push_le_u64(void **state)
+{
+ uint8_t data[16] = {0};
+ uint64_t result;
+
+ (void)state;
+
+ PUSH_LE_U64(data, 0, 32678);
+
+ result = PULL_LE_U64(data, 0);
+ assert_int_equal(result, 32678);
+
+ PUSH_LE_U64(data, 0, 0xfffefffefffefffeUL);
+
+ result = PULL_LE_U64(data, 0);
+ assert_int_equal(result, 0xfffefffefffefffeUL);
+}
+
+/****************** BIG ENDIAN ********************/
+
+static void torture_pull_be_u8(void **state)
+{
+ uint8_t data[2] = {0};
+ uint8_t result;
+
+ (void)state;
+
+ result = PULL_BE_U8(data, 0);
+ assert_int_equal(result, 0);
+
+ data[0] = 0x2a;
+ result = PULL_BE_U8(data, 0);
+ assert_int_equal(result, 42);
+
+
+ data[0] = 0xf;
+ result = PULL_BE_U8(data, 0);
+ assert_int_equal(result, 0xf);
+
+ data[0] = 0xff;
+ result = PULL_BE_U8(data, 0);
+ assert_int_equal(result, 0xff);
+
+ data[1] = 0x2a;
+ result = PULL_BE_U8(data, 1);
+ assert_int_equal(result, 42);
+}
+
+static void torture_pull_be_u16(void **state)
+{
+ uint8_t data[2] = {0, 0};
+ uint16_t result;
+
+ (void)state;
+
+ result = PULL_BE_U16(data, 0);
+ assert_int_equal(result, 0);
+
+ data[0] = 0x00;
+ data[1] = 0x2a;
+ result = PULL_BE_U16(data, 0);
+ assert_int_equal(result, 42);
+
+ data[0] = 0x00;
+ data[1] = 0xff;
+ result = PULL_BE_U16(data, 0);
+ assert_int_equal(result, 0x00ff);
+
+ data[0] = 0xff;
+ data[1] = 0x00;
+ result = PULL_BE_U16(data, 0);
+ assert_int_equal(result, 0xff00);
+
+ data[0] = 0xff;
+ data[1] = 0xff;
+ result = PULL_BE_U16(data, 0);
+ assert_int_equal(result, 0xffff);
+}
+
+static void torture_pull_be_u32(void **state)
+{
+ uint8_t data[4] = {0, 0, 0, 0};
+ uint32_t result;
+
+ (void)state;
+
+ result = PULL_BE_U32(data, 0);
+ assert_int_equal(result, 0);
+
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0x2a;
+ result = PULL_BE_U32(data, 0);
+ assert_int_equal(result, 42);
+
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0xff;
+ result = PULL_BE_U32(data, 0);
+ assert_int_equal(result, 0x00ff);
+
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0xff;
+ data[3] = 0x00;
+ result = PULL_BE_U32(data, 0);
+ assert_int_equal(result, 0xff00);
+
+ data[0] = 0x00;
+ data[1] = 0xff;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ result = PULL_BE_U32(data, 0);
+ assert_int_equal(result, 0xff0000);
+
+ data[0] = 0xff;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ result = PULL_BE_U32(data, 0);
+ assert_int_equal(result, 0xff000000);
+
+ data[0] = 0xff;
+ data[1] = 0xff;
+ data[2] = 0xff;
+ data[3] = 0xff;
+ result = PULL_BE_U32(data, 0);
+ assert_int_equal(result, 0xffffffff);
+}
+
+static void torture_push_be_u8(void **state)
+{
+ uint8_t data[4] = {0, 0, 0, 0};
+ uint8_t data2[4] = {42, 42, 42, 42};
+
+ (void)state;
+
+ PUSH_BE_U8(data, 0, 42);
+ PUSH_BE_U8(data, 1, 42);
+ PUSH_BE_U8(data, 2, 42);
+ PUSH_BE_U8(data, 3, 42);
+ assert_memory_equal(data, data2, sizeof(data));
+}
+
+static void torture_push_be_u16(void **state)
+{
+ uint8_t data[4] = {0, 0, 0, 0};
+ uint8_t data2[4] = {0x7f, 0xa6, 0x00, 0x2a};
+ uint16_t result;
+
+ (void)state;
+
+ PUSH_BE_U16(data, 0, 32678);
+ PUSH_BE_U16(data, 2, 42);
+ assert_memory_equal(data, data2, sizeof(data));
+
+ result = PULL_BE_U16(data, 2);
+ assert_int_equal(result, 42);
+
+ result = PULL_BE_U16(data, 0);
+ assert_int_equal(result, 32678);
+}
+
+static void torture_push_be_u32(void **state)
+{
+ uint8_t data[8] = {0};
+ uint8_t data2[8] = {0x00, 0x00, 0x7f, 0xa6, 0x00, 0x00, 0x00, 0x2a};
+ uint32_t result;
+
+ (void)state;
+
+ PUSH_BE_U32(data, 0, 32678);
+ PUSH_BE_U32(data, 4, 42);
+ assert_memory_equal(data, data2, sizeof(data));
+
+ result = PULL_BE_U32(data, 4);
+ assert_int_equal(result, 42);
+
+ result = PULL_BE_U32(data, 0);
+ assert_int_equal(result, 32678);
+
+ PUSH_BE_U32(data, 0, 0xfffefffe);
+ result = PULL_BE_U32(data, 0);
+ assert_int_equal(result, 0xfffefffe);
+}
+
+static void torture_push_be_u64(void **state)
+{
+ uint8_t data[16] = {0};
+ uint64_t result;
+
+ (void)state;
+
+ PUSH_BE_U64(data, 0, 32678);
+
+ result = PULL_BE_U64(data, 0);
+ assert_int_equal(result, 32678);
+
+ PUSH_LE_U64(data, 8, 0xfffefffe);
+
+ result = PULL_LE_U64(data, 8);
+ assert_int_equal(result, 0xfffefffe);
+}
+
+int main(int argc, char *argv[])
+{
+ int rc;
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(torture_pull_le_u8),
+ cmocka_unit_test(torture_pull_le_u16),
+ cmocka_unit_test(torture_pull_le_u32),
+
+ cmocka_unit_test(torture_push_le_u8),
+ cmocka_unit_test(torture_push_le_u16),
+ cmocka_unit_test(torture_push_le_u32),
+ cmocka_unit_test(torture_push_le_u64),
+
+ /* BIG ENDIAN */
+ cmocka_unit_test(torture_pull_be_u8),
+ cmocka_unit_test(torture_pull_be_u16),
+ cmocka_unit_test(torture_pull_be_u32),
+
+ cmocka_unit_test(torture_push_be_u8),
+ cmocka_unit_test(torture_push_be_u16),
+ cmocka_unit_test(torture_push_be_u32),
+ cmocka_unit_test(torture_push_be_u64),
+ };
+
+ if (argc == 2) {
+ cmocka_set_test_filter(argv[1]);
+ }
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+ rc = cmocka_run_group_tests(tests, NULL, NULL);
+
+ return rc;
+}
diff --git a/lib/util/tests/test_byteorder.c b/lib/util/tests/test_byteorder.c
new file mode 100644
index 0000000..9faa038
--- /dev/null
+++ b/lib/util/tests/test_byteorder.c
@@ -0,0 +1,435 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2018-2019 Andreas Schneider <asn@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "lib/replace/replace.h"
+#include "lib/util/byteorder.h"
+
+static void torture_pull_le_u8(void **state)
+{
+ uint8_t data[2] = {0};
+ uint8_t result;
+
+ (void)state;
+
+ result = CVAL(data, 0);
+ assert_int_equal(result, 0);
+
+ data[0] = 0x2a;
+ result = CVAL(data, 0);
+ assert_int_equal(result, 42);
+
+
+ data[0] = 0xf;
+ result = CVAL(data, 0);
+ assert_int_equal(result, 0xf);
+
+ data[0] = 0xff;
+ result = CVAL(data, 0);
+ assert_int_equal(result, 0xff);
+
+ data[1] = 0x2a;
+ result = CVAL(data, 1);
+ assert_int_equal(result, 42);
+}
+
+static void torture_pull_le_u16(void **state)
+{
+ uint8_t data[2] = {0, 0};
+ uint16_t result;
+
+ (void)state;
+
+ result = SVAL(data, 0);
+ assert_int_equal(result, 0);
+
+ data[0] = 0x2a;
+ data[1] = 0x00;
+ result = SVAL(data, 0);
+ assert_int_equal(result, 42);
+
+ data[0] = 0xff;
+ data[1] = 0x00;
+ result = SVAL(data, 0);
+ assert_int_equal(result, 0x00ff);
+
+ data[0] = 0x00;
+ data[1] = 0xff;
+ result = SVAL(data, 0);
+ assert_int_equal(result, 0xff00);
+
+ data[0] = 0xff;
+ data[1] = 0xff;
+ result = SVAL(data, 0);
+ assert_int_equal(result, 0xffff);
+}
+
+static void torture_pull_le_u32(void **state)
+{
+ uint8_t data[4] = {0, 0, 0, 0};
+ uint32_t result;
+
+ (void)state;
+
+ result = IVAL(data, 0);
+ assert_int_equal(result, 0);
+
+ data[0] = 0x2a;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ result = IVAL(data, 0);
+ assert_int_equal(result, 42);
+
+ data[0] = 0xff;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ result = IVAL(data, 0);
+ assert_int_equal(result, 0x00ff);
+
+ data[0] = 0x00;
+ data[1] = 0xff;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ result = IVAL(data, 0);
+ assert_int_equal(result, 0xff00);
+
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0xff;
+ data[3] = 0x00;
+ result = IVAL(data, 0);
+ assert_int_equal(result, 0xff0000);
+
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0xff;
+ result = IVAL(data, 0);
+ assert_int_equal(result, 0xff000000);
+
+ data[0] = 0xff;
+ data[1] = 0xff;
+ data[2] = 0xff;
+ data[3] = 0xff;
+ result = IVAL(data, 0);
+ assert_int_equal(result, 0xffffffff);
+}
+
+static void torture_push_le_u8(void **state)
+{
+ uint8_t data[4] = {0, 0, 0, 0};
+ uint8_t data2[4] = {42, 42, 42, 42};
+
+ (void)state;
+
+ SCVAL(data, 0, 42);
+ SCVAL(data, 1, 42);
+ SCVAL(data, 2, 42);
+ SCVAL(data, 3, 42);
+ assert_memory_equal(data, data2, sizeof(data));
+}
+
+static void torture_push_le_u16(void **state)
+{
+ uint8_t data[4] = {0, 0, 0, 0};
+ uint8_t data2[4] = {0xa6, 0x7f, 0x2a, 0x00};
+ uint16_t result;
+
+ (void)state;
+
+ SSVALX(data, 0, 32678);
+ SSVALX(data, 2, 42);
+ assert_memory_equal(data, data2, sizeof(data));
+
+ result = SVAL(data, 2);
+ assert_int_equal(result, 42);
+
+ result = SVAL(data, 0);
+ assert_int_equal(result, 32678);
+}
+
+static void torture_push_le_u32(void **state)
+{
+ uint8_t data[8] = {0};
+ uint8_t data2[8] = {0xa6, 0x7f, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00};
+ uint32_t result;
+
+ (void)state;
+
+ SIVALX(data, 0, 32678);
+ SIVALX(data, 4, 42);
+ assert_memory_equal(data, data2, sizeof(data));
+
+ result = IVAL(data, 4);
+ assert_int_equal(result, 42);
+
+ result = IVAL(data, 0);
+ assert_int_equal(result, 32678);
+
+ SIVALX(data, 0, 0xfffefffe);
+ result = IVAL(data, 0);
+ assert_int_equal(result, 0xfffefffe);
+}
+
+static void torture_push_le_u64(void **state)
+{
+ uint8_t data[16] = {0};
+ uint64_t result;
+
+ (void)state;
+
+ SBVAL(data, 0, 32678);
+
+ result = BVAL(data, 0);
+ assert_int_equal(result, 32678);
+
+ SBVAL(data, 0, 0xfffefffefffefffeUL);
+
+ result = BVAL(data, 0);
+ assert_int_equal(result, 0xfffefffefffefffeUL);
+}
+
+/****************** BIG ENDIAN ********************/
+
+static void torture_pull_be_u8(void **state)
+{
+ uint8_t data[2] = {0};
+ uint8_t result;
+
+ (void)state;
+
+ result = CVAL(data, 0);
+ assert_int_equal(result, 0);
+
+ data[0] = 0x2a;
+ result = CVAL(data, 0);
+ assert_int_equal(result, 42);
+
+
+ data[0] = 0xf;
+ result = CVAL(data, 0);
+ assert_int_equal(result, 0xf);
+
+ data[0] = 0xff;
+ result = CVAL(data, 0);
+ assert_int_equal(result, 0xff);
+
+ data[1] = 0x2a;
+ result = CVAL(data, 1);
+ assert_int_equal(result, 42);
+}
+
+static void torture_pull_be_u16(void **state)
+{
+ uint8_t data[2] = {0, 0};
+ uint16_t result;
+
+ (void)state;
+
+ result = RSVAL(data, 0);
+ assert_int_equal(result, 0);
+
+ data[0] = 0x00;
+ data[1] = 0x2a;
+ result = RSVAL(data, 0);
+ assert_int_equal(result, 42);
+
+ data[0] = 0x00;
+ data[1] = 0xff;
+ result = RSVAL(data, 0);
+ assert_int_equal(result, 0x00ff);
+
+ data[0] = 0xff;
+ data[1] = 0x00;
+ result = RSVAL(data, 0);
+ assert_int_equal(result, 0xff00);
+
+ data[0] = 0xff;
+ data[1] = 0xff;
+ result = RSVAL(data, 0);
+ assert_int_equal(result, 0xffff);
+}
+
+static void torture_pull_be_u32(void **state)
+{
+ uint8_t data[4] = {0, 0, 0, 0};
+ uint32_t result;
+
+ (void)state;
+
+ result = RIVAL(data, 0);
+ assert_int_equal(result, 0);
+
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0x2a;
+ result = RIVAL(data, 0);
+ assert_int_equal(result, 42);
+
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0xff;
+ result = RIVAL(data, 0);
+ assert_int_equal(result, 0x00ff);
+
+ data[0] = 0x00;
+ data[1] = 0x00;
+ data[2] = 0xff;
+ data[3] = 0x00;
+ result = RIVAL(data, 0);
+ assert_int_equal(result, 0xff00);
+
+ data[0] = 0x00;
+ data[1] = 0xff;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ result = RIVAL(data, 0);
+ assert_int_equal(result, 0xff0000);
+
+ data[0] = 0xff;
+ data[1] = 0x00;
+ data[2] = 0x00;
+ data[3] = 0x00;
+ result = RIVAL(data, 0);
+ assert_int_equal(result, 0xff000000);
+
+ data[0] = 0xff;
+ data[1] = 0xff;
+ data[2] = 0xff;
+ data[3] = 0xff;
+ result = RIVAL(data, 0);
+ assert_int_equal(result, 0xffffffff);
+}
+
+static void torture_push_be_u8(void **state)
+{
+ uint8_t data[4] = {0, 0, 0, 0};
+ uint8_t data2[4] = {42, 42, 42, 42};
+
+ (void)state;
+
+ SCVAL(data, 0, 42);
+ SCVAL(data, 1, 42);
+ SCVAL(data, 2, 42);
+ SCVAL(data, 3, 42);
+ assert_memory_equal(data, data2, sizeof(data));
+}
+
+static void torture_push_be_u16(void **state)
+{
+ uint8_t data[4] = {0, 0, 0, 0};
+ uint8_t data2[4] = {0x7f, 0xa6, 0x00, 0x2a};
+ uint16_t result;
+
+ (void)state;
+
+ RSSVALS(data, 0, 32678);
+ RSSVALS(data, 2, 42);
+ assert_memory_equal(data, data2, sizeof(data));
+
+ result = RSVAL(data, 2);
+ assert_int_equal(result, 42);
+
+ result = RSVAL(data, 0);
+ assert_int_equal(result, 32678);
+}
+
+static void torture_push_be_u32(void **state)
+{
+ uint8_t data[8] = {0};
+ uint8_t data2[8] = {0x00, 0x00, 0x7f, 0xa6, 0x00, 0x00, 0x00, 0x2a};
+ uint32_t result;
+
+ (void)state;
+
+ RSIVALS(data, 0, 32678);
+ RSIVALS(data, 4, 42);
+ assert_memory_equal(data, data2, sizeof(data));
+
+ result = RIVAL(data, 4);
+ assert_int_equal(result, 42);
+
+ result = RIVAL(data, 0);
+ assert_int_equal(result, 32678);
+
+ RSIVALS(data, 0, 0xfffefffe);
+ result = RIVAL(data, 0);
+ assert_int_equal(result, 0xfffefffe);
+}
+
+static void torture_push_be_u64(void **state)
+{
+ uint8_t data[16] = {0};
+ uint64_t result;
+
+ (void)state;
+
+ RSBVALS(data, 0, 32678);
+
+ result = RBVAL(data, 0);
+ assert_int_equal(result, 32678);
+
+ SBVAL(data, 8, 0xfffefffe);
+
+ result = BVAL(data, 8);
+ assert_int_equal(result, 0xfffefffe);
+}
+
+int main(int argc, char *argv[])
+{
+ int rc;
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(torture_pull_le_u8),
+ cmocka_unit_test(torture_pull_le_u16),
+ cmocka_unit_test(torture_pull_le_u32),
+
+ cmocka_unit_test(torture_push_le_u8),
+ cmocka_unit_test(torture_push_le_u16),
+ cmocka_unit_test(torture_push_le_u32),
+ cmocka_unit_test(torture_push_le_u64),
+
+ /* BIG ENDIAN */
+ cmocka_unit_test(torture_pull_be_u8),
+ cmocka_unit_test(torture_pull_be_u16),
+ cmocka_unit_test(torture_pull_be_u32),
+
+ cmocka_unit_test(torture_push_be_u8),
+ cmocka_unit_test(torture_push_be_u16),
+ cmocka_unit_test(torture_push_be_u32),
+ cmocka_unit_test(torture_push_be_u64),
+ };
+
+ if (argc == 2) {
+ cmocka_set_test_filter(argv[1]);
+ }
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+ rc = cmocka_run_group_tests(tests, NULL, NULL);
+
+ return rc;
+}
diff --git a/lib/util/tests/test_byteorder_verify.c b/lib/util/tests/test_byteorder_verify.c
new file mode 100644
index 0000000..a18ddad
--- /dev/null
+++ b/lib/util/tests/test_byteorder_verify.c
@@ -0,0 +1,273 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2018-2019 Andreas Schneider <asn@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "lib/replace/replace.h"
+#include "lib/util/bytearray.h"
+#include "lib/util/byteorder.h"
+
+static void torture_le_u8(void **state)
+{
+ uint8_t data[2] = {0};
+ uint8_t result;
+
+ (void)state;
+
+ /* Test CVAL and SCVAL */
+ PUSH_LE_U8(data, 0, 23);
+ PUSH_LE_U8(data, 1, 42);
+
+ result = CVAL(data, 0);
+ assert_int_equal(result, 23);
+
+ result = CVAL(data, 1);
+ assert_int_equal(result, 42);
+
+ /* Test CVAL_NC and PVAL */
+ PUSH_LE_U8(data, 0, 23);
+ PUSH_LE_U8(data, 1, 42);
+
+ result = CVAL_NC(data, 0);
+ assert_int_equal(result, 23);
+
+ result = PVAL(data, 1);
+ assert_int_equal(result, 42);
+
+ /* Test SCVAL */
+ SCVAL(data, 0, 42);
+ SCVAL(data, 1, 23);
+
+ result = PULL_LE_U8(data, 0);
+ assert_int_equal(result, 42);
+
+ result = PULL_LE_U8(data, 1);
+ assert_int_equal(result, 23);
+}
+
+static void torture_le_u16(void **state)
+{
+ uint8_t data[2] = {0};
+ uint16_t result;
+
+ (void)state;
+
+ /* Test SVAL */
+ PUSH_LE_U16(data, 0, 0xff00);
+ result = SVAL(data, 0);
+ assert_int_equal(result, 0xff00);
+
+ /* Test SSVAL */
+ SSVAL(data, 0, 0x00ff);
+ result = PULL_LE_U16(data, 0);
+ assert_int_equal(result, 0x00ff);
+
+ /* Test SSVALX */
+ SSVALX(data, 0, 0x00fa);
+ result = PULL_LE_U16(data, 0);
+ assert_int_equal(result, 0x00fa);
+
+ /* Test SSVALS */
+ SSVALS(data, 0, 0x00fb);
+ result = PULL_LE_U16(data, 0);
+ assert_int_equal(result, 0x00fb);
+}
+
+static void torture_le_u32(void **state)
+{
+ uint8_t data[4] = {0};
+ uint32_t result;
+
+ (void)state;
+
+ /* Test IVAL */
+ PUSH_LE_U32(data, 0, 0xff000000);
+ result = IVAL(data, 0);
+ assert_int_equal(result, 0xff000000);
+
+ /* Test SIVAL */
+ SIVAL(data, 0, 0xffaabbcc);
+ result = PULL_LE_U32(data, 0);
+ assert_int_equal(result, 0xffaabbcc);
+
+ /* Test SIVALX */
+ SIVALX(data, 0, 0xffbbccdd);
+ result = PULL_LE_U32(data, 0);
+ assert_int_equal(result, 0xffbbccdd);
+
+ /* Test SIVALS */
+ SIVALS(data, 0, 0xffccddee);
+ result = PULL_LE_U32(data, 0);
+ assert_int_equal(result, 0xffccddee);
+}
+
+static void torture_le_u64(void **state)
+{
+ uint8_t data[8] = {0};
+ uint64_t result;
+
+ (void)state;
+
+ PUSH_LE_U64(data, 0, 0xfffefffefffefffeUL);
+ result = BVAL(data, 0);
+ assert_int_equal(result, 0xfffefffefffefffeUL);
+
+ SBVAL(data, 0, 0xfffafffafffafffaUL);
+ result = PULL_LE_U64(data, 0);
+ assert_int_equal(result, 0xfffafffafffafffaUL);
+}
+
+static void torture_be_u8(void **state)
+{
+ uint8_t data[2] = {0};
+ uint8_t result;
+
+ (void)state;
+
+ PUSH_BE_U8(data, 0, 23);
+ PUSH_BE_U8(data, 1, 42);
+
+ result = CVAL(data, 0);
+ assert_int_equal(result, 23);
+
+ result = CVAL(data, 1);
+ assert_int_equal(result, 42);
+
+ SCVAL(data, 0, 42);
+ SCVAL(data, 1, 23);
+
+ result = PULL_BE_U8(data, 0);
+ assert_int_equal(result, 42);
+
+ result = PULL_BE_U8(data, 1);
+ assert_int_equal(result, 23);
+}
+
+static void torture_be_u16(void **state)
+{
+ uint8_t data[2] = {0};
+ uint16_t result;
+
+ (void)state;
+
+ /* Test RSVAL */
+ PUSH_BE_U16(data, 0, 0xff00);
+ result = RSVAL(data, 0);
+ assert_int_equal(result, 0xff00);
+
+ /* Test RSVALS */
+ PUSH_BE_U16(data, 0, 0xffaa);
+ result = RSVALS(data, 0);
+ assert_int_equal(result, 0xffaa);
+
+ /* Test RSSVAL */
+ RSSVAL(data, 0, 0x00ff);
+ result = PULL_BE_U16(data, 0);
+ assert_int_equal(result, 0x00ff);
+
+ /* Test RSSVALS */
+ RSSVALS(data, 0, 0x00fa);
+ result = PULL_BE_U16(data, 0);
+ assert_int_equal(result, 0x00fa);
+}
+
+static void torture_be_u32(void **state)
+{
+ uint8_t data[4] = {0};
+ uint32_t result;
+
+ (void)state;
+
+ /* Test RIVAL */
+ PUSH_BE_U32(data, 0, 0xff000000);
+ result = RIVAL(data, 0);
+ assert_int_equal(result, 0xff000000);
+
+ /* Test RIVALS */
+ PUSH_BE_U32(data, 0, 0xff0000aa);
+ result = RIVALS(data, 0);
+ assert_int_equal(result, 0xff0000aa);
+
+ /* Test RSIVAL */
+ RSIVAL(data, 0, 0xffeeddcc);
+ result = PULL_BE_U32(data, 0);
+ assert_int_equal(result, 0xffeeddcc);
+
+ /* Test RSIVALS */
+ RSIVALS(data, 0, 0xffaaddcc);
+ result = PULL_BE_U32(data, 0);
+ assert_int_equal(result, 0xffaaddcc);
+}
+
+static void torture_be_u64(void **state)
+{
+ uint8_t data[8] = {0};
+ uint64_t result;
+
+ (void)state;
+
+ /* Test RBVAL */
+ PUSH_BE_U64(data, 0, 0xfffefffefffefffeUL);
+ result = RBVAL(data, 0);
+ assert_int_equal(result, 0xfffefffefffefffeUL);
+
+ /* Test RBVALS */
+ PUSH_BE_U64(data, 0, 0xfffafffafffafffaUL);
+ result = RBVALS(data, 0);
+ assert_int_equal(result, 0xfffafffafffafffaUL);
+
+ /* Test RSBVAL */
+ RSBVAL(data, 0, 0xfffbfffbfffbfffbUL);
+ result = PULL_BE_U64(data, 0);
+ assert_int_equal(result, 0xfffbfffbfffbfffbUL);
+
+ /* Test RSBVALS */
+ RSBVALS(data, 0, 0xfffcfffcfffcfffcUL);
+ result = PULL_BE_U64(data, 0);
+ assert_int_equal(result, 0xfffcfffcfffcfffcUL);
+}
+
+int main(int argc, char *argv[])
+{
+ int rc;
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(torture_le_u8),
+ cmocka_unit_test(torture_le_u16),
+ cmocka_unit_test(torture_le_u32),
+ cmocka_unit_test(torture_le_u64),
+
+ cmocka_unit_test(torture_be_u8),
+ cmocka_unit_test(torture_be_u16),
+ cmocka_unit_test(torture_be_u32),
+ cmocka_unit_test(torture_be_u64),
+ };
+
+ if (argc == 2) {
+ cmocka_set_test_filter(argv[1]);
+ }
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+ rc = cmocka_run_group_tests(tests, NULL, NULL);
+
+ return rc;
+}
diff --git a/lib/util/tests/test_logging.c b/lib/util/tests/test_logging.c
new file mode 100644
index 0000000..9b13b05
--- /dev/null
+++ b/lib/util/tests/test_logging.c
@@ -0,0 +1,146 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ A test server that only does logging.
+
+ Copyright (C) Andrew Tridgell 1992-2005
+ Copyright (C) Martin Pool 2002
+ Copyright (C) Jelmer Vernooij 2002
+ Copyright (C) James J Myers 2003 <myersjj@samba.org>
+ Copyright (C) Douglas Bagnall 2022
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "lib/cmdline/cmdline.h"
+
+#ifdef USING_CMDLINE_S3
+#include "lib/util/debug_s3.h"
+#endif
+
+#define BINARY_NAME "test_s4_logging"
+
+static int log_level = 1;
+
+
+#include "lib/util/debug-classes/debug-classname-table.c"
+
+static int log_all_classes(int level)
+{
+ size_t i;
+ const char *name = NULL;
+ for (i = 0; i < ARRAY_SIZE(default_classname_table); i++) {
+ name = default_classname_table[i];
+ DEBUGC(i, level,
+ ("logging for '%s' [%zu], at level %d\n",
+ name, i, level));
+
+ /*
+ * That's it for the tests *here*. The invoker of this
+ * process will have set up an smb.conf that directs the
+ * output in particular ways, and will be looking to see that
+ * happens correctly.
+ */
+ }
+ return 0;
+}
+
+
+static int init_daemon(TALLOC_CTX *mem_ctx,
+ int argc,
+ const char *argv[],
+ const char **error)
+{
+ poptContext pc;
+ int opt;
+ bool ok;
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ {
+ .longName = "level",
+ .shortName = 'L',
+ .argInfo = POPT_ARG_INT,
+ .arg = &log_level,
+ .descrip = "log at this level",
+ .argDescrip = "LEVEL",
+ },
+ POPT_COMMON_SAMBA
+ POPT_COMMON_DAEMON
+ POPT_COMMON_VERSION
+ POPT_TABLEEND
+ };
+
+ setproctitle(BINARY_NAME);
+
+ ok = samba_cmdline_init(mem_ctx,
+ SAMBA_CMDLINE_CONFIG_SERVER,
+ true /* require_smbconf */);
+ if (!ok) {
+ *error = "Failed to init cmdline parser!\n";
+ return EINVAL;
+ }
+
+ pc = samba_popt_get_context(BINARY_NAME,
+ argc,
+ argv,
+ long_options,
+ 0);
+ if (pc == NULL) {
+ *error = "Failed to setup popt context!\n";
+ return ENOTRECOVERABLE;
+ }
+
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ fprintf(stderr, "\nInvalid option %s: %s\n\n",
+ poptBadOption(pc, 0), poptStrerror(opt));
+ poptPrintUsage(pc, stderr, 0);
+ return 1;
+ }
+
+ poptFreeContext(pc);
+
+#ifdef USING_CMDLINE_S3
+ reopen_logs();
+#endif
+ return 0;
+}
+
+
+int main(int argc, const char *argv[])
+{
+ int rc;
+ const char *error = NULL;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+ if (mem_ctx == NULL) {
+ exit(ENOMEM);
+ }
+
+ setproctitle_init(argc, discard_const(argv), environ);
+
+ rc = init_daemon(mem_ctx, argc, argv, &error);
+ if (rc != 0) {
+ fprintf(stderr, "error [%d]: %s\n", rc, error);
+ exit_daemon(error, rc);
+ }
+
+ rc = log_all_classes(log_level);
+ if (rc != 0) {
+ fprintf(stderr, "error in log_all_classes [%d]\n", rc);
+ exit_daemon("logging error", rc);
+ }
+
+ TALLOC_FREE(mem_ctx);
+ return rc;
+}
diff --git a/lib/util/tests/test_memcache.c b/lib/util/tests/test_memcache.c
new file mode 100644
index 0000000..8a39978
--- /dev/null
+++ b/lib/util/tests/test_memcache.c
@@ -0,0 +1,161 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2021 Andreas Schneider <asn@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "lib/replace/replace.h"
+#include "lib/util/talloc_stack.h"
+#include "lib/util/memcache.h"
+
+static int setup_talloc_context(void **state)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ *state = frame;
+ return 0;
+}
+
+static int teardown_talloc_context(void **state)
+{
+ TALLOC_CTX *frame = *state;
+ TALLOC_FREE(frame);
+ return 0;
+}
+
+static void torture_memcache_init(void **state)
+{
+ TALLOC_CTX *mem_ctx = *state;
+ struct memcache *cache = NULL;
+
+ cache = memcache_init(mem_ctx, 0);
+ assert_non_null(cache);
+
+ TALLOC_FREE(cache);
+
+ cache = memcache_init(mem_ctx, 10);
+ assert_non_null(cache);
+
+ TALLOC_FREE(cache);
+}
+
+static void torture_memcache_add_lookup_delete(void **state)
+{
+ TALLOC_CTX *mem_ctx = *state;
+ struct memcache *cache = NULL;
+ DATA_BLOB key1, key2;
+ char *path1 = NULL, *path2 = NULL;
+
+ cache = memcache_init(mem_ctx, 0);
+ assert_non_null(cache);
+
+ key1 = data_blob_const("key1", 4);
+ path1 = talloc_strdup(mem_ctx, "/tmp/one");
+ assert_non_null(path1);
+
+ key2 = data_blob_const("key2", 4);
+ path2 = talloc_strdup(mem_ctx, "/tmp/two");
+ assert_non_null(path1);
+
+ memcache_add_talloc(cache, GETWD_CACHE, key1, &path1);
+ assert_null(path1);
+
+ memcache_add_talloc(cache, GETWD_CACHE, key2, &path2);
+ assert_null(path2);
+
+ path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1);
+ assert_non_null(path1);
+ assert_string_equal(path1, "/tmp/one");
+
+ path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2);
+ assert_non_null(path2);
+ assert_string_equal(path2, "/tmp/two");
+
+ memcache_delete(cache, GETWD_CACHE, key1);
+ path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1);
+ assert_null(path1);
+
+ memcache_flush(cache, GETWD_CACHE);
+ path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2);
+ assert_null(path2);
+
+ TALLOC_FREE(path1);
+ TALLOC_FREE(path2);
+ TALLOC_FREE(cache);
+}
+
+static void torture_memcache_add_oversize(void **state)
+{
+ TALLOC_CTX *mem_ctx = *state;
+ struct memcache *cache = NULL;
+ DATA_BLOB key1, key2;
+ char *path1 = NULL, *path2 = NULL;
+
+ cache = memcache_init(mem_ctx, 10);
+ assert_non_null(cache);
+
+ key1 = data_blob_const("key1", 4);
+ path1 = talloc_strdup(mem_ctx, "/tmp/one");
+ assert_non_null(path1);
+
+ key2 = data_blob_const("key2", 4);
+ path2 = talloc_strdup(mem_ctx, "/tmp/two");
+ assert_non_null(path1);
+
+ memcache_add_talloc(cache, GETWD_CACHE, key1, &path1);
+ assert_null(path1);
+
+ memcache_add_talloc(cache, GETWD_CACHE, key2, &path2);
+ assert_null(path2);
+
+ path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1);
+ assert_null(path1);
+
+ path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2);
+ assert_non_null(path2);
+ assert_string_equal(path2, "/tmp/two");
+
+ TALLOC_FREE(path1);
+ TALLOC_FREE(path2);
+ TALLOC_FREE(cache);
+}
+
+int main(int argc, char *argv[])
+{
+ int rc;
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(torture_memcache_init),
+ cmocka_unit_test(torture_memcache_add_lookup_delete),
+ cmocka_unit_test(torture_memcache_add_oversize),
+ };
+
+ if (argc == 2) {
+ cmocka_set_test_filter(argv[1]);
+ }
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+ rc = cmocka_run_group_tests(tests,
+ setup_talloc_context,
+ teardown_talloc_context);
+
+ return rc;
+}
diff --git a/lib/util/tests/test_ms_fnmatch.c b/lib/util/tests/test_ms_fnmatch.c
new file mode 100644
index 0000000..d11c7be
--- /dev/null
+++ b/lib/util/tests/test_ms_fnmatch.c
@@ -0,0 +1,114 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2018 David Disseldorp <ddiss@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <errno.h>
+
+#include "lib/replace/replace.h"
+#include "lib/util/samba_util.h"
+#include "libcli/smb/smb_constants.h"
+
+static void test_ms_fn_match_protocol_no_wildcard(void **state)
+{
+ int cmp;
+
+ /* no wildcards in pattern, a simple strcasecmp_m */
+ cmp = ms_fnmatch_protocol("pattern", "string", PROTOCOL_COREPLUS,
+ true); /* case sensitive */
+ assert_int_equal(cmp, -3);
+}
+
+static void test_ms_fn_match_protocol_pattern_upgraded(void **state)
+{
+ int cmp;
+
+ /* protocol < PROTOCOL_NT1 pattern is "upgraded" */
+ cmp = ms_fnmatch_protocol("??????", "string", PROTOCOL_COREPLUS,
+ false);
+ assert_int_equal(cmp, 0);
+}
+
+static void test_ms_fn_match_protocol_match_zero_or_more(void **state)
+{
+ int cmp;
+
+ /* '*' matches zero or more characters. handled via recursive calls */
+ cmp = ms_fnmatch_protocol("********", "string", PROTOCOL_COREPLUS,
+ true);
+ assert_int_equal(cmp, 0);
+}
+
+static void test_ms_fn_match_protocol_mapped_char(void **state)
+{
+ int cmp;
+
+ /* '?' is mapped to '>', which matches any char or a '\0' */
+ cmp = ms_fnmatch_protocol("???????", "string", PROTOCOL_COREPLUS,
+ false);
+ assert_int_equal(cmp, 0);
+}
+
+static void test_ms_fn_match_protocol_nt1_any_char(void **state)
+{
+ int cmp;
+
+ /* PROTOCOL_NT1 '?' matches any char, '\0' is not included */
+ cmp = ms_fnmatch_protocol("???????", "string", PROTOCOL_NT1,
+ false);
+ assert_int_equal(cmp, -1);
+}
+
+static void test_ms_fn_match_protocol_nt1_case_sensitive(void **state)
+{
+ int cmp;
+
+ cmp = ms_fnmatch_protocol("StRinG", "string", PROTOCOL_NT1,
+ true); /* case sensitive */
+ assert_int_equal(cmp, 0);
+
+ cmp = ms_fnmatch_protocol("StRin?", "string", PROTOCOL_NT1,
+ true); /* case sensitive */
+ assert_int_equal(cmp, -1);
+
+ cmp = ms_fnmatch_protocol("StRin?", "string", PROTOCOL_NT1,
+ false);
+ assert_int_equal(cmp, 0);
+ cmp = ms_fnmatch_protocol("strin?", "string", PROTOCOL_NT1,
+ true); /* case sensitive */
+ assert_int_equal(cmp, 0);
+}
+
+int main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_ms_fn_match_protocol_no_wildcard),
+ cmocka_unit_test(test_ms_fn_match_protocol_pattern_upgraded),
+ cmocka_unit_test(test_ms_fn_match_protocol_match_zero_or_more),
+ cmocka_unit_test(test_ms_fn_match_protocol_mapped_char),
+ cmocka_unit_test(test_ms_fn_match_protocol_nt1_any_char),
+ cmocka_unit_test(test_ms_fn_match_protocol_nt1_case_sensitive),
+ };
+
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/lib/util/tests/test_stable_sort.c b/lib/util/tests/test_stable_sort.c
new file mode 100644
index 0000000..ae4b1f3
--- /dev/null
+++ b/lib/util/tests/test_stable_sort.c
@@ -0,0 +1,317 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2018 Andreas Schneider <asn@samba.org>
+ * Copyright (C) 2022 Douglas Bagnall <dbagnall@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+#include <stdbool.h>
+#include "replace.h"
+#include <talloc.h>
+
+#include "../stable_sort.h"
+
+
+static int cmp_integer(int *a, int *b)
+{
+ if (a == NULL || b == NULL) {
+ return 0;
+ }
+
+ if (*a > *b) {
+ return 1;
+ }
+
+ if (*a < *b) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static void test_stable_sort(void **state)
+{
+ int a[6] = { 6, 3, 2, 7, 9, 4 };
+ int tmp[6];
+ bool ok;
+ ok = stable_sort(a, tmp,
+ 6, sizeof(int), (samba_compare_fn_t)cmp_integer);
+
+ assert_true(ok);
+ assert_int_equal(a[0], 2);
+ assert_int_equal(a[1], 3);
+ assert_int_equal(a[2], 4);
+ assert_int_equal(a[3], 6);
+ assert_int_equal(a[4], 7);
+ assert_int_equal(a[5], 9);
+}
+
+static void test_stable_sort_talloc_short(void **state)
+{
+ int a[6] = { 6, 3, 2, 7, 9, 4 };
+ int ret;
+ ret = stable_sort_talloc(NULL, a, 6, sizeof(int),
+ (samba_compare_fn_t)cmp_integer);
+ assert_true(ret);
+
+ assert_int_equal(a[0], 2);
+ assert_int_equal(a[1], 3);
+ assert_int_equal(a[2], 4);
+ assert_int_equal(a[3], 6);
+ assert_int_equal(a[4], 7);
+ assert_int_equal(a[5], 9);
+}
+
+static void test_stable_sort_talloc_long(void **state)
+{
+ int i, ret;
+ size_t n = 1500;
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
+ int *a = talloc_array(mem_ctx, int, n);
+ for (i = 0; i < n; i++) {
+ a[i] = n - i;
+ }
+
+ ret = stable_sort_talloc(mem_ctx, a, n, sizeof(int),
+ (samba_compare_fn_t)cmp_integer);
+ assert_true(ret);
+
+ for (i = 0; i < n; i++) {
+ assert_int_equal(a[i], 1 + i);
+ }
+}
+
+
+/*
+ * Sort an array of structs with:
+ * - unwieldy uneven size
+ * - sort key not at the start
+ * - comparison depends on context
+ *
+ * which are things we sometimes do.
+ */
+
+struct contrived_struct {
+ char padding_1[13];
+ int key[3];
+ char padding_2[18];
+ size_t *index;
+};
+
+
+static int cmp_contrived_struct(struct contrived_struct *as,
+ struct contrived_struct *bs)
+{
+ int i = *as->index;
+ int a = as->key[i];
+ int b = bs->key[i];
+ return a - b;
+}
+
+static int cmp_contrived_struct_rev(struct contrived_struct *as,
+ struct contrived_struct *bs)
+{
+ /* will sort in reverseo order */
+ int i = *as->index;
+ int a = as->key[i];
+ int b = bs->key[i];
+ return b - a;
+}
+
+
+static void test_stable_sort_talloc_contrived_struct(void **state)
+{
+ int i, ret, prev;
+ size_t n = 800000;
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
+ size_t key_index = 0;
+
+ struct contrived_struct *a = talloc_zero_array(mem_ctx,
+ struct contrived_struct,
+ n);
+
+ /* we don't really want a good RNG, we want mess and repeated values. */
+ uint32_t x = 89, y = (uint32_t)-6, z = 11;
+ for (i = 0; i < n; i++) {
+ a[i].index = &key_index;
+ a[i].key[0] = (x & 0xffff) - 0x8000;
+ a[i].key[1] = z & 255;
+ /* key[2] is original order, useful for checking stability */
+ a[i].key[2] = i;
+ x += z ^ y;
+ y *= z + (x + 0x5555);
+ z -= x ^ i;
+ }
+
+ /* 1. sort by key[0] */
+ ret = stable_sort_talloc(mem_ctx, a, n,
+ sizeof(struct contrived_struct),
+ (samba_compare_fn_t)cmp_contrived_struct);
+ assert_true(ret);
+ prev = a[0].key[0];
+ for (i = 1; i < n; i++) {
+ int value = a[i].key[0];
+ assert_true(value >= prev);
+ if (value == prev) {
+ /* we can test the stability by comparing key[2] */
+ assert_true(a[i].key[2] >= a[i - 1].key[2]);
+ }
+ prev = value;
+ }
+
+ /* 2. sort by key[1]. key[0] now indicates stability. */
+ key_index = 1;
+ ret = stable_sort_talloc(mem_ctx, a, n,
+ sizeof(struct contrived_struct),
+ (samba_compare_fn_t)cmp_contrived_struct);
+ assert_true(ret);
+ prev = a[0].key[1];
+ for (i = 1; i < n; i++) {
+ int value = a[i].key[1];
+ assert_true(value >= prev);
+ if (value == prev) {
+ assert_true(a[i].key[0] >= a[i - 1].key[0]);
+ }
+ prev = value;
+ }
+
+ /*
+ * 3. sort by key[2]. key[1] would now indicate stability, but we know
+ * that key[2] has no duplicates, so stability is moot.
+ */
+ key_index = 2;
+ ret = stable_sort_talloc(mem_ctx, a, n,
+ sizeof(struct contrived_struct),
+ (samba_compare_fn_t)cmp_contrived_struct);
+ assert_true(ret);
+ prev = a[0].key[2];
+ for (i = 1; i < n; i++) {
+ int value = a[i].key[2];
+ assert_true(value > prev);
+ prev = value;
+ }
+
+ /*
+ * 4. sort by key[0] again, using descending sort order. key[2] should
+ * still be in ascending order where there are duplicate key[0] values.
+ */
+ key_index = 0;
+ ret = stable_sort_talloc(mem_ctx, a, n,
+ sizeof(struct contrived_struct),
+ (samba_compare_fn_t)cmp_contrived_struct_rev);
+ assert_true(ret);
+ prev = a[0].key[0];
+ for (i = 1; i < n; i++) {
+ int value = a[i].key[0];
+ assert_true(value <= prev);
+ if (value == prev) {
+ assert_true(a[i].key[2] >= a[i - 1].key[2]);
+ }
+ prev = value;
+ }
+}
+
+
+
+static int cmp_integer_xor_blob(int *_a, int *_b, int *opaque)
+{
+ int a = *_a ^ *opaque;
+ int b = *_b ^ *opaque;
+
+ if (a > b) {
+ return 1;
+ }
+
+ if (a < b) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static void test_stable_sort_talloc_r(void **state)
+{
+ int i;
+ size_t n = 1500;
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
+ int opaque = 42;
+ bool ok;
+ int *a = talloc_array(mem_ctx, int, n);
+ for (i = 0; i < n; i++) {
+ a[i] = (i * 7) & 255;
+ }
+
+ ok = stable_sort_talloc_r(mem_ctx, a, n, sizeof(int),
+ (samba_compare_with_context_fn_t)cmp_integer_xor_blob,
+ &opaque);
+ assert_true(ok);
+
+ for (i = 1; i < n; i++) {
+ assert_true((a[i - 1] ^ opaque) <= (a[i] ^ opaque));
+ }
+}
+
+
+static void test_stable_sort_silly_size(void **state)
+{
+ bool ok;
+ int a[33] = {0};
+ int b[33] = {0};
+
+ ok = stable_sort(a,
+ b,
+ (SIZE_MAX / 2) + 2,
+ (SIZE_MAX / 2) + 2,
+ (samba_compare_fn_t)cmp_integer);
+ assert_false(ok);
+}
+
+static void test_stable_sort_null_array(void **state)
+{
+ bool ok;
+ int a[33] = {0};
+
+ ok = stable_sort(a,
+ NULL,
+ 33,
+ sizeof(int),
+ (samba_compare_fn_t)cmp_integer);
+ assert_false(ok);
+}
+
+
+
+
+
+int main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_stable_sort),
+ cmocka_unit_test(test_stable_sort_talloc_short),
+ cmocka_unit_test(test_stable_sort_talloc_long),
+ cmocka_unit_test(test_stable_sort_talloc_contrived_struct),
+ cmocka_unit_test(test_stable_sort_talloc_r),
+ cmocka_unit_test(test_stable_sort_silly_size),
+ cmocka_unit_test(test_stable_sort_null_array),
+ };
+ if (!isatty(1)) {
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+ }
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/lib/util/tests/test_sys_rw.c b/lib/util/tests/test_sys_rw.c
new file mode 100644
index 0000000..22688fb
--- /dev/null
+++ b/lib/util/tests/test_sys_rw.c
@@ -0,0 +1,178 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Unit test for sys_rw.c
+ *
+ * Copyright (C) Ralph Böhme 2021
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "lib/replace/replace.h"
+#include "system/dir.h"
+
+#include "lib/util/sys_rw.c"
+
+static void test_sys_io_ranges_overlap(void **state)
+{
+ bool overlap;
+
+ /*
+ * sys_io_ranges_overlap() args are:
+ *
+ * src size, src offset, dst size, dst offset
+ */
+
+ /* src and dst size 0 => no overlap */
+ overlap = sys_io_ranges_overlap(0, 0, 0, 0);
+ assert_false(overlap);
+
+ /* dst size 0 => no overlap */
+ overlap = sys_io_ranges_overlap(1, 0, 0, 0);
+ assert_false(overlap);
+
+ /* src size 0 => no overlap */
+ overlap = sys_io_ranges_overlap(0, 0, 1, 0);
+ assert_false(overlap);
+
+ /* same range => overlap */
+ overlap = sys_io_ranges_overlap(1, 0, 1, 0);
+ assert_true(overlap);
+
+ /*
+ * |.|
+ * |.|
+ * src before dst => no overlap
+ */
+ overlap = sys_io_ranges_overlap(1, 0, 1, 1);
+ assert_false(overlap);
+
+ /*
+ * |..|
+ * |..|
+ * src into dst => overlap
+ */
+ overlap = sys_io_ranges_overlap(2, 0, 2, 1);
+ assert_true(overlap);
+
+ /*
+ * |....|
+ * |..|
+ * src encompasses dst => overlap
+ */
+ overlap = sys_io_ranges_overlap(4, 0, 1, 2);
+ assert_true(overlap);
+
+
+ /*
+ * |..|
+ * |..|
+ * dst into src => overlap
+ */
+ overlap = sys_io_ranges_overlap(2, 1, 2, 0);
+ assert_true(overlap);
+
+ /*
+ * |..|
+ * |....|
+ * dst encompasses src => overlap
+ */
+ overlap = sys_io_ranges_overlap(2, 1, 4, 0);
+ assert_true(overlap);
+}
+
+static void test_sys_block_align(void **state)
+{
+ int asize;
+
+ asize = sys_block_align(0, 2);
+ assert_int_equal(asize, 0);
+ asize = sys_block_align(1, 2);
+ assert_int_equal(asize, 2);
+ asize = sys_block_align(2, 2);
+ assert_int_equal(asize, 2);
+ asize = sys_block_align(3, 2);
+ assert_int_equal(asize, 4);
+
+ asize = sys_block_align(0, 4);
+ assert_int_equal(asize, 0);
+ asize = sys_block_align(1, 4);
+ assert_int_equal(asize, 4);
+ asize = sys_block_align(3, 4);
+ assert_int_equal(asize, 4);
+ asize = sys_block_align(4, 4);
+ assert_int_equal(asize, 4);
+ asize = sys_block_align(5, 4);
+ assert_int_equal(asize, 8);
+ asize = sys_block_align(7, 4);
+ assert_int_equal(asize, 8);
+ asize = sys_block_align(8, 4);
+ assert_int_equal(asize, 8);
+ asize = sys_block_align(9, 4);
+ assert_int_equal(asize, 12);
+}
+
+static void test_sys_block_align_truncate(void **state)
+{
+ int asize;
+
+ asize = sys_block_align_truncate(0, 2);
+ assert_int_equal(asize, 0);
+ asize = sys_block_align_truncate(1, 2);
+ assert_int_equal(asize, 0);
+ asize = sys_block_align_truncate(2, 2);
+ assert_int_equal(asize, 2);
+ asize = sys_block_align_truncate(3, 2);
+ assert_int_equal(asize, 2);
+ asize = sys_block_align_truncate(4, 2);
+ assert_int_equal(asize, 4);
+ asize = sys_block_align_truncate(5, 2);
+ assert_int_equal(asize, 4);
+
+ asize = sys_block_align_truncate(0, 4);
+ assert_int_equal(asize, 0);
+ asize = sys_block_align_truncate(1, 4);
+ assert_int_equal(asize, 0);
+ asize = sys_block_align_truncate(3, 4);
+ assert_int_equal(asize, 0);
+ asize = sys_block_align_truncate(4, 4);
+ assert_int_equal(asize, 4);
+ asize = sys_block_align_truncate(5, 4);
+ assert_int_equal(asize, 4);
+ asize = sys_block_align_truncate(7, 4);
+ assert_int_equal(asize, 4);
+ asize = sys_block_align_truncate(8, 4);
+ assert_int_equal(asize, 8);
+ asize = sys_block_align_truncate(9, 4);
+ assert_int_equal(asize, 8);
+}
+
+int main(int argc, char **argv)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_sys_io_ranges_overlap),
+ cmocka_unit_test(test_sys_block_align),
+ cmocka_unit_test(test_sys_block_align_truncate),
+ };
+
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/lib/util/tests/test_talloc_keep_secret.c b/lib/util/tests/test_talloc_keep_secret.c
new file mode 100644
index 0000000..1462dab
--- /dev/null
+++ b/lib/util/tests/test_talloc_keep_secret.c
@@ -0,0 +1,94 @@
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <string.h>
+#include <talloc.h>
+#include "lib/util/talloc_keep_secret.h"
+
+int rep_memset_s(void *dest, size_t destsz, int ch, size_t count);
+
+int rep_memset_s(void *dest, size_t destsz, int ch, size_t count)
+{
+ check_expected_ptr(dest);
+ check_expected(destsz);
+ check_expected(ch);
+ check_expected(count);
+
+ return 0;
+}
+
+static void test_talloc_keep_secret(void ** state)
+{
+ TALLOC_CTX *pool = NULL;
+ char *ptr1 = NULL;
+ char *ptr2 = NULL;
+ const char *ptr1_talloc_name = NULL;
+ size_t ptr1_size;
+ size_t i;
+
+ pool = talloc_pool(NULL, 256);
+ assert_non_null(pool);
+
+ ptr1 = talloc_strdup(pool, "secret");
+ assert_non_null(ptr1);
+ assert_string_equal(ptr1, "secret");
+
+ talloc_keep_secret(ptr1);
+
+ ptr1_talloc_name = talloc_get_name(ptr1);
+ assert_string_equal(ptr1_talloc_name, "ptr1");
+
+ ptr1_size = talloc_get_size(ptr1);
+ assert_int_equal(ptr1_size, strlen(ptr1) + 1);
+
+ expect_string(rep_memset_s, dest, "secret");
+ expect_value(rep_memset_s, destsz, strlen(ptr1) + 1);
+ expect_value(rep_memset_s, ch, (int)'\0');
+ expect_value(rep_memset_s, count, strlen(ptr1) + 1);
+
+ talloc_free(ptr1);
+
+ ptr2 = talloc_size(pool, ptr1_size);
+ assert_ptr_equal(ptr1, ptr2);
+
+ for (i = 1; i < ptr1_size; i++) {
+ assert_int_not_equal(ptr2[0], ptr2[i]);
+ }
+
+ talloc_free(pool);
+}
+
+static void test_talloc_keep_secret_validate_memset(void **state)
+{
+ TALLOC_CTX *mem_ctx = NULL;
+ char *password = NULL;
+
+ mem_ctx = talloc_new(NULL);
+ assert_non_null(mem_ctx);
+
+ password = talloc_strdup(mem_ctx, "secret");
+ assert_non_null(password);
+ talloc_keep_secret(password);
+
+ expect_string(rep_memset_s, dest, "secret");
+ expect_value(rep_memset_s, destsz, strlen(password) + 1);
+ expect_value(rep_memset_s, ch, (int)'\0');
+ expect_value(rep_memset_s, count, strlen(password) + 1);
+
+ talloc_free(mem_ctx);
+}
+
+int main(void)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_talloc_keep_secret),
+ cmocka_unit_test(test_talloc_keep_secret_validate_memset),
+ };
+
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
diff --git a/lib/util/tests/test_util.c b/lib/util/tests/test_util.c
new file mode 100644
index 0000000..62f10ed
--- /dev/null
+++ b/lib/util/tests/test_util.c
@@ -0,0 +1,344 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Unit test for util.c
+ *
+ * Copyright (C) Christof Schmitt 2020
+ * Copyright (C) Andreas Schneider 2020
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "lib/replace/replace.h"
+#include "system/dir.h"
+
+#include "lib/util/util.c"
+
+struct test_paths {
+ char testdir[PATH_MAX];
+ char none[PATH_MAX];
+ char dir[PATH_MAX];
+ char dir_recursive[PATH_MAX];
+ mode_t dir_mode;
+ char file[PATH_MAX];
+ mode_t file_mode;
+ char symlink_none[PATH_MAX];
+ char symlink_dir[PATH_MAX];
+ char symlink_file[PATH_MAX];
+};
+
+static int group_setup(void **state)
+{
+ struct test_paths *paths = NULL;
+ char *testdir = NULL;
+ int ret, fd;
+
+ umask(0);
+
+ paths = malloc(sizeof(struct test_paths));
+ assert_non_null(paths);
+
+ strlcpy(paths->testdir, tmpdir(), sizeof(paths->testdir));
+ strlcat(paths->testdir, "/test_util_XXXXXX", sizeof(paths->testdir));
+ testdir = mkdtemp(paths->testdir);
+ assert_non_null(testdir);
+
+ strlcpy(paths->none, testdir, sizeof(paths->none));
+ strlcat(paths->none, "/none", sizeof(paths->none));
+
+ strlcpy(paths->dir, testdir, sizeof(paths->dir));
+ strlcat(paths->dir, "/dir", sizeof(paths->dir));
+ paths->dir_mode = 0750;
+ ret = mkdir(paths->dir, paths->dir_mode);
+ assert_return_code(ret, errno);
+
+ strlcpy(paths->dir_recursive, testdir, sizeof(paths->dir));
+ strlcat(paths->dir_recursive, "/dir_recursive", sizeof(paths->dir));
+ paths->dir_mode = 0750;
+ ret = mkdir(paths->dir_recursive, paths->dir_mode);
+ assert_return_code(ret, errno);
+
+ strlcpy(paths->file, testdir, sizeof(paths->file));
+ strlcat(paths->file, "/file", sizeof(paths->file));
+ paths->file_mode = 0640;
+ fd = creat(paths->file, paths->file_mode);
+ assert_return_code(fd, errno);
+ ret = close(fd);
+ assert_return_code(ret, errno);
+
+ strlcpy(paths->symlink_none, testdir, sizeof(paths->symlink_none));
+ strlcat(paths->symlink_none, "/symlink_none",
+ sizeof(paths->symlink_none));
+ ret = symlink("/none", paths->symlink_none);
+ assert_return_code(ret, errno);
+
+ strlcpy(paths->symlink_dir, testdir, sizeof(paths->symlink_dir));
+ strlcat(paths->symlink_dir, "/symlink_dir", sizeof(paths->symlink_dir));
+ ret = symlink(paths->dir, paths->symlink_dir);
+ assert_return_code(ret, errno);
+
+ strlcpy(paths->symlink_file, testdir, sizeof(paths->symlink_file));
+ strlcat(paths->symlink_file, "/symlink_file",
+ sizeof(paths->symlink_file));
+ ret = symlink(paths->file, paths->symlink_file);
+ assert_return_code(ret, errno);
+
+ *state = paths;
+
+ return 0;
+}
+
+static int torture_rmdirs(const char *path)
+{
+ DIR *d;
+ struct dirent *dp;
+ struct stat sb;
+ char *fname;
+
+ if ((d = opendir(path)) != NULL) {
+ while(stat(path, &sb) == 0) {
+ /* if we can remove the directory we're done */
+ if (rmdir(path) == 0) {
+ break;
+ }
+ switch (errno) {
+ case ENOTEMPTY:
+ case EEXIST:
+ case EBADF:
+ break; /* continue */
+ default:
+ closedir(d);
+ return 0;
+ }
+
+ while ((dp = readdir(d)) != NULL) {
+ size_t len;
+ /* skip '.' and '..' */
+ if (dp->d_name[0] == '.' &&
+ (dp->d_name[1] == '\0' ||
+ (dp->d_name[1] == '.' && dp->d_name[2] == '\0'))) {
+ continue;
+ }
+
+ len = strlen(path) + strlen(dp->d_name) + 2;
+ fname = malloc(len);
+ if (fname == NULL) {
+ closedir(d);
+ return -1;
+ }
+ snprintf(fname, len, "%s/%s", path, dp->d_name);
+
+ /* stat the file */
+ if (lstat(fname, &sb) != -1) {
+ if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode)) {
+ if (rmdir(fname) < 0) { /* can't be deleted */
+ if (errno == EACCES) {
+ closedir(d);
+ SAFE_FREE(fname);
+ return -1;
+ }
+ torture_rmdirs(fname);
+ }
+ } else {
+ unlink(fname);
+ }
+ } /* lstat */
+ SAFE_FREE(fname);
+ } /* readdir */
+
+ rewinddir(d);
+ }
+ } else {
+ return -1;
+ }
+
+ closedir(d);
+ return 0;
+}
+
+static int group_teardown(void **state)
+{
+ struct test_paths *paths = *state;
+ int ret;
+
+ ret = unlink(paths->file);
+ assert_return_code(ret, errno);
+
+ ret = unlink(paths->symlink_none);
+ assert_return_code(ret, errno);
+
+ ret = unlink(paths->symlink_dir);
+ assert_return_code(ret, errno);
+
+ ret = unlink(paths->symlink_file);
+ assert_return_code(ret, errno);
+
+ ret = torture_rmdirs(paths->testdir);
+ assert_return_code(ret, errno);
+
+ free(paths);
+ return 0;
+}
+
+static void test_directory_create_or_exists_none(void **state)
+{
+ struct test_paths *paths = *state;
+ bool b;
+ struct stat sbuf;
+ int ret;
+
+ b = directory_create_or_exist(paths->none, 0775);
+ assert_true(b);
+
+ ret = lstat(paths->none, &sbuf);
+ assert_return_code(ret, errno);
+ assert_int_equal(sbuf.st_mode & 0777, 0775);
+ assert_true(S_ISDIR(sbuf.st_mode));
+}
+
+static int teardown_none_directory(void **state)
+{
+ struct test_paths *paths = *state;
+
+ rmdir(paths->none);
+ return 0;
+}
+
+static void test_directory_create_or_exists_dir(void **state)
+{
+ struct test_paths *paths = *state;
+ bool b;
+ struct stat sbuf;
+ int ret;
+
+ b = directory_create_or_exist(paths->dir, 770);
+ assert_true(b);
+
+ ret = lstat(paths->dir, &sbuf);
+ assert_return_code(ret, errno);
+ assert_int_equal(sbuf.st_mode & 0777, paths->dir_mode);
+ assert_true(S_ISDIR(sbuf.st_mode));
+}
+
+static void test_directory_create_or_exists_file(void **state)
+{
+ struct test_paths *paths = *state;
+ bool b;
+ struct stat sbuf;
+ int ret;
+
+ b = directory_create_or_exist(paths->file, 770);
+ assert_false(b);
+
+ ret = lstat(paths->file, &sbuf);
+ assert_return_code(ret, errno);
+ assert_int_equal(sbuf.st_mode & 0777, paths->file_mode);
+ assert_true(S_ISREG(sbuf.st_mode));
+}
+
+static void test_directory_create_or_exists_symlink_none(void **state)
+{
+ struct test_paths *paths = *state;
+ bool b;
+ struct stat sbuf;
+ int ret;
+
+ b = directory_create_or_exist(paths->symlink_none, 770);
+ assert_false(b);
+
+ ret = lstat(paths->symlink_none, &sbuf);
+ assert_return_code(ret, errno);
+ assert_int_equal(sbuf.st_mode & 0777, 0777);
+ assert_true(S_ISLNK(sbuf.st_mode));
+}
+
+static void test_directory_create_or_exists_symlink_dir(void **state)
+{
+ struct test_paths *paths = *state;
+ bool b;
+ struct stat sbuf;
+ int ret;
+
+ b = directory_create_or_exist(paths->symlink_dir, 770);
+ assert_true(b);
+
+ ret = lstat(paths->symlink_dir, &sbuf);
+ assert_return_code(ret, errno);
+ assert_int_equal(sbuf.st_mode & 0777, 0777);
+ assert_true(S_ISLNK(sbuf.st_mode));
+}
+
+static void test_directory_create_or_exists_symlink_file(void **state)
+{
+ struct test_paths *paths = *state;
+ bool b;
+ struct stat sbuf;
+ int ret;
+
+ b = directory_create_or_exist(paths->symlink_file, 770);
+ assert_false(b);
+
+ ret = lstat(paths->symlink_file, &sbuf);
+ assert_return_code(ret, errno);
+ assert_int_equal(sbuf.st_mode & 0777, 0777);
+ assert_true(S_ISLNK(sbuf.st_mode));
+}
+
+static void test_directory_create_or_exists_recursive(void **state)
+{
+ struct test_paths *paths = *state;
+ char recursive_testdir[PATH_MAX] = {0};
+ struct stat sbuf = {0};
+ bool ok;
+ int ret;
+
+ ret = snprintf(recursive_testdir,
+ sizeof(recursive_testdir),
+ "%s/wurst/brot",
+ paths->dir_recursive);
+ assert_int_not_equal(ret, -1);
+
+ ok = directory_create_or_exists_recursive(recursive_testdir,
+ 0700);
+ assert_true(ok);
+
+ ret = lstat(recursive_testdir, &sbuf);
+ assert_return_code(ret, errno);
+ assert_int_equal(sbuf.st_mode & 0777, 0700);
+ assert_true(S_ISDIR(sbuf.st_mode));
+}
+
+int main(int argc, char **argv)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_teardown(test_directory_create_or_exists_none,
+ teardown_none_directory),
+ cmocka_unit_test(test_directory_create_or_exists_dir),
+ cmocka_unit_test(test_directory_create_or_exists_file),
+ cmocka_unit_test(test_directory_create_or_exists_symlink_none),
+ cmocka_unit_test(test_directory_create_or_exists_symlink_dir),
+ cmocka_unit_test(test_directory_create_or_exists_symlink_file),
+ cmocka_unit_test(test_directory_create_or_exists_recursive),
+ };
+
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+ return cmocka_run_group_tests(tests, group_setup, group_teardown);
+}
diff --git a/lib/util/tests/test_util_paths.c b/lib/util/tests/test_util_paths.c
new file mode 100644
index 0000000..4dfe11c
--- /dev/null
+++ b/lib/util/tests/test_util_paths.c
@@ -0,0 +1,127 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2020 Andreas Schneider <asn@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "lib/replace/replace.h"
+#include <talloc.h>
+
+#include "lib/util/util_paths.c"
+
+static int setup(void **state)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
+
+ assert_non_null(mem_ctx);
+ *state = mem_ctx;
+
+ return 0;
+}
+
+static int teardown(void **state)
+{
+ TALLOC_CTX *mem_ctx = *state;
+ TALLOC_FREE(mem_ctx);
+
+ return 0;
+}
+
+static void test_get_user_home_dir(void **state)
+{
+ TALLOC_CTX *mem_ctx = *state;
+ struct passwd *pwd = getpwuid(getuid());
+ char *user;
+
+ user = get_user_home_dir(mem_ctx);
+ assert_non_null(user);
+ assert_string_equal(user, pwd->pw_dir);
+
+ TALLOC_FREE(user);
+}
+
+static void test_path_expand_tilde(void **state)
+{
+ TALLOC_CTX *mem_ctx = *state;
+ char h[256] = {0};
+ char *d = NULL;
+ const char *user = NULL;
+ char *home = NULL;
+
+ user = getenv("USER");
+ if (user == NULL){
+ user = getenv("LOGNAME");
+ }
+
+ /* In certain CIs there no such variables */
+ if (user == NULL) {
+ struct passwd *pw = getpwuid(getuid());
+ if (pw){
+ user = pw->pw_name;
+ }
+ }
+
+ home = getenv("HOME");
+ assert_non_null(home);
+ snprintf(h, sizeof(h), "%s/.cache", home);
+
+ d = path_expand_tilde(mem_ctx, "~/.cache");
+ assert_non_null(d);
+ assert_string_equal(d, h);
+ TALLOC_FREE(d);
+
+ snprintf(h, sizeof(h), "%s/.cache/X~", home);
+ d = path_expand_tilde(mem_ctx, "~/.cache/X~");
+ assert_string_equal(d, h);
+ TALLOC_FREE(d);
+
+ d = path_expand_tilde(mem_ctx, "/guru/meditation");
+ assert_non_null(d);
+ assert_string_equal(d, "/guru/meditation");
+ TALLOC_FREE(d);
+
+ snprintf(h, sizeof(h), "~%s/.cache", user);
+ d = path_expand_tilde(mem_ctx, h);
+ assert_non_null(d);
+
+ snprintf(h, sizeof(h), "%s/.cache", home);
+ assert_string_equal(d, h);
+ TALLOC_FREE(d);
+}
+
+int main(int argc, char *argv[])
+{
+ int rc;
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_get_user_home_dir),
+ cmocka_unit_test(test_path_expand_tilde),
+ };
+
+ if (argc == 2) {
+ cmocka_set_test_filter(argv[1]);
+ }
+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+ rc = cmocka_run_group_tests(tests, setup, teardown);
+
+ return rc;
+}
diff --git a/lib/util/tests/tfork-drd.supp b/lib/util/tests/tfork-drd.supp
new file mode 100644
index 0000000..7d0544b
--- /dev/null
+++ b/lib/util/tests/tfork-drd.supp
@@ -0,0 +1,14 @@
+{
+ tfork_pthread_cond_init
+ drd:CondErr
+ fun:pthread_cond_init_intercept
+ fun:pthread_cond_init@*
+ fun:tfork_atfork_child
+ fun:fork
+ fun:tfork_start_waiter_and_worker
+ fun:tfork_create
+ fun:tfork_thread
+ fun:vgDrd_thread_wrapper
+ fun:start_thread
+ fun:clone
+}
diff --git a/lib/util/tests/tfork-helgrind.supp b/lib/util/tests/tfork-helgrind.supp
new file mode 100644
index 0000000..4b62b2a
--- /dev/null
+++ b/lib/util/tests/tfork-helgrind.supp
@@ -0,0 +1,32 @@
+{
+ tfork_atexit_unknown1
+ Helgrind:Misc
+ fun:mutex_destroy_WRK
+ fun:pthread_mutex_destroy
+ obj:/usr/lib64/libp11-kit.so.0.3.0
+ fun:_dl_fini
+ fun:__run_exit_handlers
+ fun:exit
+ fun:(below main)
+}
+
+{
+ tfork_atexit_unknown2
+ Helgrind:Misc
+ fun:mutex_destroy_WRK
+ fun:pthread_mutex_destroy
+ fun:_dl_fini
+ fun:__run_exit_handlers
+ fun:exit
+ fun:(below main)
+}
+{
+ tfork_pthread_get_specific
+ Helgrind:Race
+ fun:tfork_global_get
+ fun:tfork_create
+ fun:tfork_thread
+ fun:mythread_wrapper
+ fun:start_thread
+ fun:clone
+}
diff --git a/lib/util/tests/tfork.c b/lib/util/tests/tfork.c
new file mode 100644
index 0000000..70ae975
--- /dev/null
+++ b/lib/util/tests/tfork.c
@@ -0,0 +1,855 @@
+/*
+ * Tests for tfork
+ *
+ * Copyright Ralph Boehme <slow@samba.org> 2017
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include <talloc.h>
+#include <tevent.h>
+#include "system/filesys.h"
+#include "system/wait.h"
+#include "system/select.h"
+#include "libcli/util/ntstatus.h"
+#include "torture/torture.h"
+#include "lib/util/data_blob.h"
+#include "torture/local/proto.h"
+#include "lib/util/tfork.h"
+#include "lib/util/samba_util.h"
+#include "lib/util/sys_rw.h"
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+#endif
+
+static bool test_tfork_simple(struct torture_context *tctx)
+{
+ pid_t parent = getpid();
+ struct tfork *t = NULL;
+ pid_t child;
+ int ret;
+
+ t = tfork_create();
+ if (t == NULL) {
+ torture_fail(tctx, "tfork failed\n");
+ return false;
+ }
+ child = tfork_child_pid(t);
+ if (child == 0) {
+ torture_comment(tctx, "my parent pid is %d\n", parent);
+ torture_assert(tctx, getpid() != parent, "tfork failed\n");
+ _exit(0);
+ }
+
+ ret = tfork_destroy(&t);
+ torture_assert(tctx, ret == 0, "tfork_destroy failed\n");
+
+ return true;
+}
+
+static bool test_tfork_status(struct torture_context *tctx)
+{
+ struct tfork *t = NULL;
+ int status;
+ pid_t child;
+ bool ok = true;
+
+ t = tfork_create();
+ if (t == NULL) {
+ torture_fail(tctx, "tfork failed\n");
+ return false;
+ }
+ child = tfork_child_pid(t);
+ if (child == 0) {
+ _exit(123);
+ }
+
+ status = tfork_status(&t, true);
+ if (status == -1) {
+ torture_fail(tctx, "tfork_status failed\n");
+ }
+
+ torture_assert_goto(tctx, WIFEXITED(status) == true, ok, done,
+ "tfork failed\n");
+ torture_assert_goto(tctx, WEXITSTATUS(status) == 123, ok, done,
+ "tfork failed\n");
+
+ torture_comment(tctx, "exit status [%d]\n", WEXITSTATUS(status));
+
+done:
+ return ok;
+}
+
+static bool test_tfork_sigign(struct torture_context *tctx)
+{
+ struct tfork *t = NULL;
+ struct sigaction act;
+ pid_t child;
+ int status;
+ bool ok = true;
+ int ret;
+
+ act = (struct sigaction) {
+ .sa_flags = SA_NOCLDWAIT,
+ .sa_handler = SIG_IGN,
+ };
+
+ ret = sigaction(SIGCHLD, &act, NULL);
+ torture_assert_goto(tctx, ret == 0, ok, done, "sigaction failed\n");
+
+ t = tfork_create();
+ if (t == NULL) {
+ torture_fail(tctx, "tfork failed\n");
+ return false;
+ }
+ child = tfork_child_pid(t);
+ if (child == 0) {
+ sleep(1);
+ _exit(123);
+ }
+
+ child = fork();
+ if (child == -1) {
+ torture_fail(tctx, "fork failed\n");
+ return false;
+ }
+ if (child == 0) {
+ _exit(0);
+ }
+
+ status = tfork_status(&t, true);
+ if (status == -1) {
+ torture_fail(tctx, "tfork_status failed\n");
+ }
+
+ torture_assert_goto(tctx, WIFEXITED(status) == true, ok, done,
+ "tfork failed\n");
+ torture_assert_goto(tctx, WEXITSTATUS(status) == 123, ok, done,
+ "tfork failed\n");
+ torture_comment(tctx, "exit status [%d]\n", WEXITSTATUS(status));
+
+done:
+ return ok;
+}
+
+static void sigchld_handler1(int signum, siginfo_t *si, void *u)
+{
+ pid_t pid;
+ int status;
+
+ if (signum != SIGCHLD) {
+ abort();
+ }
+
+ pid = waitpid(si->si_pid, &status, 0);
+ if (pid != si->si_pid) {
+ abort();
+ }
+}
+
+static bool test_tfork_sighandler(struct torture_context *tctx)
+{
+ struct tfork *t = NULL;
+ struct sigaction act;
+ struct sigaction oldact;
+ pid_t child;
+ int status;
+ bool ok = true;
+ int ret;
+
+ act = (struct sigaction) {
+ .sa_flags = SA_SIGINFO,
+ .sa_sigaction = sigchld_handler1,
+ };
+
+ ret = sigaction(SIGCHLD, &act, &oldact);
+ torture_assert_goto(tctx, ret == 0, ok, done, "sigaction failed\n");
+
+ t = tfork_create();
+ if (t == NULL) {
+ torture_fail(tctx, "tfork failed\n");
+ return false;
+ }
+ child = tfork_child_pid(t);
+ if (child == 0) {
+ sleep(1);
+ _exit(123);
+ }
+
+ child = fork();
+ if (child == -1) {
+ torture_fail(tctx, "fork failed\n");
+ return false;
+ }
+ if (child == 0) {
+ _exit(0);
+ }
+
+ status = tfork_status(&t, true);
+ if (status == -1) {
+ torture_fail(tctx, "tfork_status failed\n");
+ }
+
+ torture_assert_goto(tctx, WIFEXITED(status) == true, ok, done,
+ "tfork failed\n");
+ torture_assert_goto(tctx, WEXITSTATUS(status) == 123, ok, done,
+ "tfork failed\n");
+ torture_comment(tctx, "exit status [%d]\n", WEXITSTATUS(status));
+
+done:
+ sigaction(SIGCHLD, &oldact, NULL);
+
+ return ok;
+}
+
+static bool test_tfork_process_hierarchy(struct torture_context *tctx)
+{
+ struct tfork *t = NULL;
+ pid_t pid = getpid();
+ pid_t child;
+ pid_t pgid = getpgid(0);
+ pid_t sid = getsid(0);
+ char *procpath = NULL;
+ int status;
+ struct stat st;
+ int ret;
+ bool ok = true;
+
+ procpath = talloc_asprintf(tctx, "/proc/%d/status", getpid());
+ torture_assert_not_null(tctx, procpath, "talloc_asprintf failed\n");
+
+ ret = stat(procpath, &st);
+ TALLOC_FREE(procpath);
+ if (ret != 0) {
+ if (errno == ENOENT) {
+ torture_skip(tctx, "/proc missing\n");
+ }
+ torture_fail(tctx, "stat failed\n");
+ }
+
+ t = tfork_create();
+ if (t == NULL) {
+ torture_fail(tctx, "tfork failed\n");
+ return false;
+ }
+ child = tfork_child_pid(t);
+ if (child == 0) {
+ char *cmd = NULL;
+ FILE *fp = NULL;
+ char line[64];
+ char *p;
+ pid_t ppid;
+
+ torture_assert_goto(tctx, pgid == getpgid(0), ok, child_fail, "tfork failed\n");
+ torture_assert_goto(tctx, sid == getsid(0), ok, child_fail, "tfork failed\n");
+
+ cmd = talloc_asprintf(tctx, "cat /proc/%d/status | awk '/^PPid:/ {print $2}'", getppid());
+ torture_assert_goto(tctx, cmd != NULL, ok, child_fail, "talloc_asprintf failed\n");
+
+ fp = popen(cmd, "r");
+ torture_assert_goto(tctx, fp != NULL, ok, child_fail, "popen failed\n");
+
+ p = fgets(line, sizeof(line) - 1, fp);
+ pclose(fp);
+ torture_assert_goto(tctx, p != NULL, ok, child_fail, "popen failed\n");
+
+ ret = sscanf(line, "%d", &ppid);
+ torture_assert_goto(tctx, ret == 1, ok, child_fail, "sscanf failed\n");
+ torture_assert_goto(tctx, ppid == pid, ok, child_fail, "process hierarchy not rooted at caller\n");
+
+ _exit(0);
+
+ child_fail:
+ _exit(1);
+ }
+
+ status = tfork_status(&t, true);
+ if (status == -1) {
+ torture_fail(tctx, "tfork_status failed\n");
+ }
+
+ torture_assert_goto(tctx, WIFEXITED(status) == true, ok, done,
+ "tfork failed\n");
+ torture_assert_goto(tctx, WEXITSTATUS(status) == 0, ok, done,
+ "tfork failed\n");
+ torture_comment(tctx, "exit status [%d]\n", WEXITSTATUS(status));
+
+done:
+ return ok;
+}
+
+static bool test_tfork_pipe(struct torture_context *tctx)
+{
+ struct tfork *t = NULL;
+ int status;
+ pid_t child;
+ int up[2];
+ int down[2];
+ char c;
+ int ret;
+ bool ok = true;
+
+ ret = pipe(&up[0]);
+ torture_assert(tctx, ret == 0, "pipe failed\n");
+
+ ret = pipe(&down[0]);
+ torture_assert(tctx, ret == 0, "pipe failed\n");
+
+ t = tfork_create();
+ if (t == NULL) {
+ torture_fail(tctx, "tfork failed\n");
+ return false;
+ }
+ child = tfork_child_pid(t);
+ if (child == 0) {
+ close(up[0]);
+ close(down[1]);
+
+ ret = read(down[0], &c, 1);
+ torture_assert_goto(tctx, ret == 1, ok, child_fail, "read failed\n");
+ torture_assert_goto(tctx, c == 1, ok, child_fail, "read failed\n");
+
+ ret = write(up[1], &(char){2}, 1);
+ torture_assert_goto(tctx, ret == 1, ok, child_fail, "write failed\n");
+
+ _exit(0);
+
+ child_fail:
+ _exit(1);
+ }
+
+ close(up[1]);
+ close(down[0]);
+
+ ret = write(down[1], &(char){1}, 1);
+ torture_assert(tctx, ret == 1, "read failed\n");
+
+ ret = read(up[0], &c, 1);
+ torture_assert(tctx, ret == 1, "read failed\n");
+ torture_assert(tctx, c == 2, "read failed\n");
+
+ status = tfork_status(&t, true);
+ if (status == -1) {
+ torture_fail(tctx, "tfork_status failed\n");
+ }
+
+ torture_assert_goto(tctx, WIFEXITED(status) == true, ok, done,
+ "tfork failed\n");
+ torture_assert_goto(tctx, WEXITSTATUS(status) == 0, ok, done,
+ "tfork failed\n");
+done:
+ return ok;
+}
+
+static bool test_tfork_twice(struct torture_context *tctx)
+{
+ struct tfork *t = NULL;
+ int status;
+ pid_t child;
+ pid_t pid;
+ int up[2];
+ int ret;
+ bool ok = true;
+
+ ret = pipe(&up[0]);
+ torture_assert(tctx, ret == 0, "pipe failed\n");
+
+ t = tfork_create();
+ if (t == NULL) {
+ torture_fail(tctx, "tfork failed\n");
+ return false;
+ }
+ child = tfork_child_pid(t);
+ if (child == 0) {
+ close(up[0]);
+
+ t = tfork_create();
+ if (t == NULL) {
+ torture_fail(tctx, "tfork failed\n");
+ return false;
+ }
+ child = tfork_child_pid(t);
+ if (child == 0) {
+ sleep(1);
+ pid = getpid();
+ ret = write(up[1], &pid, sizeof(pid_t));
+ torture_assert_goto(tctx, ret == sizeof(pid_t), ok, child_fail, "write failed\n");
+
+ _exit(0);
+
+ child_fail:
+ _exit(1);
+ }
+
+ _exit(0);
+ }
+
+ close(up[1]);
+
+ ret = read(up[0], &pid, sizeof(pid_t));
+ torture_assert(tctx, ret == sizeof(pid_t), "read failed\n");
+
+ status = tfork_status(&t, true);
+ torture_assert_goto(tctx, status != -1, ok, done, "tfork_status failed\n");
+
+ torture_assert_goto(tctx, WIFEXITED(status) == true, ok, done,
+ "tfork failed\n");
+ torture_assert_goto(tctx, WEXITSTATUS(status) == 0, ok, done,
+ "tfork failed\n");
+done:
+ return ok;
+}
+
+static void *tfork_thread(void *p)
+{
+ struct tfork *t = NULL;
+ int status;
+ pid_t child;
+ uint64_t tid = (uint64_t)pthread_self();
+ uint64_t *result = NULL;
+ int up[2];
+ ssize_t nread;
+ int ret;
+
+ ret = pipe(up);
+ if (ret != 0) {
+ pthread_exit(NULL);
+ }
+
+ t = tfork_create();
+ if (t == NULL) {
+ pthread_exit(NULL);
+ }
+ child = tfork_child_pid(t);
+ if (child == 0) {
+ ssize_t nwritten;
+
+ close(up[0]);
+ tid++;
+ nwritten = sys_write(up[1], &tid, sizeof(uint64_t));
+ if (nwritten != sizeof(uint64_t)) {
+ _exit(1);
+ }
+ _exit(0);
+ }
+ close(up[1]);
+
+ result = malloc(sizeof(uint64_t));
+ if (result == NULL) {
+ pthread_exit(NULL);
+ }
+
+ nread = sys_read(up[0], result, sizeof(uint64_t));
+ if (nread != sizeof(uint64_t)) {
+ pthread_exit(NULL);
+ }
+
+ status = tfork_status(&t, true);
+ if (status == -1) {
+ pthread_exit(NULL);
+ }
+
+ pthread_exit(result);
+}
+
+static bool test_tfork_threads(struct torture_context *tctx)
+{
+ int ret;
+ bool ok = true;
+ const int num_threads = 64;
+ pthread_t threads[num_threads];
+ sigset_t set;
+ int i;
+
+#ifndef HAVE_PTHREAD
+ torture_skip(tctx, "no pthread support\n");
+#endif
+
+ /*
+ * Be nasty and taste for the worst case: ensure all threads start with
+ * SIGCHLD unblocked so we have the most fun with SIGCHLD being
+ * delivered to a random thread. :)
+ */
+ sigemptyset(&set);
+ sigaddset(&set, SIGCHLD);
+#ifdef HAVE_PTHREAD
+ ret = pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+#else
+ ret = sigprocmask(SIG_UNBLOCK, &set, NULL);
+#endif
+ if (ret != 0) {
+ return false;
+ }
+
+ for (i = 0; i < num_threads; i++) {
+ ret = pthread_create(&threads[i], NULL, tfork_thread, NULL);
+ torture_assert_goto(tctx, ret == 0, ok, done,
+ "pthread_create failed\n");
+ }
+
+ for (i = 0; i < num_threads; i++) {
+ void *p;
+ uint64_t *result;
+
+ ret = pthread_join(threads[i], &p);
+ torture_assert_goto(tctx, ret == 0, ok, done,
+ "pthread_join failed\n");
+ result = (uint64_t *)p;
+ torture_assert_goto(tctx, *result == (uint64_t)threads[i] + 1,
+ ok, done, "thread failed\n");
+ free(p);
+ }
+
+done:
+ return ok;
+}
+
+static bool test_tfork_cmd_send(struct torture_context *tctx)
+{
+ struct tevent_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ const char *cmd[2] = { NULL, NULL };
+ bool ok = true;
+
+ ev = tevent_context_init(tctx);
+ torture_assert_goto(tctx, ev != NULL, ok, done,
+ "tevent_context_init failed\n");
+
+ cmd[0] = talloc_asprintf(tctx, "%s/testprogs/blackbox/tfork.sh", SRCDIR);
+ torture_assert_goto(tctx, cmd[0] != NULL, ok, done,
+ "talloc_asprintf failed\n");
+
+ req = samba_runcmd_send(tctx, ev, timeval_zero(), 0, 0,
+ cmd, "foo", NULL);
+ torture_assert_goto(tctx, req != NULL, ok, done,
+ "samba_runcmd_send failed\n");
+
+ ok = tevent_req_poll(req, ev);
+ torture_assert_goto(tctx, ok, ok, done, "tevent_req_poll failed\n");
+
+ torture_comment(tctx, "samba_runcmd_send test finished\n");
+
+done:
+ TALLOC_FREE(ev);
+
+ return ok;
+}
+
+/*
+ * Test to ensure that the event_fd becomes readable after
+ * a tfork_process terminates.
+ */
+static bool test_tfork_event_file_handle(struct torture_context *tctx)
+{
+ bool ok = true;
+
+ struct tfork *t1 = NULL;
+ pid_t child1;
+ struct pollfd poll1[] = {
+ {
+ .fd = -1,
+ .events = POLLIN,
+ },
+ };
+
+ struct tfork *t2 = NULL;
+ pid_t child2;
+ struct pollfd poll2[] = {
+ {
+ .fd = -1,
+ .events = POLLIN,
+ },
+ };
+
+
+ t1 = tfork_create();
+ if (t1 == NULL) {
+ torture_fail(tctx, "tfork failed\n");
+ return false;
+ }
+
+ child1 = tfork_child_pid(t1);
+ if (child1 == 0) {
+ /*
+ * Parent process will kill this with a SIGTERM
+ * so 10 seconds should be plenty
+ */
+ sleep(10);
+ exit(1);
+ }
+ poll1[0].fd = tfork_event_fd(t1);
+
+ t2 = tfork_create();
+ if (t2 == NULL) {
+ torture_fail(tctx, "tfork failed\n");
+ return false;
+ }
+ child2 = tfork_child_pid(t2);
+ if (child2 == 0) {
+ /*
+ * Parent process will kill this with a SIGTERM
+ * so 10 seconds should be plenty
+ */
+ sleep(10);
+ exit(2);
+ }
+ poll2[0].fd = tfork_event_fd(t2);
+
+ /*
+ * Have forked two process and are in the master process
+ * Expect that both event_fds are unreadable
+ */
+ poll(poll1, 1, 0);
+ ok = !(poll1[0].revents & POLLIN);
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork process 1 event fd readable\n");
+ poll(poll2, 1, 0);
+ ok = !(poll2[0].revents & POLLIN);
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork process 1 event fd readable\n");
+
+ /* Kill the first child process */
+ kill(child1, SIGKILL);
+ sleep(1);
+
+ /*
+ * Have killed the first child, so expect it's event_fd to have gone
+ * readable.
+ *
+ */
+ poll(poll1, 1, 0);
+ ok = (poll1[0].revents & POLLIN);
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork process 1 event fd not readable\n");
+ poll(poll2, 1, 0);
+ ok = !(poll2[0].revents & POLLIN);
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork process 2 event fd readable\n");
+
+ /* Kill the secind child process */
+ kill(child2, SIGKILL);
+ sleep(1);
+ /*
+ * Have killed the children, so expect their event_fd's to have gone
+ * readable.
+ *
+ */
+ poll(poll1, 1, 0);
+ ok = (poll1[0].revents & POLLIN);
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork process 1 event fd not readable\n");
+ poll(poll2, 1, 0);
+ ok = (poll2[0].revents & POLLIN);
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork process 2 event fd not readable\n");
+
+done:
+ free(t1);
+ free(t2);
+
+ return ok;
+}
+
+/*
+ * Test to ensure that the status calls behave as expected after a process
+ * terminates.
+ *
+ * As the parent process owns the status fd's they get passed to all
+ * subsequent children after a tfork. So it's possible for another
+ * child process to hold the status pipe open.
+ *
+ * The event fd needs to be left open by tfork, as a close in the status
+ * code can cause issues in tevent code.
+ *
+ */
+static bool test_tfork_status_handle(struct torture_context *tctx)
+{
+ bool ok = true;
+
+ struct tfork *t1 = NULL;
+ pid_t child1;
+
+ struct tfork *t2 = NULL;
+ pid_t child2;
+
+ int status;
+ int fd;
+ int ev1_fd;
+ int ev2_fd;
+
+
+ t1 = tfork_create();
+ if (t1 == NULL) {
+ torture_fail(tctx, "tfork failed\n");
+ return false;
+ }
+
+ child1 = tfork_child_pid(t1);
+ if (child1 == 0) {
+ /*
+ * Parent process will kill this with a SIGTERM
+ * so 10 seconds should be plenty
+ */
+ sleep(10);
+ exit(1);
+ }
+ ev1_fd = tfork_event_fd(t1);
+
+ t2 = tfork_create();
+ if (t2 == NULL) {
+ torture_fail(tctx, "tfork failed\n");
+ return false;
+ }
+ child2 = tfork_child_pid(t2);
+ if (child2 == 0) {
+ /*
+ * Parent process will kill this with a SIGTERM
+ * so 10 seconds should be plenty
+ */
+ sleep(10);
+ exit(2);
+ }
+ ev2_fd = tfork_event_fd(t2);
+
+ /*
+ * Have forked two process and are in the master process
+ * expect that the status call will block, and hence return -1
+ * as the processes are still running
+ * The event fd's should be open.
+ */
+ status = tfork_status(&t1, false);
+ ok = status == -1;
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork status available for non terminated "
+ "process 1\n");
+ /* Is the event fd open? */
+ fd = dup(ev1_fd);
+ ok = fd != -1;
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork process 1 event fd is not open");
+
+ status = tfork_status(&t2, false);
+ ok = status == -1;
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork status available for non terminated "
+ "process 2\n");
+ /* Is the event fd open? */
+ fd = dup(ev2_fd);
+ ok = fd != -1;
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork process 2 event fd is not open");
+
+ /*
+ * Kill the first process, it's status should be readable
+ * and it's event_fd should be open
+ * The second process's status should be unreadable.
+ */
+ kill(child1, SIGTERM);
+ sleep(1);
+ status = tfork_status(&t1, false);
+ ok = status != -1;
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork status for child 1 not available after "
+ "termination\n");
+ /* Is the event fd open? */
+ fd = dup(ev2_fd);
+ ok = fd != -1;
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork process 1 event fd is not open");
+
+ status = tfork_status(&t2, false);
+ ok = status == -1;
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork status available for child 2 after "
+ "termination of child 1\n");
+
+ /*
+ * Kill the second process, it's status should be readable
+ */
+ kill(child2, SIGTERM);
+ sleep(1);
+ status = tfork_status(&t2, false);
+ ok = status != -1;
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork status for child 2 not available after "
+ "termination\n");
+
+ /* Check that the event fd's are still open */
+ /* Is the event fd open? */
+ fd = dup(ev1_fd);
+ ok = fd != -1;
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork process 1 event fd is not open");
+ /* Is the event fd open? */
+ fd = dup(ev2_fd);
+ ok = fd != -1;
+ torture_assert_goto(tctx, ok, ok, done,
+ "tfork process 2 event fd is not open");
+
+done:
+ return ok;
+}
+
+struct torture_suite *torture_local_tfork(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite =
+ torture_suite_create(mem_ctx, "tfork");
+
+ torture_suite_add_simple_test(suite,
+ "tfork_simple",
+ test_tfork_simple);
+
+ torture_suite_add_simple_test(suite,
+ "tfork_status",
+ test_tfork_status);
+
+ torture_suite_add_simple_test(suite,
+ "tfork_sigign",
+ test_tfork_sigign);
+
+ torture_suite_add_simple_test(suite,
+ "tfork_sighandler",
+ test_tfork_sighandler);
+
+ torture_suite_add_simple_test(suite,
+ "tfork_process_hierarchy",
+ test_tfork_process_hierarchy);
+
+ torture_suite_add_simple_test(suite,
+ "tfork_pipe",
+ test_tfork_pipe);
+
+ torture_suite_add_simple_test(suite,
+ "tfork_twice",
+ test_tfork_twice);
+
+ torture_suite_add_simple_test(suite,
+ "tfork_threads",
+ test_tfork_threads);
+
+ torture_suite_add_simple_test(suite,
+ "tfork_cmd_send",
+ test_tfork_cmd_send);
+
+ torture_suite_add_simple_test(suite,
+ "tfork_event_file_handle",
+ test_tfork_event_file_handle);
+
+ torture_suite_add_simple_test(suite,
+ "tfork_status_handle",
+ test_tfork_status_handle);
+
+ return suite;
+}
diff --git a/lib/util/tests/time.c b/lib/util/tests/time.c
new file mode 100644
index 0000000..ec27f56
--- /dev/null
+++ b/lib/util/tests/time.c
@@ -0,0 +1,151 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ util time testing
+
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+
+static bool test_null_time(struct torture_context *tctx)
+{
+ torture_assert(tctx, null_time(0), "0");
+ torture_assert(tctx, null_time(0xFFFFFFFF), "0xFFFFFFFF");
+ torture_assert(tctx, null_time(-1), "-1");
+ torture_assert(tctx, !null_time(42), "42");
+ return true;
+}
+
+static bool test_null_nttime(struct torture_context *tctx)
+{
+ torture_assert(tctx, null_nttime(0), "0");
+ torture_assert(tctx, !null_nttime(NTTIME_FREEZE), "-1");
+ torture_assert(tctx, !null_nttime(NTTIME_THAW), "-2");
+ torture_assert(tctx, !null_nttime(42), "42");
+ return true;
+}
+
+
+static bool test_http_timestring(struct torture_context *tctx)
+{
+ const char *start = "Thu, 01 Jan 1970";
+ char *result;
+ /*
+ * Correct test for negative UTC offset. Without the correction, the
+ * test fails when run on hosts with negative UTC offsets, as the date
+ * returned is back in 1969 (pre-epoch).
+ */
+ time_t now = time(NULL);
+ struct tm local = *localtime(&now);
+ struct tm gmt = *gmtime(&now);
+ time_t utc_offset = mktime(&local) - mktime(&gmt);
+
+ result = http_timestring(tctx, 42 - (utc_offset < 0 ? utc_offset : 0));
+ torture_assert(tctx, !strncmp(start, result,
+ strlen(start)), result);
+ torture_assert_str_equal(tctx, "never",
+ http_timestring(tctx, get_time_t_max()), "42");
+ return true;
+}
+
+static bool test_timestring(struct torture_context *tctx)
+{
+ const char *start = "Thu Jan 1";
+ char *result;
+ /*
+ * Correct test for negative UTC offset. Without the correction, the
+ * test fails when run on hosts with negative UTC offsets, as the date
+ * returned is back in 1969 (pre-epoch).
+ */
+ time_t now = time(NULL);
+ struct tm local = *localtime(&now);
+ struct tm gmt = *gmtime(&now);
+ time_t utc_offset = mktime(&local) - mktime(&gmt);
+
+ result = timestring(tctx, 42 - (utc_offset < 0 ? utc_offset : 0));
+ torture_assert(tctx, !strncmp(start, result, strlen(start)), result);
+ return true;
+}
+
+static bool test_normalize_timespec(struct torture_context *tctx)
+{
+ const struct {
+ time_t in_s; long in_ns;
+ time_t out_s; long out_ns;
+ } data [] = {
+ { 0, 0, 0, 0 }
+ , { 1, 0, 1, 0 }
+ , { -1, 0, -1, 0 }
+ , { 0, 1000000000, 1, 0 }
+ , { 0, 2000000000, 2, 0 }
+ , { 0, 1000000001, 1, 1 }
+ , { 0, 2000000001, 2, 1 }
+ , { 0, -1000000000, -1, 0 }
+ , { 0, -2000000000, -2, 0 }
+ , { 0, -1000000001, -2, 999999999 }
+ , { 0, -2000000001, -3, 999999999 }
+ , { 0, -1, -1, 999999999 }
+ , { 1, -1, 0, 999999999 }
+ , { -1, -1, -2, 999999999 }
+ , { 0, 999999999, 0, 999999999 }
+ , { 0, 1999999999, 1, 999999999 }
+ , { 0, 2999999999, 2, 999999999 }
+ , { 0, -999999999, -1, 1 }
+ , { 0, -1999999999, -2, 1 }
+ , { 0, -2999999999, -3, 1 }
+ , { LONG_MAX, 1000000001, LONG_MAX, 999999999 } /* overflow */
+ , { LONG_MAX, 999999999, LONG_MAX, 999999999 } /* harmless */
+ , { LONG_MAX, -1, LONG_MAX-1, 999999999 } /* -1 */
+ , { LONG_MIN, -1000000001, LONG_MIN, 0 } /* overflow */
+ , { LONG_MIN, 0, LONG_MIN, 0 } /* harmless */
+ , { LONG_MIN, 1000000000, LONG_MIN+1, 0 } /* +1 */
+ };
+ int i;
+
+ for (i = 0; i < sizeof(data) / sizeof(data[0]); ++i) {
+ struct timespec ts = (struct timespec)
+ { .tv_sec = data[i].in_s
+ , .tv_nsec = data[i].in_ns };
+
+ normalize_timespec(&ts);
+
+ torture_assert_int_equal(tctx, ts.tv_sec, data[i].out_s,
+ "mismatch in tv_sec");
+ torture_assert_int_equal(tctx, ts.tv_nsec, data[i].out_ns,
+ "mismatch in tv_nsec");
+ }
+
+ return true;
+}
+
+struct torture_suite *torture_local_util_time(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "time");
+
+ torture_suite_add_simple_test(suite, "null_time", test_null_time);
+ torture_suite_add_simple_test(suite, "null_nttime", test_null_nttime);
+ torture_suite_add_simple_test(suite, "http_timestring",
+ test_http_timestring);
+ torture_suite_add_simple_test(suite, "timestring",
+ test_timestring);
+ torture_suite_add_simple_test(suite, "normalize_timespec",
+ test_normalize_timespec);
+
+ return suite;
+}
diff --git a/lib/util/tests/util.c b/lib/util/tests/util.c
new file mode 100644
index 0000000..0b69e21
--- /dev/null
+++ b/lib/util/tests/util.c
@@ -0,0 +1,652 @@
+/*
+ * Tests for strv_util
+ *
+ * Copyright Martin Schwenke <martin@meltin.net> 2016
+ * Copyright Christof Schmitt <cs@samba.org> 2018
+ * Copyright Swen Schillig <swen@linux.ibm.com> 2019
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <talloc.h>
+
+#include "replace.h"
+#include "system/filesys.h"
+
+#include "libcli/util/ntstatus.h"
+#include "torture/torture.h"
+#include "lib/util/data_blob.h"
+#include "torture/local/proto.h"
+
+#include "lib/util/samba_util.h"
+#include "lib/util/smb_strtox.h"
+
+#include "limits.h"
+#include "string.h"
+
+struct test_trim_string_data {
+ const char *desc;
+ const char *in;
+ const char *front;
+ const char *back;
+ const char *out;
+ bool ret;
+};
+
+static const struct test_trim_string_data test_trim_string_data[] = {
+ {
+ .desc = "All NULL",
+ .in = NULL,
+ .front = NULL,
+ .back = NULL,
+ .out = NULL,
+ .ret = false,
+ },
+ {
+ .desc = "Input NULL",
+ .in = NULL,
+ .front = "abc",
+ .back = "123",
+ .out = NULL,
+ .ret = false,
+ },
+ {
+ .desc = "Trim NULL",
+ .in = "abc",
+ .front = NULL,
+ .back = NULL,
+ .out = "abc",
+ .ret = false,
+ },
+ {
+ .desc = "Trim empty",
+ .in = "abc",
+ .front = "",
+ .back = "",
+ .out = "abc",
+ .ret = false,
+ },
+ {
+ .desc = "Trim front, non-matching",
+ .in = "abc",
+ .front = "x",
+ .back = "",
+ .out = "abc",
+ .ret = false,
+ },
+ {
+ .desc = "Trim front, matches back",
+ .in = "abc",
+ .front = "c",
+ .back = "",
+ .out = "abc",
+ .ret = false,
+ },
+ {
+ .desc = "Trim front, partial-match",
+ .in = "abc",
+ .front = "ac",
+ .back = "",
+ .out = "abc",
+ .ret = false,
+ },
+ {
+ .desc = "Trim front, too long",
+ .in = "aaa",
+ .front = "aaaa",
+ .back = "",
+ .out = "aaa",
+ .ret = false,
+ },
+ {
+ .desc = "Trim front, 1 char, 1x",
+ .in = "abc",
+ .front = "a",
+ .back = "",
+ .out = "bc",
+ .ret = true,
+ },
+ {
+ .desc = "Trim front, 1 char, 2x",
+ .in = "aabc",
+ .front = "a",
+ .back = "",
+ .out = "bc",
+ .ret = true,
+ },
+ {
+ .desc = "Trim front, 1 char, 3x",
+ .in = "aaabc",
+ .front = "a",
+ .back = "",
+ .out = "bc",
+ .ret = true,
+ },
+ {
+ .desc = "Trim front, 1 char, matches all",
+ .in = "aaa",
+ .front = "a",
+ .back = "",
+ .out = "",
+ .ret = true,
+ },
+ {
+ .desc = "Trim front, 2 chars, 1x",
+ .in = "abc",
+ .front = "ab",
+ .back = "",
+ .out = "c",
+ .ret = true,
+ },
+ {
+ .desc = "Trim front, 2 chars, 2x",
+ .in = "ababc",
+ .front = "ab",
+ .back = "",
+ .out = "c",
+ .ret = true,
+ },
+ {
+ .desc = "Trim front, 3 chars, matches all",
+ .in = "abc",
+ .front = "abc",
+ .back = "",
+ .out = "",
+ .ret = true,
+ },
+ {
+ .desc = "Trim back, non-matching",
+ .in = "abc",
+ .front = "",
+ .back = "x",
+ .out = "abc",
+ .ret = false,
+ },
+ {
+ .desc = "Trim back, matches front",
+ .in = "abc",
+ .front = "",
+ .back = "a",
+ .out = "abc",
+ .ret = false,
+ },
+ {
+ .desc = "Trim back, partial-match",
+ .in = "abc",
+ .front = "",
+ .back = "xc",
+ .out = "abc",
+ .ret = false,
+ },
+ {
+ .desc = "Trim back, too long",
+ .in = "aaa",
+ .front = "",
+ .back = "aaaa",
+ .out = "aaa",
+ .ret = false,
+ },
+ {
+ .desc = "Trim back, 1 char, 1x",
+ .in = "abc",
+ .front = "",
+ .back = "c",
+ .out = "ab",
+ .ret = true,
+ },
+ {
+ .desc = "Trim back, 1 char, 2x",
+ .in = "abcc",
+ .front = "",
+ .back = "c",
+ .out = "ab",
+ .ret = true,
+ },
+ {
+ .desc = "Trim back, 1 char, 3x",
+ .in = "abccc",
+ .front = "",
+ .back = "c",
+ .out = "ab",
+ .ret = true,
+ },
+ {
+ .desc = "Trim back, 1 char, matches all",
+ .in = "aaa",
+ .front = "",
+ .back = "a",
+ .out = "",
+ .ret = true,
+ },
+ {
+ .desc = "Trim back, 2 chars, 1x",
+ .in = "abc",
+ .front = "",
+ .back = "bc",
+ .out = "a",
+ .ret = true,
+ },
+ {
+ .desc = "Trim back, 2 chars, 2x",
+ .in = "abcbc",
+ .front = "",
+ .back = "bc",
+ .out = "a",
+ .ret = true,
+ },
+ {
+ .desc = "Trim back, 3 chars, matches all",
+ .in = "abc",
+ .front = "",
+ .back = "abc",
+ .out = "",
+ .ret = true,
+ },
+ {
+ .desc = "Trim both, non-matching",
+ .in = "abc",
+ .front = "x",
+ .back = "y",
+ .out = "abc",
+ .ret = false,
+ },
+ {
+ .desc = "Trim both, reversed",
+ .in = "abc",
+ .front = "c",
+ .back = "a",
+ .out = "abc",
+ .ret = false,
+ },
+ {
+ .desc = "Trim both, 1 char, 1x",
+ .in = "abc",
+ .front = "a",
+ .back = "c",
+ .out = "b",
+ .ret = true,
+ },
+ {
+ .desc = "Trim both, 1 char, 2x",
+ .in = "aabcc",
+ .front = "a",
+ .back = "c",
+ .out = "b",
+ .ret = true,
+ },
+ {
+ .desc = "Trim both, 1 char, 3x",
+ .in = "aaabccc",
+ .front = "a",
+ .back = "c",
+ .out = "b",
+ .ret = true,
+ },
+ {
+ .desc = "Trim both, 1 char, matches all",
+ .in = "aaabbb",
+ .front = "a",
+ .back = "b",
+ .out = "",
+ .ret = true,
+ },
+ {
+ .desc = "Trim both, 2 chars, 1x",
+ .in = "abxbc",
+ .front = "ab",
+ .back = "bc",
+ .out = "x",
+ .ret = true,
+ },
+ {
+ .desc = "Trim both, 2 chars, 2x",
+ .in = "ababxyzbcbc",
+ .front = "ab",
+ .back = "bc",
+ .out = "xyz",
+ .ret = true,
+ },
+ {
+ .desc = "Trim both, 2 chars, front matches, back doesn't",
+ .in = "abcde",
+ .front = "ab",
+ .back = "xy",
+ .out = "cde",
+ .ret = true,
+ },
+ {
+ .desc = "Trim both, 2 chars, back matches, front doesn't",
+ .in = "abcde",
+ .front = "xy",
+ .back = "de",
+ .out = "abc",
+ .ret = true,
+ },
+ {
+ .desc = "Trim back, 3 chars, matches all",
+ .in = "abcxyz",
+ .front = "abc",
+ .back = "xyz",
+ .out = "",
+ .ret = true,
+ },
+};
+
+static bool test_trim_string(struct torture_context *tctx)
+{
+ int j;
+ for (j = 0; j < ARRAY_SIZE(test_trim_string_data); j++) {
+ bool ret;
+ const struct test_trim_string_data *d =
+ &test_trim_string_data[j];
+ char *str = talloc_strdup(tctx, d->in);
+ torture_assert(tctx, d->in == NULL || str != NULL,
+ "Out of memory");
+
+ torture_comment(tctx, "%s\n", d->desc);
+ ret = trim_string(str, d->front, d->back);
+ torture_assert(tctx, ret == d->ret,
+ "Incorrect return from trim_string()");
+ if (d->out == NULL) {
+ torture_assert(tctx, str == NULL, "Expected NULL");
+ } else {
+ torture_assert(tctx, str != NULL, "Expected non-NULL");
+ torture_assert_str_equal(tctx, str, d->out,
+ "Incorrect output");
+ }
+ TALLOC_FREE(str);
+ }
+
+ return true;
+}
+
+static bool test_directory_create_or_exist(struct torture_context *tctx)
+{
+ char *path = NULL, *new_path = NULL, *file_path = NULL;
+ bool ret = true, b = true;
+ int fd;
+ NTSTATUS status;
+ const mode_t perms = 0741;
+
+ status = torture_temp_dir(tctx, "util_dir", &path);;
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
+ "Creating test directory failed.\n");
+
+ b = directory_create_or_exist(path, perms);
+ torture_assert_goto(tctx, b == true, ret, done,
+ "directory_create_or_exist on "
+ "existing directory failed.\n");
+
+ new_path = talloc_asprintf(tctx, "%s/%s", path, "dir");
+ torture_assert_goto(tctx, new_path != NULL, ret, done,
+ "Could not allocate memory for directory path\n");
+
+ b = directory_exist(new_path);
+ torture_assert_goto(tctx, b == false, ret, done,
+ "Check for non-existing directory failed.\n");
+
+ b = directory_create_or_exist(new_path, perms);
+ torture_assert_goto(tctx, b == true, ret, done,
+ "directory_create_or_exist for "
+ "new directory failed.\n");
+
+ b = directory_exist(new_path);
+ torture_assert_goto(tctx, b == true, ret, done,
+ "Check for existing directory failed.\n");
+
+ b = file_check_permissions(new_path, geteuid(), perms, NULL);
+ torture_assert_goto(tctx, b == true, ret, done,
+ "Permission check for directory failed.\n");
+
+ file_path = talloc_asprintf(tctx, "%s/%s", path, "file");
+ torture_assert_goto(tctx, file_path != NULL, ret, done,
+ "Could not allocate memory for file path\n");
+ fd = creat(file_path, perms);
+ torture_assert_goto(tctx, fd != -1, ret, done,
+ "Creating file failed.\n");
+ close(fd);
+
+ b = directory_create_or_exist(file_path, perms);
+ torture_assert_goto(tctx, b == false, ret, done,
+ "directory_create_or_exist for "
+ "existing file failed.\n");
+
+done:
+ return ret;
+}
+
+static bool test_mem_equal_const_time(struct torture_context *tctx)
+{
+ const char *test_string = "abcdabcd";
+
+ torture_assert(tctx, mem_equal_const_time("", "", 0),
+ "zero-length comparison failed");
+
+ torture_assert(tctx, mem_equal_const_time(test_string, test_string, 8),
+ "comparison with equal pointers failed");
+
+ torture_assert(tctx, mem_equal_const_time(test_string, test_string + 4, 4),
+ "comparison with non-equal pointers failed");
+
+ torture_assert(tctx, !mem_equal_const_time("abcd", "efgh", 4),
+ "comparison with different values failed");
+
+ return true;
+}
+
+static bool test_smb_strtoul_errno_check(struct torture_context *tctx)
+{
+ const char *number = "123";
+ unsigned long int val = 0;
+ unsigned long long int vall = 0;
+ int err;
+
+ /* select an error code which is not set by the smb_strtoul routines */
+ errno = EAGAIN;
+ err = EAGAIN;
+ val = smb_strtoul(number, NULL, 0, &err, SMB_STR_STANDARD);
+ torture_assert(tctx, errno == EAGAIN, "smb_strtoul: Expected EAGAIN");
+ torture_assert(tctx, err == 0, "smb_strtoul: Expected err = 0");
+ torture_assert(tctx, val == 123, "smb_strtoul: Expected value 123");
+
+ /* set err to an impossible value again before continuing */
+ err = EAGAIN;
+ vall = smb_strtoull(number, NULL, 0, &err, SMB_STR_STANDARD);
+ torture_assert(tctx, errno == EAGAIN, "smb_strtoull: Expected EAGAIN");
+ torture_assert(tctx, err == 0, "smb_strtoul: Expected err = 0");
+ torture_assert(tctx, vall == 123, "smb_strtoul: Expected value 123");
+
+ return true;
+}
+
+static bool test_smb_strtoul_negative(struct torture_context *tctx)
+{
+ const char *number = "-132";
+ const char *number2 = "132-";
+ unsigned long int val = 0;
+ unsigned long long int vall = 0;
+ int err;
+
+ err = 0;
+ smb_strtoul(number, NULL, 0, &err, SMB_STR_STANDARD);
+ torture_assert(tctx, err == EINVAL, "smb_strtoul: Expected EINVAL");
+
+ err = 0;
+ smb_strtoull(number, NULL, 0, &err, SMB_STR_STANDARD);
+ torture_assert(tctx, err == EINVAL, "smb_strtoull: Expected EINVAL");
+
+ /* it is allowed to have a "-" sign after a number,
+ * e.g. as part of a formular, however, it is not supposed to
+ * have an effect on the converted value.
+ */
+
+ err = 0;
+ val = smb_strtoul(number2, NULL, 0, &err, SMB_STR_STANDARD);
+ torture_assert(tctx, err == 0, "smb_strtoul: Expected no error");
+ torture_assert(tctx, val == 132, "smb_strtoul: Wrong value");
+
+ err = 0;
+ vall = smb_strtoull(number2, NULL, 0, &err, SMB_STR_STANDARD);
+ torture_assert(tctx, err == 0, "smb_strtoull: Expected no error");
+ torture_assert(tctx, vall == 132, "smb_strtoull: Wrong value");
+
+ return true;
+}
+
+static bool test_smb_strtoul_no_number(struct torture_context *tctx)
+{
+ const char *number = "ghijk";
+ const char *blank = "";
+ int err;
+
+ err = 0;
+ smb_strtoul(number, NULL, 0, &err, SMB_STR_STANDARD);
+ torture_assert(tctx, err == EINVAL, "smb_strtoul: Expected EINVAL");
+
+ err = 0;
+ smb_strtoull(number, NULL, 0, &err, SMB_STR_STANDARD);
+ torture_assert(tctx, err == EINVAL, "smb_strtoull: Expected EINVAL");
+
+ err = 0;
+ smb_strtoul(blank, NULL, 0, &err, SMB_STR_STANDARD);
+ torture_assert(tctx, err == EINVAL, "smb_strtoul: Expected EINVAL");
+
+ err = 0;
+ smb_strtoull(blank, NULL, 0, &err, SMB_STR_STANDARD);
+ torture_assert(tctx, err == EINVAL, "smb_strtoull: Expected EINVAL");
+
+ return true;
+}
+
+static bool test_smb_strtoul_allow_negative(struct torture_context *tctx)
+{
+ const char *number = "-1";
+ const char *number2 = "-1-1";
+ unsigned long res = 0;
+ unsigned long long res2 = 0;
+ char *end_ptr = NULL;
+ int err;
+
+ err = 0;
+ res = smb_strtoul(number, NULL, 0, &err, SMB_STR_ALLOW_NEGATIVE);
+ torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
+ torture_assert(tctx, res == ULONG_MAX, "strtoul_err: Unexpected value");
+
+ err = 0;
+ res2 = smb_strtoull(number, NULL, 0, &err, SMB_STR_ALLOW_NEGATIVE);
+ torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
+ torture_assert(tctx, res2 == ULLONG_MAX, "strtoull_err: Unexpected value");
+
+ err = 0;
+ smb_strtoul(number2, &end_ptr, 0, &err, SMB_STR_ALLOW_NEGATIVE);
+ torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
+ torture_assert(tctx, end_ptr[0] == '-', "strtoul_err: Unexpected end pointer");
+
+ err = 0;
+ smb_strtoull(number2, &end_ptr, 0, &err, SMB_STR_ALLOW_NEGATIVE);
+ torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
+ torture_assert(tctx, end_ptr[0] == '-', "strtoull_err: Unexpected end pointer");
+
+ return true;
+}
+
+static bool test_smb_strtoul_full_string(struct torture_context *tctx)
+{
+ const char *number = "123 ";
+ const char *number2 = "123";
+ int err;
+
+ err = 0;
+ smb_strtoul(number, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
+ torture_assert(tctx, err == EINVAL, "strtoul_err: Expected EINVAL");
+
+ err = 0;
+ smb_strtoull(number, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
+ torture_assert(tctx, err == EINVAL, "strtoull_err: Expected EINVAL");
+
+ err = 0;
+ smb_strtoul(number2, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
+ torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
+
+ err = 0;
+ smb_strtoull(number2, NULL, 0, &err, SMB_STR_FULL_STR_CONV);
+ torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
+
+ return true;
+}
+
+static bool test_smb_strtoul_allow_no_conversion(struct torture_context *tctx)
+{
+ const char *number = "";
+ const char *number2 = "xyz";
+ unsigned long int n1 = 0;
+ unsigned long long int n2 = 0;
+ int err;
+
+ err = 0;
+ smb_strtoul(number, NULL, 0, &err, SMB_STR_ALLOW_NO_CONVERSION);
+ torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
+ torture_assert(tctx, n1 == 0, "strtoul_err: Unexpected value");
+
+ err = 0;
+ smb_strtoull(number, NULL, 0, &err, SMB_STR_ALLOW_NO_CONVERSION);
+ torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
+ torture_assert(tctx, n2 == 0, "strtoull_err: Unexpected value");
+
+ err = 0;
+ smb_strtoul(number2, NULL, 0, &err, SMB_STR_ALLOW_NO_CONVERSION);
+ torture_assert(tctx, err == 0, "strtoul_err: Unexpected error");
+ torture_assert(tctx, n1 == 0, "strtoul_err: Unexpected value");
+
+ err = 0;
+ smb_strtoull(number2, NULL, 0, &err, SMB_STR_ALLOW_NO_CONVERSION);
+ torture_assert(tctx, err == 0, "strtoull_err: Unexpected error");
+ torture_assert(tctx, n2 == 0, "strtoull_err: Unexpected value");
+
+ return true;
+}
+struct torture_suite *torture_local_util(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite =
+ torture_suite_create(mem_ctx, "util");
+
+ torture_suite_add_simple_test(suite,
+ "trim_string",
+ test_trim_string);
+ torture_suite_add_simple_test(suite,
+ "directory_create_or_exist",
+ test_directory_create_or_exist);
+ torture_suite_add_simple_test(suite,
+ "mem_equal_const_time",
+ test_mem_equal_const_time);
+ torture_suite_add_simple_test(suite,
+ "smb_strtoul(l) errno",
+ test_smb_strtoul_errno_check);
+ torture_suite_add_simple_test(suite,
+ "smb_strtoul(l) negative",
+ test_smb_strtoul_negative);
+ torture_suite_add_simple_test(suite,
+ "smb_strtoul(l) no number",
+ test_smb_strtoul_no_number);
+ torture_suite_add_simple_test(suite,
+ "smb_strtoul(l) allow_negative",
+ test_smb_strtoul_allow_negative);
+ torture_suite_add_simple_test(suite,
+ "smb_strtoul(l) full string conversion",
+ test_smb_strtoul_full_string);
+ torture_suite_add_simple_test(suite,
+ "smb_strtoul(l) allow no conversion",
+ test_smb_strtoul_allow_no_conversion);
+ return suite;
+}
diff --git a/lib/util/tests/util_str_escape.c b/lib/util/tests/util_str_escape.c
new file mode 100644
index 0000000..82e2209
--- /dev/null
+++ b/lib/util/tests/util_str_escape.c
@@ -0,0 +1,90 @@
+/*
+
+ util_str_escape testing
+
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "torture/local/proto.h"
+#include "lib/util/util_str_escape.h"
+
+static bool test_log_escape_empty_string(struct torture_context *tctx)
+{
+ char *result = log_escape( tctx, "");
+ torture_assert_str_equal(tctx, result, "", "Empty string handling");
+ return true;
+}
+
+static bool test_log_escape_null_string(struct torture_context *tctx)
+{
+ char *result = log_escape( tctx, NULL);
+ torture_assert(tctx, (result == NULL), "Empty string handling");
+ return true;
+}
+
+static bool test_log_escape_plain_string(struct torture_context *tctx)
+{
+ const char *input = "a plain string with no escapable characters";
+ const char *expected = "a plain string with no escapable characters";
+
+ char *result = log_escape( tctx, input);
+ torture_assert_str_equal(tctx, result, expected,
+ "Plain string handling");
+ return true;
+}
+
+static bool test_log_escape_string(struct torture_context *tctx)
+{
+ const char *input = "\a\b\f\n\r\t\v\\\x01";
+ const char *expected = "\\a\\b\\f\\n\\r\\t\\v\\\\\\x01";
+
+ char *result = log_escape( tctx, input);
+ torture_assert_str_equal(tctx, result, expected,
+ "Escapable characters in string");
+ return true;
+}
+
+static bool test_log_escape_hex_string(struct torture_context *tctx)
+{
+ const char *input = "\x01\x1F ";
+ const char *expected = "\\x01\\x1F ";
+
+ char *result = log_escape( tctx, input);
+ torture_assert_str_equal(tctx, result, expected,
+ "hex escaping");
+ return true;
+}
+struct torture_suite *torture_local_util_str_escape(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx,
+ "util_str_escape");
+
+ torture_suite_add_simple_test(suite, "log_escape_empty_string",
+ test_log_escape_empty_string);
+ torture_suite_add_simple_test(suite, "log_escape_null_string",
+ test_log_escape_null_string);
+ torture_suite_add_simple_test(suite, "log_escape_plain_string",
+ test_log_escape_plain_string);
+ torture_suite_add_simple_test(suite, "log_escape_string",
+ test_log_escape_string);
+ torture_suite_add_simple_test(suite, "log_escape_hex_string",
+ test_log_escape_hex_string);
+
+
+ return suite;
+}
diff --git a/lib/util/tevent_debug.c b/lib/util/tevent_debug.c
new file mode 100644
index 0000000..4ec9057
--- /dev/null
+++ b/lib/util/tevent_debug.c
@@ -0,0 +1,116 @@
+/*
+ Unix SMB/CIFS implementation.
+ Copyright (C) Andrew Tridgell 2003
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include <tevent.h>
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_TEVENT
+
+static void samba_tevent_debug(void *context,
+ enum tevent_debug_level level,
+ const char *fmt,
+ va_list ap) PRINTF_ATTRIBUTE(3,0);
+
+static void samba_tevent_debug(void *context,
+ enum tevent_debug_level level,
+ const char *fmt,
+ va_list ap)
+{
+ int samba_level = -1;
+
+ switch (level) {
+ case TEVENT_DEBUG_FATAL:
+ samba_level = 0;
+ break;
+ case TEVENT_DEBUG_ERROR:
+ samba_level = 1;
+ break;
+ case TEVENT_DEBUG_WARNING:
+ samba_level = 2;
+ break;
+ case TEVENT_DEBUG_TRACE:
+ samba_level = 50;
+ break;
+ };
+
+ if (CHECK_DEBUGLVL(samba_level)) {
+ const char *name = (const char *)context;
+ char *message = NULL;
+ int ret;
+
+ ret = vasprintf(&message, fmt, ap);
+ if (ret == -1) {
+ return;
+ }
+
+ if (name == NULL) {
+ name = "samba_tevent";
+ }
+
+ DEBUG(samba_level, ("%s: %s", name, message));
+ free(message);
+ }
+}
+
+static void samba_tevent_abort_fn(const char *reason)
+{
+ smb_panic(reason);
+}
+
+static void samba_tevent_setup_abort_fn(void)
+{
+ static bool abort_fn_done;
+
+ if (!abort_fn_done) {
+ tevent_set_abort_fn(samba_tevent_abort_fn);
+ abort_fn_done = true;
+ }
+}
+
+void samba_tevent_set_debug(struct tevent_context *ev, const char *name)
+{
+ void *p = discard_const(name);
+ samba_tevent_setup_abort_fn();
+ tevent_set_debug(ev, samba_tevent_debug, p);
+
+ /* these values should match samba_tevent_debug() */
+ if (CHECK_DEBUGLVL(50)) {
+ tevent_set_max_debug_level(ev, TEVENT_DEBUG_TRACE);
+ } else if (CHECK_DEBUGLVL(2)) {
+ tevent_set_max_debug_level(ev, TEVENT_DEBUG_WARNING);
+ } else if (CHECK_DEBUGLVL(1)) {
+ tevent_set_max_debug_level(ev, TEVENT_DEBUG_ERROR);
+ } else {
+ tevent_set_max_debug_level(ev, TEVENT_DEBUG_FATAL);
+ }
+}
+
+struct tevent_context *samba_tevent_context_init(TALLOC_CTX *mem_ctx)
+{
+ struct tevent_context *ev;
+
+ samba_tevent_setup_abort_fn();
+
+ ev = tevent_context_init(mem_ctx);
+ if (ev) {
+ samba_tevent_set_debug(ev, NULL);
+ }
+
+ return ev;
+}
diff --git a/lib/util/tevent_ntstatus.c b/lib/util/tevent_ntstatus.c
new file mode 100644
index 0000000..7659f15
--- /dev/null
+++ b/lib/util/tevent_ntstatus.c
@@ -0,0 +1,114 @@
+/*
+ Unix SMB/CIFS implementation.
+ Wrap unix errno around tevent_req
+ Copyright (C) Volker Lendecke 2009
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "../replace/replace.h"
+#include "tevent_ntstatus.h"
+#include "libcli/util/error.h"
+
+#define TEVENT_NTERROR_MAGIC (0x917b5acd)
+
+bool _tevent_req_nterror(struct tevent_req *req,
+ NTSTATUS status,
+ const char *location)
+{
+ uint64_t err;
+
+ if (NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ /*
+ * I've put this variable here, because I'm not 100% certain
+ * how to correctly assign a 64-bit constant and left-shift it
+ * by 32 bits in a single expression. If anyone knows, feel
+ * free :-)
+ */
+ err = TEVENT_NTERROR_MAGIC;
+ err <<= 32;
+ err |= NT_STATUS_V(status);
+
+ return _tevent_req_error(req, err, location);
+}
+
+bool tevent_req_is_nterror(struct tevent_req *req, NTSTATUS *status)
+{
+ enum tevent_req_state state;
+ uint64_t err;
+
+ if (!tevent_req_is_error(req, &state, &err)) {
+ return false;
+ }
+ switch (state) {
+ case TEVENT_REQ_TIMED_OUT:
+ *status = NT_STATUS_IO_TIMEOUT;
+ break;
+ case TEVENT_REQ_NO_MEMORY:
+ *status = NT_STATUS_NO_MEMORY;
+ break;
+ case TEVENT_REQ_USER_ERROR:
+ if ((err >> 32) != TEVENT_NTERROR_MAGIC) {
+ abort();
+ }
+ *status = NT_STATUS(err & 0xffffffff);
+ break;
+ default:
+ *status = NT_STATUS_INTERNAL_ERROR;
+ break;
+ }
+ return true;
+}
+
+NTSTATUS tevent_req_simple_recv_ntstatus(struct tevent_req *req)
+{
+ NTSTATUS status = NT_STATUS_OK;
+
+ /*
+ * Ignore result of tevent_req_is_nterror, we're only interested in
+ * the status
+ */
+ tevent_req_is_nterror(req, &status);
+ tevent_req_received(req);
+ return status;
+}
+
+void tevent_req_simple_finish_ntstatus(struct tevent_req *subreq,
+ NTSTATUS subreq_status)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+
+ TALLOC_FREE(subreq);
+
+ if (!NT_STATUS_IS_OK(subreq_status)) {
+ tevent_req_nterror(req, subreq_status);
+ return;
+ }
+ tevent_req_done(req);
+}
+
+bool tevent_req_poll_ntstatus(struct tevent_req *req,
+ struct tevent_context *ev,
+ NTSTATUS *status)
+{
+ bool ret = tevent_req_poll(req, ev);
+ if (!ret) {
+ *status = map_nt_error_from_unix_common(errno);
+ }
+ return ret;
+}
diff --git a/lib/util/tevent_ntstatus.h b/lib/util/tevent_ntstatus.h
new file mode 100644
index 0000000..570b6f9
--- /dev/null
+++ b/lib/util/tevent_ntstatus.h
@@ -0,0 +1,47 @@
+/*
+ Unix SMB/CIFS implementation.
+ Wrap unix errno around tevent_req
+ Copyright (C) Volker Lendecke 2009
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _TEVENT_NTSTATUS_H
+#define _TEVENT_NTSTATUS_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "../libcli/util/ntstatus.h"
+#include <tevent.h>
+
+bool _tevent_req_nterror(struct tevent_req *req,
+ NTSTATUS status,
+ const char *location);
+#define tevent_req_nterror(req, status) \
+ _tevent_req_nterror(req, status, __location__)
+bool tevent_req_is_nterror(struct tevent_req *req, NTSTATUS *pstatus);
+NTSTATUS tevent_req_simple_recv_ntstatus(struct tevent_req *req);
+
+/*
+ * Helper routine to pass the subreq_ntstatus to the req embedded in
+ * tevent_req_callback_data(subreq), which will be freed.
+ */
+void tevent_req_simple_finish_ntstatus(struct tevent_req *subreq,
+ NTSTATUS subreq_status);
+
+bool tevent_req_poll_ntstatus(struct tevent_req *req,
+ struct tevent_context *ev,
+ NTSTATUS *status);
+
+#endif
diff --git a/lib/util/tevent_req_profile.c b/lib/util/tevent_req_profile.c
new file mode 100644
index 0000000..2d280f7
--- /dev/null
+++ b/lib/util/tevent_req_profile.c
@@ -0,0 +1,506 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Helpers around tevent_req_profile
+ *
+ * Copyright (C) Volker Lendecke 2018
+ *
+ * ** NOTE! The following LGPL license applies to the tevent
+ * ** library. This does NOT imply that all of Samba is released
+ * ** under the LGPL
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include <tevent.h>
+#include "lib/util/tevent_req_profile.h"
+#include "lib/util/time_basic.h"
+#include "lib/util/memory.h"
+
+static bool tevent_req_profile_string_internal(
+ const struct tevent_req_profile *profile,
+ unsigned indent,
+ unsigned max_indent,
+ char **string)
+{
+ struct timeval start, stop, diff;
+ struct timeval_buf start_buf, stop_buf;
+ const char *req_name = NULL;
+ const char *start_location = NULL;
+ const char *stop_location = NULL;
+ pid_t pid;
+ enum tevent_req_state state;
+ const char *state_buf = NULL;
+ uint64_t user_error;
+ const struct tevent_req_profile *sub = NULL;
+ char *result;
+
+ tevent_req_profile_get_name(profile, &req_name);
+
+ tevent_req_profile_get_start(profile, &start_location, &start);
+ timeval_str_buf(&start, false, true, &start_buf);
+
+ tevent_req_profile_get_stop(profile, &stop_location, &stop);
+ timeval_str_buf(&stop, false, true, &stop_buf);
+
+ diff = tevent_timeval_until(&start, &stop);
+
+ tevent_req_profile_get_status(profile, &pid, &state, &user_error);
+
+ switch(state) {
+ case TEVENT_REQ_INIT:
+ state_buf = "TEVENT_REQ_INIT";
+ break;
+ case TEVENT_REQ_IN_PROGRESS:
+ state_buf = "TEVENT_REQ_IN_PROGRESS";
+ break;
+ case TEVENT_REQ_DONE:
+ state_buf = "TEVENT_REQ_DONE";
+ break;
+ case TEVENT_REQ_USER_ERROR:
+ state_buf = "TEVENT_REQ_USER_ERROR";
+ break;
+ case TEVENT_REQ_TIMED_OUT:
+ state_buf = "TEVENT_REQ_TIMED_OUT";
+ break;
+ case TEVENT_REQ_NO_MEMORY:
+ state_buf = "TEVENT_REQ_NO_MEMORY";
+ break;
+ case TEVENT_REQ_RECEIVED:
+ state_buf = "TEVENT_REQ_RECEIVED";
+ break;
+ default:
+ state_buf = "unknown";
+ break;
+ }
+
+ result = talloc_asprintf_append_buffer(
+ *string,
+ "%*s[%s] %s [%s] %s [%s] [%ju.%.6ju] -> %s (%d %"PRIu64"))\n",
+ indent,
+ "",
+ req_name,
+ start_location,
+ start_buf.buf,
+ stop_location,
+ stop_buf.buf,
+ (uintmax_t)diff.tv_sec,
+ (uintmax_t)diff.tv_usec,
+ state_buf,
+ (int)state,
+ user_error);
+ if (result == NULL) {
+ return false;
+ }
+ *string = result;
+
+ indent += 1;
+
+ if (indent >= max_indent) {
+ return true;
+ }
+
+ for (sub = tevent_req_profile_get_subprofiles(profile);
+ sub != NULL;
+ sub = tevent_req_profile_next(sub)) {
+ bool ret;
+
+ ret = tevent_req_profile_string_internal(
+ sub,
+ indent,
+ max_indent,
+ string);
+ if (!ret) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+char *tevent_req_profile_string(TALLOC_CTX *mem_ctx,
+ const struct tevent_req_profile *profile,
+ unsigned indent,
+ unsigned max_indent)
+{
+ char *result;
+ bool ret;
+
+ result = talloc_strdup(mem_ctx, "");
+ if (result == NULL) {
+ return NULL;
+ }
+
+ ret = tevent_req_profile_string_internal(
+ profile,
+ indent,
+ max_indent,
+ &result);
+ if (!ret) {
+ TALLOC_FREE(result);
+ return NULL;
+ }
+
+ return result;
+}
+
+static ssize_t tevent_req_profile_pack_one(
+ const struct tevent_req_profile *profile,
+ uint8_t *buf,
+ size_t buflen)
+{
+ const char *req_name = NULL;
+ const char *start_location = NULL;
+ const char *stop_location = NULL;
+ struct timeval start_time, stop_time;
+ pid_t pid;
+ enum tevent_req_state state;
+ uint64_t user_error;
+ size_t pack_len, len;
+ int ret;
+
+ tevent_req_profile_get_name(profile, &req_name);
+ tevent_req_profile_get_start(profile, &start_location, &start_time);
+ tevent_req_profile_get_stop(profile, &stop_location, &stop_time);
+ tevent_req_profile_get_status(profile, &pid, &state, &user_error);
+
+ len = strlen(req_name)+1;
+ if (buflen >= len) {
+ memcpy(buf, req_name, len);
+ buf += len;
+ buflen -= len;
+ }
+
+ pack_len = len;
+
+ len = strlen(start_location)+1;
+ pack_len += len;
+ if (pack_len < len) {
+ return -1; /* overflow */
+ }
+
+ if (buflen >= len) {
+ memcpy(buf, start_location, len);
+ buf += len;
+ buflen -= len;
+ }
+
+ len = strlen(stop_location)+1;
+ pack_len += len;
+ if (pack_len < len) {
+ return -1; /* overflow */
+ }
+
+ if (buflen >= len) {
+ memcpy(buf, stop_location, len);
+ buf += len;
+ buflen -= len;
+ }
+
+ ret = snprintf((char *)buf,
+ buflen,
+ "%ju %ju %ju %ju %d %d %"PRIu64"",
+ (uintmax_t)start_time.tv_sec,
+ (uintmax_t)start_time.tv_usec,
+ (uintmax_t)stop_time.tv_sec,
+ (uintmax_t)stop_time.tv_usec,
+ (int)pid,
+ (int)state,
+ user_error);
+ if (ret < 0) {
+ return -1;
+ }
+
+ /*
+ * Take care of the trailing 0. No overflow check, this would
+ * be a VERY small number of bits for "int".
+ */
+ ret += 1;
+
+ pack_len += ret;
+
+ return pack_len;
+}
+
+ssize_t tevent_req_profile_pack(
+ const struct tevent_req_profile *profile,
+ uint8_t *buf,
+ size_t buflen)
+{
+ const struct tevent_req_profile *sub = NULL;
+ size_t num_sub;
+ ssize_t pack_len, profile_len;
+ int ret;
+
+ num_sub = 0;
+ pack_len = 0;
+
+ for (sub = tevent_req_profile_get_subprofiles(profile);
+ sub != NULL;
+ sub = tevent_req_profile_next(sub)) {
+ num_sub += 1;
+ }
+
+ ret = snprintf((char *)buf, buflen, "%zu ", num_sub);
+ if (ret < 0) {
+ return -1;
+ }
+
+ if (buflen > (size_t)ret) {
+ buf += ret;
+ buflen -= ret;
+ }
+
+ pack_len = ret;
+
+ profile_len = tevent_req_profile_pack_one(profile, buf, buflen);
+ if (profile_len == -1) {
+ return -1;
+ }
+
+ if (buflen >= (size_t)profile_len) {
+ buf += profile_len;
+ buflen -= profile_len;
+ }
+
+ pack_len += profile_len;
+ if (pack_len < profile_len) {
+ return -1; /* overflow */
+ }
+
+ for (sub = tevent_req_profile_get_subprofiles(profile);
+ sub != NULL;
+ sub = tevent_req_profile_next(sub)) {
+
+ profile_len = tevent_req_profile_pack(sub, buf, buflen);
+ if (profile_len == -1) {
+ return -1;
+ }
+
+ if (buflen >= (size_t)profile_len) {
+ buf += profile_len;
+ buflen -= profile_len;
+ }
+
+ pack_len += profile_len;
+ if (pack_len < profile_len) {
+ return -1; /* overflow */
+ }
+ }
+
+ return pack_len;
+}
+
+static bool parse_uintmax(const char *buf,
+ char delimiter,
+ uintmax_t *presult,
+ char **p_endptr)
+{
+ uintmax_t result;
+ char *endptr;
+
+ result = strtoumax(buf, &endptr, 10);
+ if ((result == UINTMAX_MAX) && (errno == ERANGE)) {
+ return false;
+ }
+ if (*endptr != delimiter) {
+ return false;
+ }
+
+ *presult = result;
+ *p_endptr = endptr+1;
+
+ return true;
+}
+
+static ssize_t tevent_req_profile_unpack_one(
+ const uint8_t *buf,
+ size_t buflen,
+ struct tevent_req_profile *profile)
+{
+ const char *orig_buf = (const char *)buf;
+ const char *req_name = NULL;
+ const char *start_location = NULL;
+ const char *stop_location = NULL;
+ uintmax_t start_sec, start_usec, stop_sec, stop_usec, pid, state;
+ uintmax_t user_error;
+ char *next = NULL;
+ size_t len;
+ bool ok;
+
+ if (buflen == 0) {
+ return -1;
+ }
+ if (buf[buflen-1] != '\0') {
+ return -1;
+ }
+
+ req_name = (const char *)buf;
+ len = strlen(req_name)+1;
+
+ buf += len;
+ buflen -= len;
+ if (buflen == 0) {
+ return -1;
+ }
+
+ start_location = (const char *)buf;
+ len = strlen(start_location)+1;
+
+ buf += len;
+ buflen -= len;
+ if (buflen == 0) {
+ return -1;
+ }
+
+ stop_location = (const char *)buf;
+ len = strlen(stop_location)+1;
+
+ buf += len;
+ buflen -= len;
+ if (buflen == 0) {
+ return -1;
+ }
+
+ ok = parse_uintmax((const char *)buf, ' ', &start_sec, &next);
+ if (!ok) {
+ return -1;
+ }
+
+ ok = parse_uintmax(next, ' ', &start_usec, &next);
+ if (!ok) {
+ return -1;
+ }
+
+ ok = parse_uintmax(next, ' ', &stop_sec, &next);
+ if (!ok) {
+ return -1;
+ }
+
+ ok = parse_uintmax(next, ' ', &stop_usec, &next);
+ if (!ok) {
+ return -1;
+ }
+
+ ok = parse_uintmax(next, ' ', &pid, &next);
+ if (!ok) {
+ return -1;
+ }
+
+ ok = parse_uintmax(next, ' ', &state, &next);
+ if (!ok) {
+ return -1;
+ }
+
+ ok = parse_uintmax(next, '\0', &user_error, &next);
+ if (!ok) {
+ return -1;
+ }
+
+ ok = tevent_req_profile_set_name(profile, req_name);
+ if (!ok) {
+ return -1;
+ }
+
+ ok = tevent_req_profile_set_start(
+ profile,
+ start_location,
+ (struct timeval){ .tv_sec=start_sec, .tv_usec=start_usec });
+ if (!ok) {
+ return -1;
+ }
+
+ ok = tevent_req_profile_set_stop(
+ profile,
+ stop_location,
+ (struct timeval){ .tv_sec=stop_sec, .tv_usec=stop_usec });
+ if (!ok) {
+ return -1;
+ }
+
+ tevent_req_profile_set_status(
+ profile,
+ pid,
+ (enum tevent_req_state)state,
+ user_error);
+
+ return next - orig_buf;
+}
+
+ssize_t tevent_req_profile_unpack(
+ const uint8_t *buf,
+ size_t buflen,
+ TALLOC_CTX *mem_ctx,
+ struct tevent_req_profile **p_profile)
+{
+ const uint8_t *orig_buf = buf;
+ struct tevent_req_profile *profile = NULL;
+ uintmax_t i, num_subprofiles;
+ char *next = NULL;
+ bool ok;
+ ssize_t len;
+
+ errno = 0;
+
+ if (buf[buflen-1] != '\0') {
+ return -1;
+ }
+
+ ok = parse_uintmax((const char *)buf, ' ', &num_subprofiles, &next);
+ if (!ok) {
+ return -1;
+ }
+
+ len = (next - (const char *)buf);
+
+ buf += len;
+ buflen -= len;
+
+ profile = tevent_req_profile_create(mem_ctx);
+ if (profile == NULL) {
+ return -1;
+ }
+
+ len = tevent_req_profile_unpack_one(buf, buflen, profile);
+ if (len == -1) {
+ TALLOC_FREE(profile);
+ return -1;
+ }
+
+ buf += len;
+ buflen -= len;
+
+ for (i=0; i<num_subprofiles; i++) {
+ struct tevent_req_profile *subprofile;
+
+ len = tevent_req_profile_unpack(
+ buf,
+ buflen,
+ profile,
+ &subprofile);
+ if (len == -1) {
+ TALLOC_FREE(profile);
+ return -1;
+ }
+ buf += len;
+ buflen -= len;
+
+ tevent_req_profile_append_sub(profile, &subprofile);
+ }
+
+ *p_profile = profile;
+
+ return buf - orig_buf;
+}
diff --git a/lib/util/tevent_req_profile.h b/lib/util/tevent_req_profile.h
new file mode 100644
index 0000000..3bcdbc1
--- /dev/null
+++ b/lib/util/tevent_req_profile.h
@@ -0,0 +1,46 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Helpers around tevent_req_profile
+ *
+ * Copyright (C) Volker Lendecke 2018
+ *
+ * ** NOTE! The following LGPL license applies to the tevent
+ * ** library. This does NOT imply that all of Samba is released
+ * ** under the LGPL
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIB_UTIL_TEVENT_REQ_PROFILE_UNPACK
+#define __LIB_UTIL_TEVENT_REQ_PROFILE_UNPACK
+
+#include "replace.h"
+#include <tevent.h>
+
+char *tevent_req_profile_string(TALLOC_CTX *mem_ctx,
+ const struct tevent_req_profile *profile,
+ unsigned indent,
+ unsigned max_indent);
+ssize_t tevent_req_profile_pack(
+ const struct tevent_req_profile *profile,
+ uint8_t *buf,
+ size_t buflen);
+ssize_t tevent_req_profile_unpack(
+ const uint8_t *buf,
+ size_t buflen,
+ TALLOC_CTX *mem_ctx,
+ struct tevent_req_profile **p_profile);
+
+#endif
diff --git a/lib/util/tevent_unix.c b/lib/util/tevent_unix.c
new file mode 100644
index 0000000..63bdaf6
--- /dev/null
+++ b/lib/util/tevent_unix.c
@@ -0,0 +1,73 @@
+/*
+ Unix SMB/CIFS implementation.
+ Wrap unix errno around tevent_req
+ Copyright (C) Volker Lendecke 2009
+
+ ** NOTE! The following LGPL license applies to the tevent_unix
+ ** helper library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "../replace/replace.h"
+#include "tevent_unix.h"
+
+bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno)
+{
+ enum tevent_req_state state;
+ uint64_t err;
+
+ if (!tevent_req_is_error(req, &state, &err)) {
+ return false;
+ }
+ switch (state) {
+ case TEVENT_REQ_TIMED_OUT:
+ *perrno = ETIMEDOUT;
+ break;
+ case TEVENT_REQ_NO_MEMORY:
+ *perrno = ENOMEM;
+ break;
+ case TEVENT_REQ_USER_ERROR:
+ *perrno = err;
+ break;
+ default:
+ *perrno = EINVAL;
+ break;
+ }
+ return true;
+}
+
+int tevent_req_simple_recv_unix(struct tevent_req *req)
+{
+ int err = 0;
+
+ /*
+ * Ignore result of tevent_req_is_unix_error, we're only interested in
+ * the status
+ */
+ tevent_req_is_unix_error(req, &err);
+ tevent_req_received(req);
+ return err;
+}
+
+bool tevent_req_poll_unix(struct tevent_req *req, struct tevent_context *ev,
+ int *err)
+{
+ bool ret = tevent_req_poll(req, ev);
+ if (!ret) {
+ *err = errno;
+ }
+ return ret;
+}
diff --git a/lib/util/tevent_unix.h b/lib/util/tevent_unix.h
new file mode 100644
index 0000000..39689d6
--- /dev/null
+++ b/lib/util/tevent_unix.h
@@ -0,0 +1,34 @@
+/*
+ Unix SMB/CIFS implementation.
+ Wrap unix errno around tevent_req
+ Copyright (C) Volker Lendecke 2009
+
+ ** NOTE! The following LGPL license applies to the tevent_unix
+ ** helper library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _TEVENT_UNIX_H
+#define _TEVENT_UNIX_H
+
+#include <tevent.h>
+
+bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno);
+int tevent_req_simple_recv_unix(struct tevent_req *req);
+bool tevent_req_poll_unix(struct tevent_req *req, struct tevent_context *ev,
+ int *err);
+
+#endif
diff --git a/lib/util/tevent_werror.c b/lib/util/tevent_werror.c
new file mode 100644
index 0000000..edd503e
--- /dev/null
+++ b/lib/util/tevent_werror.c
@@ -0,0 +1,94 @@
+/*
+ Unix SMB/CIFS implementation.
+ Wrap win32 errors around tevent_req
+ Copyright (C) Kai Blin 2010
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "../replace/replace.h"
+#include "tevent_werror.h"
+#include "libcli/util/error.h"
+
+bool _tevent_req_werror(struct tevent_req *req,
+ WERROR werror,
+ const char *location)
+{
+ return _tevent_req_error(req, W_ERROR_V(werror),
+ location);
+}
+
+bool tevent_req_is_werror(struct tevent_req *req, WERROR *error)
+{
+ enum tevent_req_state state;
+ uint64_t err;
+
+ if (!tevent_req_is_error(req, &state, &err)) {
+ return false;
+ }
+ switch (state) {
+ case TEVENT_REQ_TIMED_OUT:
+ *error = WERR_TIMEOUT;
+ break;
+ case TEVENT_REQ_NO_MEMORY:
+ *error = WERR_NOT_ENOUGH_MEMORY;
+ break;
+ case TEVENT_REQ_USER_ERROR:
+ *error = W_ERROR(err);
+ break;
+ default:
+ *error = WERR_INTERNAL_ERROR;
+ break;
+ }
+ return true;
+}
+
+WERROR tevent_req_simple_recv_werror(struct tevent_req *req)
+{
+ WERROR werror;
+
+ if (tevent_req_is_werror(req, &werror)) {
+ tevent_req_received(req);
+ return werror;
+ }
+ tevent_req_received(req);
+ return WERR_OK;
+}
+
+void tevent_req_simple_finish_werror(struct tevent_req *subreq,
+ WERROR subreq_error)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+
+ TALLOC_FREE(subreq);
+
+ if (!W_ERROR_IS_OK(subreq_error)) {
+ tevent_req_werror(req, subreq_error);
+ return;
+ }
+ tevent_req_done(req);
+}
+
+bool tevent_req_poll_werror(struct tevent_req *req,
+ struct tevent_context *ev,
+ WERROR *err)
+{
+ bool ret = tevent_req_poll(req, ev);
+ if (!ret) {
+ NTSTATUS status = map_nt_error_from_unix_common(errno);
+ *err = ntstatus_to_werror(status);
+ }
+ return ret;
+}
diff --git a/lib/util/tevent_werror.h b/lib/util/tevent_werror.h
new file mode 100644
index 0000000..1e08c3d
--- /dev/null
+++ b/lib/util/tevent_werror.h
@@ -0,0 +1,46 @@
+/*
+ Unix SMB/CIFS implementation.
+ Wrap win32 errors around tevent_req
+ Copyright (C) Kai Blin 2010
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _TEVENT_WERROR_H
+#define _TEVENT_WERROR_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "../libcli/util/werror.h"
+#include <tevent.h>
+
+bool _tevent_req_werror(struct tevent_req *req,
+ WERROR werror,
+ const char *location);
+#define tevent_req_werror(req, werror) \
+ _tevent_req_werror(req, werror, __location__)
+bool tevent_req_is_werror(struct tevent_req *req, WERROR *error);
+WERROR tevent_req_simple_recv_werror(struct tevent_req *req);
+
+/*
+ * Helper routine to pass the subreq_werror to the req embedded in
+ * tevent_req_callback_data(subreq), which will be freed.
+ */
+void tevent_req_simple_finish_werror(struct tevent_req *subreq,
+ WERROR subreq_error);
+
+bool tevent_req_poll_werror(struct tevent_req *req,
+ struct tevent_context *ev,
+ WERROR *err);
+#endif
diff --git a/lib/util/tfork.c b/lib/util/tfork.c
new file mode 100644
index 0000000..316287b
--- /dev/null
+++ b/lib/util/tfork.c
@@ -0,0 +1,944 @@
+/*
+ fork on steroids to avoid SIGCHLD and waitpid
+
+ Copyright (C) Stefan Metzmacher 2010
+ Copyright (C) Ralph Boehme 2017
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/wait.h"
+#include "system/filesys.h"
+#include "system/network.h"
+#include "lib/util/samba_util.h"
+#include "lib/util/sys_rw.h"
+#include "lib/util/tfork.h"
+#include "lib/util/debug.h"
+#include "lib/util/util_process.h"
+
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+#endif
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#include <assert.h>
+
+/*
+ * This is how the process hierarchy looks like:
+ *
+ * +----------+
+ * | caller |
+ * +----------+
+ * |
+ * fork
+ * |
+ * v
+ * +----------+
+ * | waiter |
+ * +----------+
+ * |
+ * fork
+ * |
+ * v
+ * +----------+
+ * | worker |
+ * +----------+
+ */
+
+#ifdef HAVE_VALGRIND_HELGRIND_H
+#include <valgrind/helgrind.h>
+#endif
+#ifndef ANNOTATE_BENIGN_RACE_SIZED
+#define ANNOTATE_BENIGN_RACE_SIZED(obj, size, description)
+#endif
+
+#define TFORK_ANNOTATE_BENIGN_RACE(obj) \
+ ANNOTATE_BENIGN_RACE_SIZED( \
+ (obj), sizeof(*(obj)), \
+ "no race, serialized by tfork_[un]install_sigchld_handler");
+
+/*
+ * The resulting (private) state per tfork_create() call, returned as a opaque
+ * handle to the caller.
+ */
+struct tfork {
+ /*
+ * This is returned to the caller with tfork_event_fd()
+ */
+ int event_fd;
+
+ /*
+ * This is used in the caller by tfork_status() to read the worker exit
+ * status and to tell the waiter to exit by closing the fd.
+ */
+ int status_fd;
+
+ pid_t waiter_pid;
+ pid_t worker_pid;
+};
+
+/*
+ * Internal per-thread state maintained while inside tfork.
+ */
+struct tfork_state {
+ pid_t waiter_pid;
+ int waiter_errno;
+
+ pid_t worker_pid;
+};
+
+/*
+ * A global state that synchronizes access to handling SIGCHLD and waiting for
+ * children.
+ */
+struct tfork_signal_state {
+ bool available;
+
+#ifdef HAVE_PTHREAD
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+#endif
+
+ /*
+ * pid of the waiter child. This points at waiter_pid in either struct
+ * tfork or struct tfork_state, depending on who called
+ * tfork_install_sigchld_handler().
+ *
+ * When tfork_install_sigchld_handler() is called the waiter_pid is
+ * still -1 and only set later after fork(), that's why this is must be
+ * a pointer. The signal handler checks this.
+ */
+ pid_t *pid;
+
+ struct sigaction oldact;
+ sigset_t oldset;
+};
+
+static struct tfork_signal_state signal_state;
+
+#ifdef HAVE_PTHREAD
+static pthread_once_t tfork_global_is_initialized = PTHREAD_ONCE_INIT;
+static pthread_key_t tfork_global_key;
+#else
+static struct tfork_state *global_state;
+#endif
+
+static void tfork_sigchld_handler(int signum, siginfo_t *si, void *p);
+
+#ifdef HAVE_PTHREAD
+static void tfork_global_destructor(void *state)
+{
+ anonymous_shared_free(state);
+}
+#endif
+
+static int tfork_acquire_sighandling(void)
+{
+ int ret = 0;
+
+#ifdef HAVE_PTHREAD
+ ret = pthread_mutex_lock(&signal_state.mutex);
+ if (ret != 0) {
+ return ret;
+ }
+
+ while (!signal_state.available) {
+ ret = pthread_cond_wait(&signal_state.cond,
+ &signal_state.mutex);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ signal_state.available = false;
+
+ ret = pthread_mutex_unlock(&signal_state.mutex);
+ if (ret != 0) {
+ return ret;
+ }
+#endif
+
+ return ret;
+}
+
+static int tfork_release_sighandling(void)
+{
+ int ret = 0;
+
+#ifdef HAVE_PTHREAD
+ ret = pthread_mutex_lock(&signal_state.mutex);
+ if (ret != 0) {
+ return ret;
+ }
+
+ signal_state.available = true;
+
+ ret = pthread_cond_signal(&signal_state.cond);
+ if (ret != 0) {
+ pthread_mutex_unlock(&signal_state.mutex);
+ return ret;
+ }
+
+ ret = pthread_mutex_unlock(&signal_state.mutex);
+ if (ret != 0) {
+ return ret;
+ }
+#endif
+
+ return ret;
+}
+
+#ifdef HAVE_PTHREAD
+static void tfork_atfork_prepare(void)
+{
+ int ret;
+
+ ret = pthread_mutex_lock(&signal_state.mutex);
+ assert(ret == 0);
+}
+
+static void tfork_atfork_parent(void)
+{
+ int ret;
+
+ ret = pthread_mutex_unlock(&signal_state.mutex);
+ assert(ret == 0);
+}
+#endif
+
+static void tfork_atfork_child(void)
+{
+ int ret;
+
+#ifdef HAVE_PTHREAD
+ ret = pthread_mutex_unlock(&signal_state.mutex);
+ assert(ret == 0);
+
+ ret = pthread_key_delete(tfork_global_key);
+ assert(ret == 0);
+
+ ret = pthread_key_create(&tfork_global_key, tfork_global_destructor);
+ assert(ret == 0);
+
+ /*
+ * There's no data race on the cond variable from the signal state, we
+ * are writing here, but there are no readers yet. Some data race
+ * detection tools report a race, but the readers are in the parent
+ * process.
+ */
+ TFORK_ANNOTATE_BENIGN_RACE(&signal_state.cond);
+
+ /*
+ * There's no way to destroy a condition variable if there are waiters,
+ * pthread_cond_destroy() will return EBUSY. Just zero out memory and
+ * then initialize again. This is not backed by POSIX but should be ok.
+ */
+ ZERO_STRUCT(signal_state.cond);
+ ret = pthread_cond_init(&signal_state.cond, NULL);
+ assert(ret == 0);
+#endif
+
+ if (signal_state.pid != NULL) {
+
+ ret = sigaction(SIGCHLD, &signal_state.oldact, NULL);
+ assert(ret == 0);
+
+#ifdef HAVE_PTHREAD
+ ret = pthread_sigmask(SIG_SETMASK, &signal_state.oldset, NULL);
+#else
+ ret = sigprocmask(SIG_SETMASK, &signal_state.oldset, NULL);
+#endif
+ assert(ret == 0);
+
+ signal_state.pid = NULL;
+ }
+
+ signal_state.available = true;
+}
+
+static void tfork_global_initialize(void)
+{
+#ifdef HAVE_PTHREAD
+ int ret;
+
+ pthread_atfork(tfork_atfork_prepare,
+ tfork_atfork_parent,
+ tfork_atfork_child);
+
+ ret = pthread_key_create(&tfork_global_key, tfork_global_destructor);
+ assert(ret == 0);
+
+ ret = pthread_mutex_init(&signal_state.mutex, NULL);
+ assert(ret == 0);
+
+ ret = pthread_cond_init(&signal_state.cond, NULL);
+ assert(ret == 0);
+
+ /*
+ * In a threaded process there's no data race on t->waiter_pid as
+ * we're serializing globally via tfork_acquire_sighandling() and
+ * tfork_release_sighandling().
+ */
+ TFORK_ANNOTATE_BENIGN_RACE(&signal_state.pid);
+#endif
+
+ signal_state.available = true;
+}
+
+static struct tfork_state *tfork_global_get(void)
+{
+ struct tfork_state *state = NULL;
+#ifdef HAVE_PTHREAD
+ int ret;
+#endif
+
+#ifdef HAVE_PTHREAD
+ state = (struct tfork_state *)pthread_getspecific(tfork_global_key);
+#else
+ state = global_state;
+#endif
+ if (state != NULL) {
+ return state;
+ }
+
+ state = (struct tfork_state *)anonymous_shared_allocate(
+ sizeof(struct tfork_state));
+ if (state == NULL) {
+ return NULL;
+ }
+
+#ifdef HAVE_PTHREAD
+ ret = pthread_setspecific(tfork_global_key, state);
+ if (ret != 0) {
+ anonymous_shared_free(state);
+ return NULL;
+ }
+#endif
+ return state;
+}
+
+static void tfork_global_free(void)
+{
+ struct tfork_state *state = NULL;
+#ifdef HAVE_PTHREAD
+ int ret;
+#endif
+
+#ifdef HAVE_PTHREAD
+ state = (struct tfork_state *)pthread_getspecific(tfork_global_key);
+#else
+ state = global_state;
+#endif
+ if (state == NULL) {
+ return;
+ }
+
+#ifdef HAVE_PTHREAD
+ ret = pthread_setspecific(tfork_global_key, NULL);
+ if (ret != 0) {
+ return;
+ }
+#endif
+ anonymous_shared_free(state);
+}
+
+/**
+ * Only one thread at a time is allowed to handle SIGCHLD signals
+ **/
+static int tfork_install_sigchld_handler(pid_t *pid)
+{
+ int ret;
+ struct sigaction act;
+ sigset_t set;
+
+ ret = tfork_acquire_sighandling();
+ if (ret != 0) {
+ return -1;
+ }
+
+ assert(signal_state.pid == NULL);
+ signal_state.pid = pid;
+
+ act = (struct sigaction) {
+ .sa_sigaction = tfork_sigchld_handler,
+ .sa_flags = SA_SIGINFO,
+ };
+
+ ret = sigaction(SIGCHLD, &act, &signal_state.oldact);
+ if (ret != 0) {
+ return -1;
+ }
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGCHLD);
+#ifdef HAVE_PTHREAD
+ ret = pthread_sigmask(SIG_UNBLOCK, &set, &signal_state.oldset);
+#else
+ ret = sigprocmask(SIG_UNBLOCK, &set, &signal_state.oldset);
+#endif
+ if (ret != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int tfork_uninstall_sigchld_handler(void)
+{
+ int ret;
+
+ signal_state.pid = NULL;
+
+ ret = sigaction(SIGCHLD, &signal_state.oldact, NULL);
+ if (ret != 0) {
+ return -1;
+ }
+
+#ifdef HAVE_PTHREAD
+ ret = pthread_sigmask(SIG_SETMASK, &signal_state.oldset, NULL);
+#else
+ ret = sigprocmask(SIG_SETMASK, &signal_state.oldset, NULL);
+#endif
+ if (ret != 0) {
+ return -1;
+ }
+
+ ret = tfork_release_sighandling();
+ if (ret != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static void tfork_sigchld_handler(int signum, siginfo_t *si, void *p)
+{
+ if ((signal_state.pid != NULL) &&
+ (*signal_state.pid != -1) &&
+ (si->si_pid == *signal_state.pid))
+ {
+ return;
+ }
+
+ /*
+ * Not our child, forward to old handler
+ */
+ if (signal_state.oldact.sa_flags & SA_SIGINFO) {
+ signal_state.oldact.sa_sigaction(signum, si, p);
+ return;
+ }
+
+ if (signal_state.oldact.sa_handler == SIG_IGN) {
+ return;
+ }
+ if (signal_state.oldact.sa_handler == SIG_DFL) {
+ return;
+ }
+ signal_state.oldact.sa_handler(signum);
+}
+
+static pid_t tfork_start_waiter_and_worker(struct tfork_state *state,
+ int *_event_fd,
+ int *_status_fd)
+{
+ int p[2];
+ int status_sp_caller_fd = -1;
+ int status_sp_waiter_fd = -1;
+ int event_pipe_caller_fd = -1;
+ int event_pipe_waiter_fd = -1;
+ int ready_pipe_caller_fd = -1;
+ int ready_pipe_worker_fd = -1;
+ ssize_t nwritten;
+ ssize_t nread;
+ pid_t pid;
+ int status;
+ int fd;
+ char c;
+ int ret;
+
+ *_event_fd = -1;
+ *_status_fd = -1;
+
+ if (state == NULL) {
+ return -1;
+ }
+
+ ret = socketpair(AF_UNIX, SOCK_STREAM, 0, p);
+ if (ret != 0) {
+ return -1;
+ }
+ set_close_on_exec(p[0]);
+ set_close_on_exec(p[1]);
+ status_sp_caller_fd = p[0];
+ status_sp_waiter_fd = p[1];
+
+ ret = pipe(p);
+ if (ret != 0) {
+ close(status_sp_caller_fd);
+ close(status_sp_waiter_fd);
+ return -1;
+ }
+ set_close_on_exec(p[0]);
+ set_close_on_exec(p[1]);
+ event_pipe_caller_fd = p[0];
+ event_pipe_waiter_fd = p[1];
+
+
+ ret = pipe(p);
+ if (ret != 0) {
+ close(status_sp_caller_fd);
+ close(status_sp_waiter_fd);
+ close(event_pipe_caller_fd);
+ close(event_pipe_waiter_fd);
+ return -1;
+ }
+ set_close_on_exec(p[0]);
+ set_close_on_exec(p[1]);
+ ready_pipe_worker_fd = p[0];
+ ready_pipe_caller_fd = p[1];
+
+ pid = fork();
+ if (pid == -1) {
+ close(status_sp_caller_fd);
+ close(status_sp_waiter_fd);
+ close(event_pipe_caller_fd);
+ close(event_pipe_waiter_fd);
+ close(ready_pipe_caller_fd);
+ close(ready_pipe_worker_fd);
+ return -1;
+ }
+ if (pid != 0) {
+ /* The caller */
+
+ /*
+ * In a threaded process there's no data race on
+ * state->waiter_pid as we're serializing globally via
+ * tfork_acquire_sighandling() and tfork_release_sighandling().
+ */
+ TFORK_ANNOTATE_BENIGN_RACE(&state->waiter_pid);
+
+ state->waiter_pid = pid;
+
+ close(status_sp_waiter_fd);
+ close(event_pipe_waiter_fd);
+ close(ready_pipe_worker_fd);
+
+ set_blocking(event_pipe_caller_fd, false);
+
+ /*
+ * wait for the waiter to get ready.
+ */
+ nread = sys_read(status_sp_caller_fd, &c, sizeof(char));
+ if (nread != sizeof(char)) {
+ return -1;
+ }
+
+ /*
+ * Notify the worker to start.
+ */
+ nwritten = sys_write(ready_pipe_caller_fd,
+ &(char){0}, sizeof(char));
+ if (nwritten != sizeof(char)) {
+ close(ready_pipe_caller_fd);
+ return -1;
+ }
+ close(ready_pipe_caller_fd);
+
+ *_event_fd = event_pipe_caller_fd;
+ *_status_fd = status_sp_caller_fd;
+
+ return pid;
+ }
+
+#ifndef HAVE_PTHREAD
+ /* cleanup sigchld_handler */
+ tfork_atfork_child();
+#endif
+
+ /*
+ * The "waiter" child.
+ */
+ process_set_title("tfork waiter", "tfork waiter process");
+
+ CatchSignal(SIGCHLD, SIG_DFL);
+
+ close(status_sp_caller_fd);
+ close(event_pipe_caller_fd);
+ close(ready_pipe_caller_fd);
+
+ pid = fork();
+ if (pid == -1) {
+ state->waiter_errno = errno;
+ _exit(0);
+ }
+ if (pid == 0) {
+ /*
+ * The worker child.
+ */
+
+ close(status_sp_waiter_fd);
+ close(event_pipe_waiter_fd);
+
+ /*
+ * Wait for the caller to give us a go!
+ */
+ nread = sys_read(ready_pipe_worker_fd, &c, sizeof(char));
+ if (nread != sizeof(char)) {
+ _exit(1);
+ }
+ close(ready_pipe_worker_fd);
+
+ return 0;
+ }
+ state->worker_pid = pid;
+ process_set_title("tfork(%d)", "tfork waiter process(%d)", pid);
+
+ close(ready_pipe_worker_fd);
+
+ /*
+ * We're going to stay around until child2 exits, so lets close all fds
+ * other than the pipe fd we may have inherited from the caller.
+ *
+ * Dup event_sp_waiter_fd and status_sp_waiter_fd onto fds 0 and 1 so we
+ * can then call closefrom(2).
+ */
+ if (event_pipe_waiter_fd > 0) {
+ int dup_fd = 0;
+
+ if (status_sp_waiter_fd == 0) {
+ dup_fd = 1;
+ }
+
+ do {
+ fd = dup2(event_pipe_waiter_fd, dup_fd);
+ } while ((fd == -1) && (errno == EINTR));
+ if (fd == -1) {
+ state->waiter_errno = errno;
+ kill(state->worker_pid, SIGKILL);
+ state->worker_pid = -1;
+ _exit(1);
+ }
+ event_pipe_waiter_fd = fd;
+ }
+
+ if (status_sp_waiter_fd > 1) {
+ do {
+ fd = dup2(status_sp_waiter_fd, 1);
+ } while ((fd == -1) && (errno == EINTR));
+ if (fd == -1) {
+ state->waiter_errno = errno;
+ kill(state->worker_pid, SIGKILL);
+ state->worker_pid = -1;
+ _exit(1);
+ }
+ status_sp_waiter_fd = fd;
+ }
+
+ closefrom(2);
+
+ /* Tell the caller we're ready */
+ nwritten = sys_write(status_sp_waiter_fd, &(char){0}, sizeof(char));
+ if (nwritten != sizeof(char)) {
+ _exit(1);
+ }
+
+ tfork_global_free();
+ state = NULL;
+
+ do {
+ ret = waitpid(pid, &status, 0);
+ } while ((ret == -1) && (errno == EINTR));
+ if (ret == -1) {
+ status = errno;
+ kill(pid, SIGKILL);
+ }
+
+ /*
+ * This writes the worker child exit status via our internal socketpair
+ * so the tfork_status() implementation can read it from its end.
+ */
+ nwritten = sys_write(status_sp_waiter_fd, &status, sizeof(status));
+ if (nwritten == -1) {
+ if (errno != EPIPE && errno != ECONNRESET) {
+ _exit(errno);
+ }
+ /*
+ * The caller exited and didn't call tfork_status().
+ */
+ _exit(0);
+ }
+ if (nwritten != sizeof(status)) {
+ _exit(1);
+ }
+
+ /*
+ * This write to the event_fd returned by tfork_event_fd() and notifies
+ * the caller that the worker child is done and he may now call
+ * tfork_status().
+ */
+ nwritten = sys_write(event_pipe_waiter_fd, &(char){0}, sizeof(char));
+ if (nwritten != sizeof(char)) {
+ _exit(1);
+ }
+
+ /*
+ * Wait for our parent (the process that called tfork_create()) to
+ * close() the socketpair fd in tfork_status().
+ *
+ * Again, the caller might have exited without calling tfork_status().
+ */
+ nread = sys_read(status_sp_waiter_fd, &c, 1);
+ if (nread == -1) {
+ if (errno == EPIPE || errno == ECONNRESET) {
+ _exit(0);
+ }
+ _exit(errno);
+ }
+ if (nread != 1) {
+ _exit(255);
+ }
+
+ _exit(0);
+}
+
+static int tfork_create_reap_waiter(pid_t waiter_pid)
+{
+ pid_t pid;
+ int waiter_status;
+
+ if (waiter_pid == -1) {
+ return 0;
+ }
+
+ kill(waiter_pid, SIGKILL);
+
+ do {
+ pid = waitpid(waiter_pid, &waiter_status, 0);
+ } while ((pid == -1) && (errno == EINTR));
+ assert(pid == waiter_pid);
+
+ return 0;
+}
+
+struct tfork *tfork_create(void)
+{
+ struct tfork_state *state = NULL;
+ struct tfork *t = NULL;
+ pid_t pid;
+ int saved_errno = 0;
+ int ret = 0;
+ int ret2;
+
+#ifdef HAVE_PTHREAD
+ ret = pthread_once(&tfork_global_is_initialized,
+ tfork_global_initialize);
+ if (ret != 0) {
+ return NULL;
+ }
+#else
+ tfork_global_initialize();
+#endif
+
+ state = tfork_global_get();
+ if (state == NULL) {
+ return NULL;
+ }
+ *state = (struct tfork_state) {
+ .waiter_pid = -1,
+ .waiter_errno = ECANCELED,
+ .worker_pid = -1,
+ };
+
+ t = malloc(sizeof(struct tfork));
+ if (t == NULL) {
+ ret = -1;
+ goto cleanup;
+ }
+
+ *t = (struct tfork) {
+ .event_fd = -1,
+ .status_fd = -1,
+ .waiter_pid = -1,
+ .worker_pid = -1,
+ };
+
+ ret = tfork_install_sigchld_handler(&state->waiter_pid);
+ if (ret != 0) {
+ goto cleanup;
+ }
+
+ pid = tfork_start_waiter_and_worker(state,
+ &t->event_fd,
+ &t->status_fd);
+ if (pid == -1) {
+ ret = -1;
+ goto cleanup;
+ }
+ if (pid == 0) {
+ /* In the worker */
+ tfork_global_free();
+ t->worker_pid = 0;
+ return t;
+ }
+
+ /*
+ * In a threaded process there's no data race on t->waiter_pid as
+ * we're serializing globally via tfork_acquire_sighandling() and
+ * tfork_release_sighandling().
+ */
+ TFORK_ANNOTATE_BENIGN_RACE(&t->waiter_pid);
+
+ t->waiter_pid = pid;
+ t->worker_pid = state->worker_pid;
+
+cleanup:
+ if (ret == -1) {
+ saved_errno = errno;
+
+ if (t != NULL) {
+ if (t->status_fd != -1) {
+ close(t->status_fd);
+ }
+ if (t->event_fd != -1) {
+ close(t->event_fd);
+ }
+
+ ret2 = tfork_create_reap_waiter(state->waiter_pid);
+ assert(ret2 == 0);
+
+ free(t);
+ t = NULL;
+ }
+ }
+
+ ret2 = tfork_uninstall_sigchld_handler();
+ assert(ret2 == 0);
+
+ tfork_global_free();
+
+ if (ret == -1) {
+ errno = saved_errno;
+ }
+ return t;
+}
+
+pid_t tfork_child_pid(const struct tfork *t)
+{
+ return t->worker_pid;
+}
+
+int tfork_event_fd(struct tfork *t)
+{
+ int fd = t->event_fd;
+
+ assert(t->event_fd != -1);
+ t->event_fd = -1;
+
+ return fd;
+}
+
+int tfork_status(struct tfork **_t, bool wait)
+{
+ struct tfork *t = *_t;
+ int status;
+ ssize_t nread;
+ int waiter_status;
+ pid_t pid;
+ int ret;
+
+ if (t == NULL) {
+ return -1;
+ }
+
+ if (wait) {
+ set_blocking(t->status_fd, true);
+
+ nread = sys_read(t->status_fd, &status, sizeof(int));
+ } else {
+ set_blocking(t->status_fd, false);
+
+ nread = read(t->status_fd, &status, sizeof(int));
+ if ((nread == -1) &&
+ ((errno == EAGAIN) || (errno == EWOULDBLOCK) || errno == EINTR)) {
+ errno = EAGAIN;
+ return -1;
+ }
+ }
+ if (nread != sizeof(int)) {
+ return -1;
+ }
+
+ ret = tfork_install_sigchld_handler(&t->waiter_pid);
+ if (ret != 0) {
+ return -1;
+ }
+
+ /*
+ * This triggers process exit in the waiter.
+ * We write to the fd as well as closing it, as any tforked sibling
+ * processes will also have the writable end of this socket open.
+ *
+ */
+ {
+ size_t nwritten;
+ nwritten = sys_write(t->status_fd, &(char){0}, sizeof(char));
+ if (nwritten != sizeof(char)) {
+ close(t->status_fd);
+ return -1;
+ }
+ }
+ close(t->status_fd);
+
+ do {
+ pid = waitpid(t->waiter_pid, &waiter_status, 0);
+ } while ((pid == -1) && (errno == EINTR));
+ assert(pid == t->waiter_pid);
+
+ if (t->event_fd != -1) {
+ close(t->event_fd);
+ t->event_fd = -1;
+ }
+
+ free(t);
+ t = NULL;
+ *_t = NULL;
+
+ ret = tfork_uninstall_sigchld_handler();
+ assert(ret == 0);
+
+ return status;
+}
+
+int tfork_destroy(struct tfork **_t)
+{
+ struct tfork *t = *_t;
+ int ret;
+
+ if (t == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ kill(t->worker_pid, SIGKILL);
+
+ ret = tfork_status(_t, true);
+ if (ret == -1) {
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/lib/util/tfork.h b/lib/util/tfork.h
new file mode 100644
index 0000000..6c59caf
--- /dev/null
+++ b/lib/util/tfork.h
@@ -0,0 +1,111 @@
+/*
+ fork on steroids to avoid SIGCHLD and waitpid
+
+ Copyright (C) Stefan Metzmacher 2010
+ Copyright (C) Ralph Boehme 2017
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef LIB_UTIL_TFORK_H
+#define LIB_UTIL_TFORK_H
+
+struct tfork;
+
+/**
+ * @brief a fork() that avoids SIGCHLD and waitpid
+ *
+ * This function is a solution to the problem of fork() requiring special
+ * preparations in the caller to handle SIGCHLD signals and to reap the child by
+ * wait()ing for it.
+ *
+ * The advantage over fork() is that the child process termination is signalled
+ * to the caller by making a pipe fd readable returned by tfork_event_fd(), in
+ * which case the exit status of the child can be fetched with tfork_status()
+ * without blocking.
+ *
+ * The child process will start with SIGCHLD handler set to SIG_DFL.
+ *
+ * @return On success, a struct tfork. NULL on failure.
+ * Use tfork_worker_pid() to get the pid of the created
+ * child and tfork_event_fd() to get the file descriptor
+ * that can be used to poll for process termination and
+ * reading the child process exit status.
+ *
+ * @note There's one thing this thing can't protect us against and that is if a
+ * process installs a SIGCHLD handler from one thread while another thread is
+ * running inside tfork_create() or tfork_status() and the signal handler
+ * doesn't forward signals for exited children it didn't fork, ie our children.
+ **/
+struct tfork *tfork_create(void);
+
+/**
+ * @brief Return the child pid from tfork_create()
+ *
+ * @param[in] t Pointer to struct tfork returned by tfork_create()
+ *
+ * @return In the caller this returns the pid of the child,
+ * in the child this returns 0.
+ **/
+pid_t tfork_child_pid(const struct tfork *t);
+
+/**
+ * @brief Return an event fd that signals child termination
+ *
+ * @param[in] t Pointer to struct tfork returned by tfork_create()
+ *
+ * It is the callers responsibility to ensure that the event fd returned by
+ * tfork_event_fd() is closed. By calling tfork_event_fd() ownership of the fd
+ * is transferred to the caller, calling tfork_event_fd() again will trigger an
+ * abort().
+ *
+ * @return An fd that becomes readable when the child created with
+ * tfork_create() terminates. It is guaranteed that a
+ * subsequent call to tfork_status() will not block and return
+ * the exit status of the child.
+ **/
+int tfork_event_fd(struct tfork *t);
+
+/**
+ * @brief Wait for the child to terminate and return its exit status
+ *
+ * @param[in] t Pointer-pointer to a struct tfork returned by
+ * tfork_create(). Upon successful completion t is freed and
+ * set to NULL.
+ *
+ * @param[in] wait Whether to wait for the child to change state. If wait is
+ * false, and the child hasn't changed state, tfork_status()
+ * will return -1 with errno set to EAGAIN. If wait is true,
+ * tfork_status() will block waiting for the child to change
+ * runstate.
+ *
+ * @return The exit status of the child, -1 on error.
+ *
+ * @note We overload the return value a bit, but a process exit status is pretty
+ * much guaranteed to be a 16-bit int and can't be -1.
+ **/
+int tfork_status(struct tfork **_t, bool wait);
+
+/**
+ * @brief Terminate the child discarding the exit status
+ *
+ * @param[in] t Pointer-pointer to a struct tfork returned by
+ * tfork_create(). Upon successful completion t is freed and
+ * set to NULL.
+ *
+ * @return 0 on success, -1 on error.
+ **/
+int tfork_destroy(struct tfork **_t);
+
+#endif /* LIB_UTIL_TFORK_H */
diff --git a/lib/util/tftw.c b/lib/util/tftw.c
new file mode 100644
index 0000000..c59bb6a
--- /dev/null
+++ b/lib/util/tftw.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2008-2018 by Andreas Schneider <asn@samba.org>
+ *
+ * Adopted from the csync source code
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/dir.h"
+#include "lib/util/debug.h"
+
+#include "tftw.h"
+
+
+int tftw(TALLOC_CTX *mem_ctx, const char *fpath, tftw_walker_fn fn, size_t depth, void *userdata)
+{
+ char *filename = NULL;
+ char *d_name = NULL;
+ DIR *dh = NULL;
+ struct dirent *dirent = NULL;
+ struct stat sb = {0};
+ int rc = 0;
+
+ if (fpath[0] == '\0') {
+ errno = ENOENT;
+ goto error;
+ }
+
+ if ((dh = opendir(fpath)) == NULL) {
+ /* permission denied */
+ if (errno == EACCES) {
+ return 0;
+ } else {
+ DBG_ERR("opendir failed for: [%s]\n", strerror(errno));
+ goto error;
+ }
+ }
+
+ while ((dirent = readdir(dh))) {
+ int flag;
+
+ d_name = dirent->d_name;
+ if (d_name == NULL) {
+ goto error;
+ }
+
+ /* skip "." and ".." */
+ if (d_name[0] == '.' && (d_name[1] == '\0'
+ || (d_name[1] == '.' && d_name[2] == '\0'))) {
+ dirent = NULL;
+ continue;
+ }
+
+ filename = talloc_asprintf(mem_ctx, "%s/%s", fpath, d_name);
+ if (filename == NULL) {
+ goto error;
+ }
+
+ rc = lstat(filename, &sb);
+ if (rc < 0) {
+ dirent = NULL;
+ goto error;
+ }
+
+ switch (sb.st_mode & S_IFMT) {
+ case S_IFLNK:
+ flag = TFTW_FLAG_SLINK;
+ break;
+ case S_IFDIR:
+ flag = TFTW_FLAG_DIR;
+ break;
+ case S_IFBLK:
+ case S_IFCHR:
+ case S_IFSOCK:
+ case S_IFIFO:
+ flag = TFTW_FLAG_SPEC;
+ break;
+ default:
+ flag = TFTW_FLAG_FILE;
+ break;
+ }
+
+ DBG_INFO("walk: [%s]\n", filename);
+
+ /* Call walker function for each file */
+ rc = fn(mem_ctx, filename, &sb, flag, userdata);
+
+ if (rc < 0) {
+ DBG_ERR("provided callback fn() failed: [%s]\n",
+ strerror(errno));
+ closedir(dh);
+ goto done;
+ }
+
+ if (flag == TFTW_FLAG_DIR && depth) {
+ rc = tftw(mem_ctx, filename, fn, depth - 1, userdata);
+ if (rc < 0) {
+ closedir(dh);
+ goto done;
+ }
+ }
+ TALLOC_FREE(filename);
+ dirent = NULL;
+ }
+ closedir(dh);
+
+done:
+ TALLOC_FREE(filename);
+ return rc;
+error:
+ if (dh != NULL) {
+ closedir(dh);
+ }
+ TALLOC_FREE(filename);
+ return -1;
+}
diff --git a/lib/util/tftw.h b/lib/util/tftw.h
new file mode 100644
index 0000000..0d3d007
--- /dev/null
+++ b/lib/util/tftw.h
@@ -0,0 +1,32 @@
+#include <talloc.h>
+
+enum tftw_flags_e {
+ /* Regular file. */
+ TFTW_FLAG_FILE,
+ /* Directory. */
+ TFTW_FLAG_DIR,
+ /* Unreadable directory. */
+ TFTW_FLAG_DNR,
+ /* Unstatable file. */
+ TFTW_FLAG_NSTAT,
+ /* Symbolic link. */
+ TFTW_FLAG_SLINK,
+ /* Special file (fifo, ...). */
+ TFTW_FLAG_SPEC,
+
+ /* Directory, all subdirs have been visited. */
+ TFTW_FLAG_DP,
+ /* Symbolic link naming non-existing file. */
+ TFTW_FLAG_SLN
+};
+
+/* Maximum number of subdirectories to descend into */
+#define TFTW_MAX_DEPTH 50
+
+typedef int (*tftw_walker_fn)(TALLOC_CTX *mem_ctx,
+ const char *fpath,
+ const struct stat *sb,
+ enum tftw_flags_e flag,
+ void *userdata);
+
+int tftw(TALLOC_CTX *mem_ctx, const char *fpath, tftw_walker_fn fn, size_t depth, void *userdata);
diff --git a/lib/util/time.c b/lib/util/time.c
new file mode 100644
index 0000000..47ae320
--- /dev/null
+++ b/lib/util/time.c
@@ -0,0 +1,1494 @@
+/*
+ Unix SMB/CIFS implementation.
+ time handling functions
+
+ Copyright (C) Andrew Tridgell 1992-2004
+ Copyright (C) Stefan (metze) Metzmacher 2002
+ Copyright (C) Jeremy Allison 2007
+ Copyright (C) Andrew Bartlett 2011
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/time.h"
+#include "byteorder.h"
+#include "time_basic.h"
+#include "lib/util/time.h" /* Avoid /usr/include/time.h */
+#include <sys/stat.h>
+#ifndef NO_CONFIG_H
+#include "config.h"
+#endif
+
+/**
+ * @file
+ * @brief time handling functions
+ */
+
+#define TIME_FIXUP_CONSTANT_INT INT64_C(11644473600)
+
+
+#define NSEC_PER_SEC 1000000000
+
+/**
+ External access to time_t_min and time_t_max.
+**/
+_PUBLIC_ time_t get_time_t_max(void)
+{
+ return TIME_T_MAX;
+}
+
+/**
+a wrapper to preferably get the monotonic time
+**/
+_PUBLIC_ void clock_gettime_mono(struct timespec *tp)
+{
+/* prefer a suspend aware monotonic CLOCK_BOOTTIME: */
+#ifdef CLOCK_BOOTTIME
+ if (clock_gettime(CLOCK_BOOTTIME,tp) == 0) {
+ return;
+ }
+#endif
+/* then try the monotonic clock: */
+#ifndef CUSTOM_CLOCK_MONOTONIC_IS_REALTIME
+ if (clock_gettime(CUSTOM_CLOCK_MONOTONIC,tp) == 0) {
+ return;
+ }
+#endif
+ clock_gettime(CLOCK_REALTIME,tp);
+}
+
+/**
+a wrapper to preferably get the monotonic time in seconds
+**/
+_PUBLIC_ time_t time_mono(time_t *t)
+{
+ struct timespec tp;
+
+ clock_gettime_mono(&tp);
+ if (t != NULL) {
+ *t = tp.tv_sec;
+ }
+ return tp.tv_sec;
+}
+
+
+#define TIME_FIXUP_CONSTANT 11644473600LL
+
+time_t convert_timespec_to_time_t(struct timespec ts)
+{
+ /* Ensure tv_nsec is less than 1sec. */
+ normalize_timespec(&ts);
+
+ /* 1 ns == 1,000,000,000 - one thousand millionths of a second.
+ increment if it's greater than 500 millionth of a second. */
+
+ if (ts.tv_nsec > 500000000) {
+ return ts.tv_sec + 1;
+ }
+ return ts.tv_sec;
+}
+
+struct timespec convert_time_t_to_timespec(time_t t)
+{
+ struct timespec ts;
+ ts.tv_sec = t;
+ ts.tv_nsec = 0;
+ return ts;
+}
+
+
+
+/**
+ Interpret an 8 byte "filetime" structure to a time_t
+ It's originally in "100ns units since jan 1st 1601"
+
+ An 8 byte value of 0xffffffffffffffff will be returned as a timespec of
+
+ tv_sec = 0
+ tv_nsec = 0;
+
+ Returns GMT.
+**/
+time_t nt_time_to_unix(NTTIME nt)
+{
+ return convert_timespec_to_time_t(nt_time_to_unix_timespec(nt));
+}
+
+
+/**
+put a 8 byte filetime from a time_t
+This takes GMT as input
+**/
+_PUBLIC_ void unix_to_nt_time(NTTIME *nt, time_t t)
+{
+ uint64_t t2;
+
+ if (t == (time_t)-1) {
+ *nt = UINT64_MAX;
+ return;
+ }
+
+ if (t == TIME_T_MAX || t == INT64_MAX) {
+ *nt = 0x7fffffffffffffffLL;
+ return;
+ }
+
+ if (t == 0) {
+ *nt = 0;
+ return;
+ }
+
+ t2 = t;
+ t2 += TIME_FIXUP_CONSTANT_INT;
+ t2 *= 1000*1000*10;
+
+ *nt = t2;
+}
+
+
+/**
+check if it's a null unix time
+**/
+_PUBLIC_ bool null_time(time_t t)
+{
+ return t == 0 ||
+ t == (time_t)0xFFFFFFFF ||
+ t == (time_t)-1;
+}
+
+
+/**
+check if it's a null NTTIME
+**/
+_PUBLIC_ bool null_nttime(NTTIME t)
+{
+ return t == 0;
+}
+
+/*******************************************************************
+ create a 16 bit dos packed date
+********************************************************************/
+static uint16_t make_dos_date1(struct tm *t)
+{
+ uint16_t ret=0;
+ ret = (((unsigned int)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1);
+ ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5));
+ return ret;
+}
+
+/*******************************************************************
+ create a 16 bit dos packed time
+********************************************************************/
+static uint16_t make_dos_time1(struct tm *t)
+{
+ uint16_t ret=0;
+ ret = ((((unsigned int)t->tm_min >> 3)&0x7) | (((unsigned int)t->tm_hour) << 3));
+ ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5));
+ return ret;
+}
+
+/*******************************************************************
+ create a 32 bit dos packed date/time from some parameters
+ This takes a GMT time and returns a packed localtime structure
+********************************************************************/
+static uint32_t make_dos_date(time_t unixdate, int zone_offset)
+{
+ struct tm *t;
+ uint32_t ret=0;
+
+ if (unixdate == 0) {
+ return 0;
+ }
+
+ unixdate -= zone_offset;
+
+ t = gmtime(&unixdate);
+ if (!t) {
+ return 0xFFFFFFFF;
+ }
+
+ ret = make_dos_date1(t);
+ ret = ((ret&0xFFFF)<<16) | make_dos_time1(t);
+
+ return ret;
+}
+
+/**
+put a dos date into a buffer (time/date format)
+This takes GMT time and puts local time in the buffer
+**/
+_PUBLIC_ void push_dos_date(uint8_t *buf, int offset, time_t unixdate, int zone_offset)
+{
+ uint32_t x = make_dos_date(unixdate, zone_offset);
+ SIVAL(buf,offset,x);
+}
+
+/**
+put a dos date into a buffer (date/time format)
+This takes GMT time and puts local time in the buffer
+**/
+_PUBLIC_ void push_dos_date2(uint8_t *buf,int offset,time_t unixdate, int zone_offset)
+{
+ uint32_t x;
+ x = make_dos_date(unixdate, zone_offset);
+ x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
+ SIVAL(buf,offset,x);
+}
+
+/**
+put a dos 32 bit "unix like" date into a buffer. This routine takes
+GMT and converts it to LOCAL time before putting it (most SMBs assume
+localtime for this sort of date)
+**/
+_PUBLIC_ void push_dos_date3(uint8_t *buf,int offset,time_t unixdate, int zone_offset)
+{
+ if (!null_time(unixdate)) {
+ unixdate -= zone_offset;
+ }
+ SIVAL(buf,offset,unixdate);
+}
+
+/*******************************************************************
+ interpret a 32 bit dos packed date/time to some parameters
+********************************************************************/
+void interpret_dos_date(uint32_t date,int *year,int *month,int *day,int *hour,int *minute,int *second)
+{
+ uint32_t p0,p1,p2,p3;
+
+ p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF;
+ p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF;
+
+ *second = 2*(p0 & 0x1F);
+ *minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3);
+ *hour = (p1>>3)&0xFF;
+ *day = (p2&0x1F);
+ *month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1;
+ *year = ((p3>>1)&0xFF) + 80;
+}
+
+/**
+ create a unix date (int GMT) from a dos date (which is actually in
+ localtime)
+**/
+_PUBLIC_ time_t pull_dos_date(const uint8_t *date_ptr, int zone_offset)
+{
+ uint32_t dos_date=0;
+ struct tm t;
+ time_t ret;
+
+ dos_date = IVAL(date_ptr,0);
+
+ if (dos_date == 0) return (time_t)0;
+
+ interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon,
+ &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec);
+ t.tm_isdst = -1;
+
+ ret = timegm(&t);
+
+ ret += zone_offset;
+
+ return ret;
+}
+
+/**
+like make_unix_date() but the words are reversed
+**/
+_PUBLIC_ time_t pull_dos_date2(const uint8_t *date_ptr, int zone_offset)
+{
+ uint32_t x,x2;
+
+ x = IVAL(date_ptr,0);
+ x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
+ SIVAL(&x,0,x2);
+
+ return pull_dos_date((const uint8_t *)&x, zone_offset);
+}
+
+/**
+ create a unix GMT date from a dos date in 32 bit "unix like" format
+ these generally arrive as localtimes, with corresponding DST
+**/
+_PUBLIC_ time_t pull_dos_date3(const uint8_t *date_ptr, int zone_offset)
+{
+ time_t t = (time_t)IVAL(date_ptr,0);
+
+ if (t == (time_t)0xFFFFFFFF) {
+ t = (time_t)-1;
+ }
+
+ if (!null_time(t)) {
+ t += zone_offset;
+ }
+ return t;
+}
+
+/****************************************************************************
+ Return the date and time as a string
+****************************************************************************/
+
+char *timeval_string(TALLOC_CTX *ctx, const struct timeval *tp, bool hires)
+{
+ struct timeval_buf tmp;
+ char *result;
+
+ result = talloc_strdup(ctx, timeval_str_buf(tp, false, hires, &tmp));
+ if (result == NULL) {
+ return NULL;
+ }
+
+ /*
+ * beautify the talloc_report output
+ *
+ * This is not just cosmetics. A C compiler might in theory make the
+ * talloc_strdup call above a tail call with the tail call
+ * optimization. This would render "tmp" invalid while talloc_strdup
+ * tries to duplicate it. The talloc_set_name_const call below puts
+ * the talloc_strdup call into non-tail position.
+ */
+ talloc_set_name_const(result, result);
+ return result;
+}
+
+/****************************************************************************
+ Return the date and time as a string
+****************************************************************************/
+
+const char *timespec_string_buf(const struct timespec *tp,
+ bool hires,
+ struct timeval_buf *buf)
+{
+ time_t t;
+ struct tm *tm = NULL;
+ int len;
+
+ if (is_omit_timespec(tp)) {
+ strlcpy(buf->buf, "SAMBA_UTIME_OMIT", sizeof(buf->buf));
+ return buf->buf;
+ }
+
+ t = (time_t)tp->tv_sec;
+ tm = localtime(&t);
+
+ if (tm == NULL) {
+ if (hires) {
+ len = snprintf(buf->buf, sizeof(buf->buf),
+ "%ld.%09ld seconds since the Epoch",
+ (long)tp->tv_sec, (long)tp->tv_nsec);
+ } else {
+ len = snprintf(buf->buf, sizeof(buf->buf),
+ "%ld seconds since the Epoch", (long)t);
+ }
+ } else if (!hires) {
+ len = snprintf(buf->buf, sizeof(buf->buf),
+ "%04d-%02d-%02d %02d:%02d:%02d",
+ 1900 + tm->tm_year,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
+ } else {
+ len = snprintf(buf->buf, sizeof(buf->buf),
+ "%04d-%02d-%02d %02d:%02d:%02d.%09ld",
+ 1900 + tm->tm_year,
+ tm->tm_mon + 1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ (long)tp->tv_nsec);
+ }
+ if (len == -1) {
+ return "";
+ }
+
+ return buf->buf;
+}
+
+char *current_timestring(TALLOC_CTX *ctx, bool hires)
+{
+ struct timeval tv;
+
+ GetTimeOfDay(&tv);
+ return timeval_string(ctx, &tv, hires);
+}
+
+/*
+ * Return date and time as a minimal string avoiding funny characters
+ * that may cause trouble in file names. We only use digits and
+ * underscore ... or a minus/hyphen if we got negative time.
+ */
+char *minimal_timeval_string(TALLOC_CTX *ctx, const struct timeval *tp, bool hires)
+{
+ time_t t;
+ struct tm *tm;
+
+ t = (time_t)tp->tv_sec;
+ tm = localtime(&t);
+ if (!tm) {
+ if (hires) {
+ return talloc_asprintf(ctx, "%ld_%06ld",
+ (long)tp->tv_sec,
+ (long)tp->tv_usec);
+ } else {
+ return talloc_asprintf(ctx, "%ld", (long)t);
+ }
+ } else {
+ if (hires) {
+ return talloc_asprintf(ctx,
+ "%04d%02d%02d_%02d%02d%02d_%06ld",
+ tm->tm_year+1900,
+ tm->tm_mon+1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ (long)tp->tv_usec);
+ } else {
+ return talloc_asprintf(ctx,
+ "%04d%02d%02d_%02d%02d%02d",
+ tm->tm_year+1900,
+ tm->tm_mon+1,
+ tm->tm_mday,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec);
+ }
+ }
+}
+
+char *current_minimal_timestring(TALLOC_CTX *ctx, bool hires)
+{
+ struct timeval tv;
+
+ GetTimeOfDay(&tv);
+ return minimal_timeval_string(ctx, &tv, hires);
+}
+
+/**
+return a HTTP/1.0 time string
+**/
+_PUBLIC_ char *http_timestring(TALLOC_CTX *mem_ctx, time_t t)
+{
+ char *buf;
+ char tempTime[60];
+ struct tm *tm = localtime(&t);
+
+ if (t == TIME_T_MAX) {
+ return talloc_strdup(mem_ctx, "never");
+ }
+
+ if (!tm) {
+ return talloc_asprintf(mem_ctx,"%ld seconds since the Epoch",(long)t);
+ }
+
+#ifndef HAVE_STRFTIME
+ buf = talloc_strdup(mem_ctx, asctime(tm));
+ if (buf[strlen(buf)-1] == '\n') {
+ buf[strlen(buf)-1] = 0;
+ }
+#else
+ strftime(tempTime, sizeof(tempTime)-1, "%a, %d %b %Y %H:%M:%S %Z", tm);
+ buf = talloc_strdup(mem_ctx, tempTime);
+#endif /* !HAVE_STRFTIME */
+
+ return buf;
+}
+
+/**
+ Return the date and time as a string
+**/
+_PUBLIC_ char *timestring(TALLOC_CTX *mem_ctx, time_t t)
+{
+ char *TimeBuf;
+ char tempTime[80];
+ struct tm *tm;
+
+ tm = localtime(&t);
+ if (!tm) {
+ return talloc_asprintf(mem_ctx,
+ "%ld seconds since the Epoch",
+ (long)t);
+ }
+
+#ifdef HAVE_STRFTIME
+ /* Some versions of gcc complain about using some special format
+ * specifiers. This is a bug in gcc, not a bug in this code. See a
+ * recent strftime() manual page for details. */
+ strftime(tempTime,sizeof(tempTime)-1,"%a %b %e %X %Y %Z",tm);
+ TimeBuf = talloc_strdup(mem_ctx, tempTime);
+#else
+ TimeBuf = talloc_strdup(mem_ctx, asctime(tm));
+ if (TimeBuf == NULL) {
+ return NULL;
+ }
+ if (TimeBuf[0] != '\0') {
+ size_t len = strlen(TimeBuf);
+ if (TimeBuf[len - 1] == '\n') {
+ TimeBuf[len - 1] = '\0';
+ }
+ }
+#endif
+
+ return TimeBuf;
+}
+
+/**
+ return a talloced string representing a NTTIME for human consumption
+*/
+_PUBLIC_ const char *nt_time_string(TALLOC_CTX *mem_ctx, NTTIME nt)
+{
+ time_t t;
+ if (nt == 0) {
+ return "NTTIME(0)";
+ }
+ t = nt_time_to_full_time_t(nt);
+ return timestring(mem_ctx, t);
+}
+
+
+/**
+ put a NTTIME into a packet
+*/
+_PUBLIC_ void push_nttime(uint8_t *base, uint16_t offset, NTTIME t)
+{
+ SBVAL(base, offset, t);
+}
+
+/**
+ pull a NTTIME from a packet
+*/
+_PUBLIC_ NTTIME pull_nttime(uint8_t *base, uint16_t offset)
+{
+ NTTIME ret = BVAL(base, offset);
+ return ret;
+}
+
+/**
+ return (tv1 - tv2) in microseconds
+*/
+_PUBLIC_ int64_t usec_time_diff(const struct timeval *tv1, const struct timeval *tv2)
+{
+ int64_t sec_diff = tv1->tv_sec - tv2->tv_sec;
+ return (sec_diff * 1000000) + (int64_t)(tv1->tv_usec - tv2->tv_usec);
+}
+
+/**
+ return (tp1 - tp2) in nanoseconds
+*/
+_PUBLIC_ int64_t nsec_time_diff(const struct timespec *tp1, const struct timespec *tp2)
+{
+ int64_t sec_diff = tp1->tv_sec - tp2->tv_sec;
+ return (sec_diff * 1000000000) + (int64_t)(tp1->tv_nsec - tp2->tv_nsec);
+}
+
+
+/**
+ return a zero timeval
+*/
+_PUBLIC_ struct timeval timeval_zero(void)
+{
+ struct timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ return tv;
+}
+
+/**
+ return true if a timeval is zero
+*/
+_PUBLIC_ bool timeval_is_zero(const struct timeval *tv)
+{
+ return tv->tv_sec == 0 && tv->tv_usec == 0;
+}
+
+/**
+ return a timeval for the current time
+*/
+_PUBLIC_ struct timeval timeval_current(void)
+{
+ struct timeval tv;
+ GetTimeOfDay(&tv);
+ return tv;
+}
+
+/**
+ return a timeval struct with the given elements
+*/
+_PUBLIC_ struct timeval timeval_set(uint32_t secs, uint32_t usecs)
+{
+ struct timeval tv;
+ tv.tv_sec = secs;
+ tv.tv_usec = usecs;
+ return tv;
+}
+
+
+/**
+ return a timeval ofs microseconds after tv
+*/
+_PUBLIC_ struct timeval timeval_add(const struct timeval *tv,
+ uint32_t secs, uint32_t usecs)
+{
+ struct timeval tv2 = *tv;
+ const unsigned int million = 1000000;
+ tv2.tv_sec += secs;
+ tv2.tv_usec += usecs;
+ tv2.tv_sec += tv2.tv_usec / million;
+ tv2.tv_usec = tv2.tv_usec % million;
+ return tv2;
+}
+
+/**
+ return the sum of two timeval structures
+*/
+struct timeval timeval_sum(const struct timeval *tv1,
+ const struct timeval *tv2)
+{
+ return timeval_add(tv1, tv2->tv_sec, tv2->tv_usec);
+}
+
+/**
+ return a timeval secs/usecs into the future
+*/
+_PUBLIC_ struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs)
+{
+ struct timeval tv = timeval_current();
+ return timeval_add(&tv, secs, usecs);
+}
+
+/**
+ return a timeval milliseconds into the future
+*/
+_PUBLIC_ struct timeval timeval_current_ofs_msec(uint32_t msecs)
+{
+ struct timeval tv = timeval_current();
+ return timeval_add(&tv, msecs / 1000, (msecs % 1000) * 1000);
+}
+
+/**
+ return a timeval microseconds into the future
+*/
+_PUBLIC_ struct timeval timeval_current_ofs_usec(uint32_t usecs)
+{
+ struct timeval tv = timeval_current();
+ return timeval_add(&tv, usecs / 1000000, usecs % 1000000);
+}
+
+/**
+ compare two timeval structures.
+ Return -1 if tv1 < tv2
+ Return 0 if tv1 == tv2
+ Return 1 if tv1 > tv2
+*/
+_PUBLIC_ int timeval_compare(const struct timeval *tv1, const struct timeval *tv2)
+{
+ if (tv1->tv_sec > tv2->tv_sec) return 1;
+ if (tv1->tv_sec < tv2->tv_sec) return -1;
+ if (tv1->tv_usec > tv2->tv_usec) return 1;
+ if (tv1->tv_usec < tv2->tv_usec) return -1;
+ return 0;
+}
+
+/**
+ return true if a timer is in the past
+*/
+_PUBLIC_ bool timeval_expired(const struct timeval *tv)
+{
+ struct timeval tv2 = timeval_current();
+ if (tv2.tv_sec > tv->tv_sec) return true;
+ if (tv2.tv_sec < tv->tv_sec) return false;
+ return (tv2.tv_usec >= tv->tv_usec);
+}
+
+/**
+ return the number of seconds elapsed between two times
+*/
+_PUBLIC_ double timeval_elapsed2(const struct timeval *tv1, const struct timeval *tv2)
+{
+ return (tv2->tv_sec - tv1->tv_sec) +
+ (tv2->tv_usec - tv1->tv_usec)*1.0e-6;
+}
+
+/**
+ return the number of seconds elapsed since a given time
+*/
+_PUBLIC_ double timeval_elapsed(const struct timeval *tv)
+{
+ struct timeval tv2 = timeval_current();
+ return timeval_elapsed2(tv, &tv2);
+}
+/**
+ * return the number of seconds elapsed between two times
+ **/
+_PUBLIC_ double timespec_elapsed2(const struct timespec *ts1,
+ const struct timespec *ts2)
+{
+ return (ts2->tv_sec - ts1->tv_sec) +
+ (ts2->tv_nsec - ts1->tv_nsec)*1.0e-9;
+}
+
+/**
+ * return the number of seconds elapsed since a given time
+ */
+_PUBLIC_ double timespec_elapsed(const struct timespec *ts)
+{
+ struct timespec ts2 = timespec_current();
+ return timespec_elapsed2(ts, &ts2);
+}
+
+/**
+ return the lesser of two timevals
+*/
+_PUBLIC_ struct timeval timeval_min(const struct timeval *tv1,
+ const struct timeval *tv2)
+{
+ if (tv1->tv_sec < tv2->tv_sec) return *tv1;
+ if (tv1->tv_sec > tv2->tv_sec) return *tv2;
+ if (tv1->tv_usec < tv2->tv_usec) return *tv1;
+ return *tv2;
+}
+
+/**
+ return the greater of two timevals
+*/
+_PUBLIC_ struct timeval timeval_max(const struct timeval *tv1,
+ const struct timeval *tv2)
+{
+ if (tv1->tv_sec > tv2->tv_sec) return *tv1;
+ if (tv1->tv_sec < tv2->tv_sec) return *tv2;
+ if (tv1->tv_usec > tv2->tv_usec) return *tv1;
+ return *tv2;
+}
+
+/**
+ return the difference between two timevals as a timeval
+ if tv1 comes after tv2, then return a zero timeval
+ (this is *tv2 - *tv1)
+*/
+_PUBLIC_ struct timeval timeval_until(const struct timeval *tv1,
+ const struct timeval *tv2)
+{
+ struct timeval t;
+ if (timeval_compare(tv1, tv2) >= 0) {
+ return timeval_zero();
+ }
+ t.tv_sec = tv2->tv_sec - tv1->tv_sec;
+ if (tv1->tv_usec > tv2->tv_usec) {
+ t.tv_sec--;
+ t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec);
+ } else {
+ t.tv_usec = tv2->tv_usec - tv1->tv_usec;
+ }
+ return t;
+}
+
+
+/**
+ convert a timeval to a NTTIME
+*/
+_PUBLIC_ NTTIME timeval_to_nttime(const struct timeval *tv)
+{
+ return 10*(tv->tv_usec +
+ ((TIME_FIXUP_CONSTANT + (uint64_t)tv->tv_sec) * 1000000));
+}
+
+/**
+ convert a NTTIME to a timeval
+*/
+_PUBLIC_ void nttime_to_timeval(struct timeval *tv, NTTIME t)
+{
+ if (tv == NULL) return;
+
+ t += 10/2;
+ t /= 10;
+ t -= TIME_FIXUP_CONSTANT*1000*1000;
+
+ tv->tv_sec = t / 1000000;
+
+ if (TIME_T_MIN > tv->tv_sec || tv->tv_sec > TIME_T_MAX) {
+ tv->tv_sec = 0;
+ tv->tv_usec = 0;
+ return;
+ }
+
+ tv->tv_usec = t - tv->tv_sec*1000000;
+}
+
+/*******************************************************************
+yield the difference between *A and *B, in seconds, ignoring leap seconds
+********************************************************************/
+static int tm_diff(struct tm *a, struct tm *b)
+{
+ int ay = a->tm_year + (1900 - 1);
+ int by = b->tm_year + (1900 - 1);
+ int intervening_leap_days =
+ (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
+ int years = ay - by;
+ int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
+ int hours = 24*days + (a->tm_hour - b->tm_hour);
+ int minutes = 60*hours + (a->tm_min - b->tm_min);
+ int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
+
+ return seconds;
+}
+
+
+/**
+ return the UTC offset in seconds west of UTC, or 0 if it cannot be determined
+ */
+_PUBLIC_ int get_time_zone(time_t t)
+{
+ struct tm *tm = gmtime(&t);
+ struct tm tm_utc;
+ if (!tm)
+ return 0;
+ tm_utc = *tm;
+ tm = localtime(&t);
+ if (!tm)
+ return 0;
+ return tm_diff(&tm_utc,tm);
+}
+
+/*
+ * Raw convert an NTTIME to a unix timespec.
+ */
+
+struct timespec nt_time_to_unix_timespec_raw(
+ NTTIME nt)
+{
+ int64_t d;
+ struct timespec ret;
+
+ d = (int64_t)nt;
+ /* d is now in 100ns units, since jan 1st 1601".
+ Save off the ns fraction. */
+
+ /*
+ * Take the last seven decimal digits and multiply by 100.
+ * to convert from 100ns units to 1ns units.
+ */
+ ret.tv_nsec = (long) ((d % (1000 * 1000 * 10)) * 100);
+
+ /* Convert to seconds */
+ d /= 1000*1000*10;
+
+ /* Now adjust by 369 years to make the secs since 1970 */
+ d -= TIME_FIXUP_CONSTANT_INT;
+
+ ret.tv_sec = (time_t)d;
+ return ret;
+}
+
+struct timespec nt_time_to_unix_timespec(NTTIME nt)
+{
+ struct timespec ret;
+
+ if (nt == 0 || nt == UINT64_MAX) {
+ ret.tv_sec = 0;
+ ret.tv_nsec = 0;
+ return ret;
+ }
+
+ ret = nt_time_to_unix_timespec_raw(nt);
+
+ if (ret.tv_sec <= TIME_T_MIN) {
+ ret.tv_sec = TIME_T_MIN;
+ ret.tv_nsec = 0;
+ return ret;
+ }
+
+ if (ret.tv_sec >= TIME_T_MAX) {
+ ret.tv_sec = TIME_T_MAX;
+ ret.tv_nsec = 0;
+ return ret;
+ }
+ return ret;
+}
+
+
+/**
+ check if 2 NTTIMEs are equal.
+*/
+bool nt_time_equal(NTTIME *t1, NTTIME *t2)
+{
+ return *t1 == *t2;
+}
+
+/**
+ Check if it's a null timespec.
+**/
+
+bool null_timespec(struct timespec ts)
+{
+ return ts.tv_sec == 0 ||
+ ts.tv_sec == (time_t)0xFFFFFFFF ||
+ ts.tv_sec == (time_t)-1;
+}
+
+/****************************************************************************
+ Convert a normalized timeval to a timespec.
+****************************************************************************/
+
+struct timespec convert_timeval_to_timespec(const struct timeval tv)
+{
+ struct timespec ts;
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
+ return ts;
+}
+
+/****************************************************************************
+ Convert a normalized timespec to a timeval.
+****************************************************************************/
+
+struct timeval convert_timespec_to_timeval(const struct timespec ts)
+{
+ struct timeval tv;
+ tv.tv_sec = ts.tv_sec;
+ tv.tv_usec = ts.tv_nsec / 1000;
+ return tv;
+}
+
+/****************************************************************************
+ Return a timespec for the current time
+****************************************************************************/
+
+_PUBLIC_ struct timespec timespec_current(void)
+{
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ return ts;
+}
+
+/****************************************************************************
+ Return the lesser of two timespecs.
+****************************************************************************/
+
+struct timespec timespec_min(const struct timespec *ts1,
+ const struct timespec *ts2)
+{
+ if (ts1->tv_sec < ts2->tv_sec) return *ts1;
+ if (ts1->tv_sec > ts2->tv_sec) return *ts2;
+ if (ts1->tv_nsec < ts2->tv_nsec) return *ts1;
+ return *ts2;
+}
+
+/****************************************************************************
+ compare two timespec structures.
+ Return -1 if ts1 < ts2
+ Return 0 if ts1 == ts2
+ Return 1 if ts1 > ts2
+****************************************************************************/
+
+_PUBLIC_ int timespec_compare(const struct timespec *ts1, const struct timespec *ts2)
+{
+ if (ts1->tv_sec > ts2->tv_sec) return 1;
+ if (ts1->tv_sec < ts2->tv_sec) return -1;
+ if (ts1->tv_nsec > ts2->tv_nsec) return 1;
+ if (ts1->tv_nsec < ts2->tv_nsec) return -1;
+ return 0;
+}
+
+/****************************************************************************
+ Round up a timespec if nsec > 500000000, round down if lower,
+ then zero nsec.
+****************************************************************************/
+
+void round_timespec_to_sec(struct timespec *ts)
+{
+ ts->tv_sec = convert_timespec_to_time_t(*ts);
+ ts->tv_nsec = 0;
+}
+
+/****************************************************************************
+ Round a timespec to usec value.
+****************************************************************************/
+
+void round_timespec_to_usec(struct timespec *ts)
+{
+ struct timeval tv = convert_timespec_to_timeval(*ts);
+ *ts = convert_timeval_to_timespec(tv);
+ normalize_timespec(ts);
+}
+
+/****************************************************************************
+ Round a timespec to NTTIME resolution.
+****************************************************************************/
+
+void round_timespec_to_nttime(struct timespec *ts)
+{
+ ts->tv_nsec = (ts->tv_nsec / 100) * 100;
+}
+
+/****************************************************************************
+ Put a 8 byte filetime from a struct timespec. Uses GMT.
+****************************************************************************/
+
+_PUBLIC_ NTTIME unix_timespec_to_nt_time(struct timespec ts)
+{
+ uint64_t d;
+
+ if (ts.tv_sec ==0 && ts.tv_nsec == 0) {
+ return 0;
+ }
+ if (ts.tv_sec == TIME_T_MAX) {
+ return 0x7fffffffffffffffLL;
+ }
+ if (ts.tv_sec == (time_t)-1) {
+ return UINT64_MAX;
+ }
+
+ d = ts.tv_sec;
+ d += TIME_FIXUP_CONSTANT_INT;
+ d *= 1000*1000*10;
+ /* d is now in 100ns units. */
+ d += (ts.tv_nsec / 100);
+
+ return d;
+}
+
+/*
+ * Functions supporting the full range of time_t and struct timespec values,
+ * including 0, -1 and all other negative values. These functions don't use 0 or
+ * -1 values as sentinel to denote "unset" variables, but use the POSIX 2008
+ * define UTIME_OMIT from utimensat(2).
+ */
+
+/**
+ * Check if it's a to be omitted timespec.
+ **/
+bool is_omit_timespec(const struct timespec *ts)
+{
+ return ts->tv_nsec == SAMBA_UTIME_OMIT;
+}
+
+/**
+ * Return a to be omitted timespec.
+ **/
+struct timespec make_omit_timespec(void)
+{
+ return (struct timespec){.tv_nsec = SAMBA_UTIME_OMIT};
+}
+
+/**
+ * Like unix_timespec_to_nt_time() but without the special casing of tv_sec=0
+ * and -1. Also dealing with SAMBA_UTIME_OMIT.
+ **/
+NTTIME full_timespec_to_nt_time(const struct timespec *_ts)
+{
+ struct timespec ts = *_ts;
+ uint64_t d;
+
+ if (is_omit_timespec(_ts)) {
+ return NTTIME_OMIT;
+ }
+
+ /* Ensure tv_nsec is less than 1 sec. */
+ while (ts.tv_nsec > 1000000000) {
+ if (ts.tv_sec > TIME_T_MAX) {
+ return NTTIME_MAX;
+ }
+ ts.tv_sec += 1;
+ ts.tv_nsec -= 1000000000;
+ }
+
+ if (ts.tv_sec >= TIME_T_MAX) {
+ return NTTIME_MAX;
+ }
+ if ((ts.tv_sec + TIME_FIXUP_CONSTANT_INT) <= 0) {
+ return NTTIME_MIN;
+ }
+
+ d = TIME_FIXUP_CONSTANT_INT;
+ d += ts.tv_sec;
+
+ d *= 1000*1000*10;
+ /* d is now in 100ns units. */
+ d += (ts.tv_nsec / 100);
+
+ return d;
+}
+
+/**
+ * Like nt_time_to_unix_timespec() but allowing negative tv_sec values and
+ * returning NTTIME=0 and -1 as struct timespec {.tv_nsec = SAMBA_UTIME_OMIT}.
+ *
+ * See also: is_omit_timespec().
+ **/
+struct timespec nt_time_to_full_timespec(NTTIME nt)
+{
+ struct timespec ret;
+
+ if (nt == NTTIME_OMIT) {
+ return make_omit_timespec();
+ }
+ if (nt == NTTIME_FREEZE || nt == NTTIME_THAW) {
+ /*
+ * This should be returned as SAMBA_UTIME_FREEZE or
+ * SAMBA_UTIME_THAW in the future.
+ */
+ return make_omit_timespec();
+ }
+ if (nt > NTTIME_MAX) {
+ nt = NTTIME_MAX;
+ }
+
+ ret = nt_time_to_unix_timespec_raw(nt);
+
+ if (ret.tv_sec >= TIME_T_MAX) {
+ ret.tv_sec = TIME_T_MAX;
+ ret.tv_nsec = 0;
+ return ret;
+ }
+
+ return ret;
+}
+
+/**
+ * Note: this function uses the full time_t range as valid date values including
+ * (time_t)0 and -1. That means that struct timespec sentinel values (cf
+ * is_omit_timespec()) can't be converted to sentinel values in a time_t
+ * representation. Callers should therefore check the NTTIME value with
+ * null_nttime() before calling this function.
+ **/
+time_t full_timespec_to_time_t(const struct timespec *_ts)
+{
+ struct timespec ts = *_ts;
+
+ if (is_omit_timespec(_ts)) {
+ /*
+ * Unfortunately there's no sensible sentinel value in the
+ * time_t range that is not conflicting with a valid time value
+ * ((time_t)0 and -1 are valid time values). Bite the bullit and
+ * return 0.
+ */
+ return 0;
+ }
+
+ /* Ensure tv_nsec is less than 1sec. */
+ while (ts.tv_nsec > 1000000000) {
+ ts.tv_sec += 1;
+ ts.tv_nsec -= 1000000000;
+ }
+
+ /* 1 ns == 1,000,000,000 - one thousand millionths of a second.
+ increment if it's greater than 500 millionth of a second. */
+
+ if (ts.tv_nsec > 500000000) {
+ return ts.tv_sec + 1;
+ }
+ return ts.tv_sec;
+}
+
+/**
+ * Like nt_time_to_unix() but supports negative time_t values.
+ *
+ * Note: this function uses the full time_t range as valid date values including
+ * (time_t)0 and -1. That means that NTTIME sentinel values of 0 and -1 which
+ * represent a "not-set" value, can't be converted to sentinel values in a
+ * time_t representation. Callers should therefore check the NTTIME value with
+ * null_nttime() before calling this function.
+ **/
+time_t nt_time_to_full_time_t(NTTIME nt)
+{
+ struct timespec ts;
+
+ ts = nt_time_to_full_timespec(nt);
+ return full_timespec_to_time_t(&ts);
+}
+
+/**
+ * Like time_t_to_unix_timespec() but supports negative time_t values.
+ *
+ * This version converts (time_t)0 and -1 to an is_omit_timespec(), so 0 and -1
+ * can't be used as valid date values. The function supports values < -1 though.
+ **/
+struct timespec time_t_to_full_timespec(time_t t)
+{
+ if (null_time(t)) {
+ return (struct timespec){.tv_nsec = SAMBA_UTIME_OMIT};
+ }
+ return (struct timespec){.tv_sec = t};
+}
+
+#if !defined(HAVE_STAT_HIRES_TIMESTAMPS)
+
+/* Old system - no ns timestamp. */
+time_t get_atimensec(const struct stat *st)
+{
+ return 0;
+}
+
+time_t get_mtimensec(const struct stat *st)
+{
+ return 0;
+}
+
+time_t get_ctimensec(const struct stat *st)
+{
+ return 0;
+}
+
+/* Set does nothing with no ns timestamp. */
+void set_atimensec(struct stat *st, time_t ns)
+{
+ return;
+}
+
+void set_mtimensec(struct stat *st, time_t ns)
+{
+ return;
+}
+
+void set_ctimensec(struct stat *st, time_t ns)
+{
+ return;
+}
+
+#elif HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
+
+time_t get_atimensec(const struct stat *st)
+{
+ return st->st_atimespec.tv_nsec;
+}
+
+time_t get_mtimensec(const struct stat *st)
+{
+ return st->st_mtimespec.tv_nsec;
+}
+
+time_t get_ctimensec(const struct stat *st)
+{
+ return st->st_ctimespec.tv_nsec;
+}
+
+void set_atimensec(struct stat *st, time_t ns)
+{
+ st->st_atimespec.tv_nsec = ns;
+}
+
+void set_mtimensec(struct stat *st, time_t ns)
+{
+ st->st_mtimespec.tv_nsec = ns;
+}
+
+void set_ctimensec(struct stat *st, time_t ns)
+{
+ st->st_ctimespec.tv_nsec = ns;
+}
+
+#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+
+time_t get_atimensec(const struct stat *st)
+{
+ return st->st_atim.tv_nsec;
+}
+
+time_t get_mtimensec(const struct stat *st)
+{
+ return st->st_mtim.tv_nsec;
+}
+
+time_t get_ctimensec(const struct stat *st)
+{
+ return st->st_ctim.tv_nsec;
+}
+
+void set_atimensec(struct stat *st, time_t ns)
+{
+ st->st_atim.tv_nsec = ns;
+}
+
+void set_mtimensec(struct stat *st, time_t ns)
+{
+ st->st_mtim.tv_nsec = ns;
+}
+void set_ctimensec(struct stat *st, time_t ns)
+{
+ st->st_ctim.tv_nsec = ns;
+}
+
+#elif HAVE_STRUCT_STAT_ST_MTIMENSEC
+
+time_t get_atimensec(const struct stat *st)
+{
+ return st->st_atimensec;
+}
+
+time_t get_mtimensec(const struct stat *st)
+{
+ return st->st_mtimensec;
+}
+
+time_t get_ctimensec(const struct stat *st)
+{
+ return st->st_ctimensec;
+}
+
+void set_atimensec(struct stat *st, time_t ns)
+{
+ st->st_atimensec = ns;
+}
+
+void set_mtimensec(struct stat *st, time_t ns)
+{
+ st->st_mtimensec = ns;
+}
+
+void set_ctimensec(struct stat *st, time_t ns)
+{
+ st->st_ctimensec = ns;
+}
+
+#elif HAVE_STRUCT_STAT_ST_MTIME_N
+
+time_t get_atimensec(const struct stat *st)
+{
+ return st->st_atime_n;
+}
+
+time_t get_mtimensec(const struct stat *st)
+{
+ return st->st_mtime_n;
+}
+
+time_t get_ctimensec(const struct stat *st)
+{
+ return st->st_ctime_n;
+}
+
+void set_atimensec(struct stat *st, time_t ns)
+{
+ st->st_atime_n = ns;
+}
+
+void set_mtimensec(struct stat *st, time_t ns)
+{
+ st->st_mtime_n = ns;
+}
+
+void set_ctimensec(struct stat *st, time_t ns)
+{
+ st->st_ctime_n = ns;
+}
+
+#elif HAVE_STRUCT_STAT_ST_UMTIME
+
+/* Only usec timestamps available. Convert to/from nsec. */
+
+time_t get_atimensec(const struct stat *st)
+{
+ return st->st_uatime * 1000;
+}
+
+time_t get_mtimensec(const struct stat *st)
+{
+ return st->st_umtime * 1000;
+}
+
+time_t get_ctimensec(const struct stat *st)
+{
+ return st->st_uctime * 1000;
+}
+
+void set_atimensec(struct stat *st, time_t ns)
+{
+ st->st_uatime = ns / 1000;
+}
+
+void set_mtimensec(struct stat *st, time_t ns)
+{
+ st->st_umtime = ns / 1000;
+}
+
+void set_ctimensec(struct stat *st, time_t ns)
+{
+ st->st_uctime = ns / 1000;
+}
+
+#else
+#error CONFIGURE_ERROR_IN_DETECTING_TIMESPEC_IN_STAT
+#endif
+
+struct timespec get_atimespec(const struct stat *pst)
+{
+ struct timespec ret;
+
+ ret.tv_sec = pst->st_atime;
+ ret.tv_nsec = get_atimensec(pst);
+ return ret;
+}
+
+struct timespec get_mtimespec(const struct stat *pst)
+{
+ struct timespec ret;
+
+ ret.tv_sec = pst->st_mtime;
+ ret.tv_nsec = get_mtimensec(pst);
+ return ret;
+}
+
+struct timespec get_ctimespec(const struct stat *pst)
+{
+ struct timespec ret;
+
+ ret.tv_sec = pst->st_ctime;
+ ret.tv_nsec = get_ctimensec(pst);
+ return ret;
+}
+
+/****************************************************************************
+ Deal with nanoseconds overflow.
+****************************************************************************/
+
+void normalize_timespec(struct timespec *ts)
+{
+ lldiv_t dres;
+
+ /* most likely case: nsec is valid */
+ if ((unsigned long)ts->tv_nsec < NSEC_PER_SEC) {
+ return;
+ }
+
+ dres = lldiv(ts->tv_nsec, NSEC_PER_SEC);
+
+ /* if the operation would result in overflow, max out values and bail */
+ if (dres.quot > 0) {
+ if ((int64_t)LONG_MAX - dres.quot < ts->tv_sec) {
+ ts->tv_sec = LONG_MAX;
+ ts->tv_nsec = NSEC_PER_SEC - 1;
+ return;
+ }
+ } else {
+ if ((int64_t)LONG_MIN - dres.quot > ts->tv_sec) {
+ ts->tv_sec = LONG_MIN;
+ ts->tv_nsec = 0;
+ return;
+ }
+ }
+
+ ts->tv_nsec = dres.rem;
+ ts->tv_sec += dres.quot;
+
+ /* if the ns part was positive or a multiple of -1000000000, we're done */
+ if (ts->tv_nsec > 0 || dres.rem == 0) {
+ return;
+ }
+
+ ts->tv_nsec += NSEC_PER_SEC;
+ --ts->tv_sec;
+}
diff --git a/lib/util/time.h b/lib/util/time.h
new file mode 100644
index 0000000..4870c84
--- /dev/null
+++ b/lib/util/time.h
@@ -0,0 +1,404 @@
+/*
+ Unix SMB/CIFS implementation.
+ time utility functions
+
+ Copyright (C) Andrew Tridgell 1992-2004
+ Copyright (C) Stefan (metze) Metzmacher 2002
+ Copyright (C) Jeremy Allison 2007
+ Copyright (C) Andrew Bartlett 2011
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_TIME_H_
+#define _SAMBA_TIME_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <talloc.h>
+#include <time.h>
+
+#ifndef TIME_T_MIN
+/* we use 0 here, because (time_t)-1 means error */
+#define TIME_T_MIN 0
+#endif
+
+/*
+ * we use the INT32_MAX here as on 64 bit systems,
+ * gmtime() fails with INT64_MAX
+ */
+#ifndef TIME_T_MAX
+#define TIME_T_MAX MIN(INT32_MAX,_TYPE_MAXIMUM(time_t))
+#endif
+
+/*
+ * According to Windows API FileTimeToSystemTime() documentation the highest
+ * allowed value " ... must be less than 0x8000000000000000.".
+ */
+#define NTTIME_MAX INT64_MAX
+
+/*
+ * The lowest possible value when NTTIME=0 is used as sentinel value.
+ */
+#define NTTIME_MIN 1
+
+/*
+ * NTTIME_OMIT in a setinfo tells us to not modify the corresponding on-disk
+ * timestamp value.
+ */
+#define NTTIME_OMIT 0
+
+/*
+ * Disable automatic timestamp updates, as described in MS-FSA. Samba doesn't
+ * implement this yet.
+ */
+#define NTTIME_FREEZE UINT64_MAX
+#define NTTIME_THAW (UINT64_MAX - 1)
+
+#define SAMBA_UTIME_NOW UTIME_NOW
+#define SAMBA_UTIME_OMIT UTIME_OMIT
+
+/* 64 bit time (100 nanosec) 1601 - cifs6.txt, section 3.5, page 30, 4 byte aligned */
+typedef uint64_t NTTIME;
+
+#define NTTIME_USEC (10UL)
+#define NTTIME_MSEC (1000UL * NTTIME_USEC)
+
+/**
+ External access to time_t_min and time_t_max.
+**/
+time_t get_time_t_max(void);
+
+/**
+a gettimeofday wrapper
+**/
+void GetTimeOfDay(struct timeval *tval);
+
+/**
+a wrapper to preferably get the monotonic time
+**/
+void clock_gettime_mono(struct timespec *tp);
+
+/**
+a wrapper to preferably get the monotonic time in s
+**/
+time_t time_mono(time_t *t);
+
+/**
+interpret an 8 byte "filetime" structure to a time_t
+It's originally in "100ns units since jan 1st 1601"
+**/
+time_t nt_time_to_unix(NTTIME nt);
+
+/**
+put a 8 byte filetime from a time_t
+This takes GMT as input
+**/
+void unix_to_nt_time(NTTIME *nt, time_t t);
+
+/**
+check if it's a null unix time
+**/
+bool null_time(time_t t);
+
+/**
+check if it's a null NTTIME
+**/
+bool null_nttime(NTTIME t);
+
+/**
+put a dos date into a buffer (time/date format)
+This takes GMT time and puts local time in the buffer
+**/
+void push_dos_date(uint8_t *buf, int offset, time_t unixdate, int zone_offset);
+
+/**
+put a dos date into a buffer (date/time format)
+This takes GMT time and puts local time in the buffer
+**/
+void push_dos_date2(uint8_t *buf,int offset,time_t unixdate, int zone_offset);
+
+/**
+put a dos 32 bit "unix like" date into a buffer. This routine takes
+GMT and converts it to LOCAL time before putting it (most SMBs assume
+localtime for this sort of date)
+**/
+void push_dos_date3(uint8_t *buf,int offset,time_t unixdate, int zone_offset);
+
+/**
+ create a unix date (int GMT) from a dos date (which is actually in
+ localtime)
+**/
+time_t pull_dos_date(const uint8_t *date_ptr, int zone_offset);
+
+/**
+like make_unix_date() but the words are reversed
+**/
+time_t pull_dos_date2(const uint8_t *date_ptr, int zone_offset);
+
+/**
+ create a unix GMT date from a dos date in 32 bit "unix like" format
+ these generally arrive as localtimes, with corresponding DST
+**/
+time_t pull_dos_date3(const uint8_t *date_ptr, int zone_offset);
+
+/**
+ Return a date and time as a string (optionally with microseconds)
+
+ format is %Y/%m/%d %H:%M:%S if strftime is available
+**/
+
+char *timeval_string(TALLOC_CTX *ctx, const struct timeval *tp, bool hires);
+
+struct timeval_buf;
+const char *timespec_string_buf(const struct timespec *tp,
+ bool hires,
+ struct timeval_buf *buf);
+
+/**
+ Return the current date and time as a string (optionally with microseconds)
+
+ format is %Y/%m/%d %H:%M:%S if strftime is available
+**/
+char *current_timestring(TALLOC_CTX *ctx, bool hires);
+
+/**
+ Return a date and time as a string (optionally with microseconds)
+
+ format is %Y%m%d_%H%M%S or %Y%m%d_%H%M%S_%us
+**/
+
+char *minimal_timeval_string(TALLOC_CTX *ctx, const struct timeval *tp, bool hires);
+
+/**
+ Return the current date and time as a string (optionally with microseconds)
+
+ format is %Y%m%d_%H%M%S or %Y%m%d_%H%M%S_%us
+**/
+char *current_minimal_timestring(TALLOC_CTX *ctx, bool hires);
+
+/**
+return a HTTP/1.0 time string
+**/
+char *http_timestring(TALLOC_CTX *mem_ctx, time_t t);
+
+/**
+ Return the date and time as a string
+
+ format is %a %b %e %X %Y %Z
+**/
+char *timestring(TALLOC_CTX *mem_ctx, time_t t);
+
+/**
+ return a talloced string representing a NTTIME for human consumption
+*/
+const char *nt_time_string(TALLOC_CTX *mem_ctx, NTTIME nt);
+
+/**
+ put a NTTIME into a packet
+*/
+void push_nttime(uint8_t *base, uint16_t offset, NTTIME t);
+
+/**
+ pull a NTTIME from a packet
+*/
+NTTIME pull_nttime(uint8_t *base, uint16_t offset);
+
+/**
+ return (tv1 - tv2) in microseconds
+*/
+int64_t usec_time_diff(const struct timeval *tv1, const struct timeval *tv2);
+
+/**
+ return (tp1 - tp2) in nanoseconds
+*/
+int64_t nsec_time_diff(const struct timespec *tp1, const struct timespec *tp2);
+
+/**
+ return a zero timeval
+*/
+struct timeval timeval_zero(void);
+
+/**
+ return true if a timeval is zero
+*/
+bool timeval_is_zero(const struct timeval *tv);
+
+/**
+ return a timeval for the current time
+*/
+struct timeval timeval_current(void);
+
+/**
+ return a timeval struct with the given elements
+*/
+struct timeval timeval_set(uint32_t secs, uint32_t usecs);
+
+/**
+ return a timeval ofs microseconds after tv
+*/
+struct timeval timeval_add(const struct timeval *tv,
+ uint32_t secs, uint32_t usecs);
+
+/**
+ return the sum of two timeval structures
+*/
+struct timeval timeval_sum(const struct timeval *tv1,
+ const struct timeval *tv2);
+
+/**
+ return a timeval secs/usecs into the future
+*/
+struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs);
+
+/**
+ return a timeval milliseconds into the future
+*/
+struct timeval timeval_current_ofs_msec(uint32_t msecs);
+
+/**
+ return a timeval microseconds into the future
+*/
+struct timeval timeval_current_ofs_usec(uint32_t usecs);
+
+/**
+ compare two timeval structures.
+ Return -1 if tv1 < tv2
+ Return 0 if tv1 == tv2
+ Return 1 if tv1 > tv2
+*/
+int timeval_compare(const struct timeval *tv1, const struct timeval *tv2);
+
+/**
+ return true if a timer is in the past
+*/
+bool timeval_expired(const struct timeval *tv);
+
+/**
+ return the number of seconds elapsed between two times
+*/
+double timeval_elapsed2(const struct timeval *tv1, const struct timeval *tv2);
+
+/**
+ return the number of seconds elapsed since a given time
+*/
+double timeval_elapsed(const struct timeval *tv);
+
+/**
+ return the number of seconds elapsed between two times
+*/
+double timespec_elapsed2(const struct timespec *ts1,
+ const struct timespec *ts2);
+/**
+ return the number of seconds elapsed since a given time
+*/
+double timespec_elapsed(const struct timespec *ts);
+
+/**
+ return the lesser of two timevals
+*/
+struct timeval timeval_min(const struct timeval *tv1,
+ const struct timeval *tv2);
+
+/**
+ return the greater of two timevals
+*/
+struct timeval timeval_max(const struct timeval *tv1,
+ const struct timeval *tv2);
+
+/**
+ return the difference between two timevals as a timeval
+ if tv1 comes after tv2, then return a zero timeval
+ (this is *tv2 - *tv1)
+*/
+struct timeval timeval_until(const struct timeval *tv1,
+ const struct timeval *tv2);
+
+/**
+ convert a timeval to a NTTIME
+*/
+NTTIME timeval_to_nttime(const struct timeval *tv);
+
+/**
+ convert a NTTIME to a timeval
+*/
+void nttime_to_timeval(struct timeval *tv, NTTIME t);
+
+/**
+ return the UTC offset in seconds west of UTC, or 0 if it cannot be determined
+ */
+int get_time_zone(time_t t);
+
+/**
+ check if 2 NTTIMEs are equal.
+*/
+bool nt_time_equal(NTTIME *t1, NTTIME *t2);
+
+void interpret_dos_date(uint32_t date,int *year,int *month,int *day,int *hour,int *minute,int *second);
+
+struct timespec nt_time_to_unix_timespec_raw(NTTIME nt);
+
+struct timespec nt_time_to_unix_timespec(NTTIME nt);
+
+time_t convert_timespec_to_time_t(struct timespec ts);
+
+struct timespec convert_time_t_to_timespec(time_t t);
+
+bool null_timespec(struct timespec ts);
+
+struct timespec convert_timeval_to_timespec(const struct timeval tv);
+struct timeval convert_timespec_to_timeval(const struct timespec ts);
+struct timespec timespec_current(void);
+struct timespec timespec_min(const struct timespec *ts1,
+ const struct timespec *ts2);
+int timespec_compare(const struct timespec *ts1, const struct timespec *ts2);
+void round_timespec_to_sec(struct timespec *ts);
+void round_timespec_to_usec(struct timespec *ts);
+void round_timespec_to_nttime(struct timespec *ts);
+NTTIME unix_timespec_to_nt_time(struct timespec ts);
+void normalize_timespec(struct timespec *ts);
+
+/*
+ * Functions supporting the full range of time_t and struct timespec values,
+ * including 0, -1 and all other negative values. These functions don't use 0 or
+ * -1 values as sentinel to denote "unset" variables, but use the POSIX 2008
+ * define UTIME_OMIT from utimensat(2).
+ */
+bool is_omit_timespec(const struct timespec *ts);
+struct timespec make_omit_timespec(void);
+NTTIME full_timespec_to_nt_time(const struct timespec *ts);
+struct timespec nt_time_to_full_timespec(NTTIME nt);
+time_t full_timespec_to_time_t(const struct timespec *ts);
+time_t nt_time_to_full_time_t(NTTIME nt);
+struct timespec time_t_to_full_timespec(time_t t);
+
+/*
+ * Functions to get and set the number of nanoseconds for times in a stat field.
+ * If the stat has timestamp granularity less than nanosecond, then the set_*
+ * operations will be lossy.
+ */
+struct stat;
+time_t get_atimensec(const struct stat *);
+time_t get_mtimensec(const struct stat *);
+time_t get_ctimensec(const struct stat *);
+void set_atimensec(struct stat *, time_t);
+void set_mtimensec(struct stat *, time_t);
+void set_ctimensec(struct stat *, time_t);
+
+/* These are convenience wrappers for the above getters. */
+struct timespec get_atimespec(const struct stat *);
+struct timespec get_mtimespec(const struct stat *);
+struct timespec get_ctimespec(const struct stat *);
+
+#endif /* _SAMBA_TIME_H_ */
diff --git a/lib/util/time_basic.c b/lib/util/time_basic.c
new file mode 100644
index 0000000..095236b
--- /dev/null
+++ b/lib/util/time_basic.c
@@ -0,0 +1,99 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * time handling functions
+ *
+ * Copyright (C) Andrew Tridgell 1992-2004
+ * Copyright (C) Stefan (metze) Metzmacher 2002
+ * Copyright (C) Jeremy Allison 2007
+ * Copyright (C) Andrew Bartlett 2011
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/time.h"
+#include "lib/util/time_basic.h"
+
+/**
+a gettimeofday wrapper
+**/
+_PUBLIC_ void GetTimeOfDay(struct timeval *tval)
+{
+#if defined(HAVE_GETTIMEOFDAY_TZ) || defined(HAVE_GETTIMEOFDAY_TZ_VOID)
+ gettimeofday(tval,NULL);
+#else
+ gettimeofday(tval);
+#endif
+}
+
+/****************************************************************************
+ Return the date and time as a string
+****************************************************************************/
+
+char *timeval_str_buf(const struct timeval *tp, bool rfc5424, bool hires,
+ struct timeval_buf *dst)
+{
+ time_t t;
+ struct tm *tm;
+ size_t len;
+
+ t = (time_t)tp->tv_sec;
+ tm = localtime(&t);
+
+ if (tm == NULL) {
+ if (hires) {
+ snprintf(dst->buf, sizeof(dst->buf),
+ "%ld.%06ld seconds since the Epoch",
+ (long)tp->tv_sec, (long)tp->tv_usec);
+ } else {
+ snprintf(dst->buf, sizeof(dst->buf),
+ "%ld seconds since the Epoch", (long)t);
+ }
+ return dst->buf;
+ }
+
+ len = snprintf(dst->buf, sizeof(dst->buf),
+ (rfc5424 ?
+ "%04d-%02d-%02dT%02d:%02d:%02d" :
+ "%04d/%02d/%02d %02d:%02d:%02d"),
+ 1900 + tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+ if ((rfc5424 || hires) && (len < sizeof(dst->buf))) {
+ len += snprintf(dst->buf + len, sizeof(dst->buf) - len,
+ ".%06ld", (long)tp->tv_usec);
+ }
+
+ if (rfc5424 && (len < sizeof(dst->buf))) {
+ struct tm tm_utc, tm_local;
+ int offset;
+
+ tm_local = *tm;
+ /* It is reasonable to assume that if localtime()
+ * worked above, then gmtime() should also work
+ * without error. */
+ tm_utc = *gmtime(&t);
+
+ offset = (tm_local.tm_hour - tm_utc.tm_hour) * 60 +
+ (tm_local.tm_min - tm_utc.tm_min);
+
+ snprintf(dst->buf + len, sizeof(dst->buf) - len,
+ "%c%02d:%02d",
+ (offset >=0 ? '+' : '-'),
+ abs(offset) / 60,
+ abs(offset) % 60);
+ }
+
+ return dst->buf;
+}
diff --git a/lib/util/time_basic.h b/lib/util/time_basic.h
new file mode 100644
index 0000000..e04cf1c
--- /dev/null
+++ b/lib/util/time_basic.h
@@ -0,0 +1,49 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * time handling functions
+ *
+ * Copyright (C) Andrew Tridgell 1992-2004
+ * Copyright (C) Stefan (metze) Metzmacher 2002
+ * Copyright (C) Jeremy Allison 2007
+ * Copyright (C) Andrew Bartlett 2011
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SAMBA_TIME_BASIC_H_
+#define _SAMBA_TIME_BASIC_H_
+
+struct timeval;
+
+/**
+a gettimeofday wrapper
+**/
+_PUBLIC_ void GetTimeOfDay(struct timeval *tval);
+
+struct timeval_buf { char buf[128]; };
+
+/**
+ Put a date and time into dst->buf, return it dst->buf
+ (optionally with microseconds)
+
+ If rfc5424 is true then produce the RFC5424 timestamp format (which
+ is a stricter instance of RFC3339 and is used for syslog). For
+ example: 2003-08-24T05:14:15.000003-07:00. Otherwise,
+ format is %Y/%m/%d %H:%M:%S
+**/
+
+char *timeval_str_buf(const struct timeval *tp, bool rfc5424, bool hires,
+ struct timeval_buf *dst);
+
+#endif /* _SAMBA_TIME_BASIC_H_ */
diff --git a/lib/util/tini.c b/lib/util/tini.c
new file mode 100644
index 0000000..36d7a45
--- /dev/null
+++ b/lib/util/tini.c
@@ -0,0 +1,320 @@
+/*
+ * Trivial smb.conf parsing code
+ *
+ * Copyright Volker Lendecke <vl@samba.org> 2014
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License Version 3 or later, in which case the
+ * provisions of the GPL are required INSTEAD OF the above restrictions.
+ * (This clause is necessary due to a potential bad interaction between the
+ * GPL and the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include "tini.h"
+
+static bool c_isspace(char c)
+{
+ unsigned char uc = c;
+ if (c != uc) {
+ return false;
+ }
+ return isspace(uc);
+}
+
+static int next_content(FILE *f)
+{
+ int c;
+
+ for (c = fgetc(f); c != EOF; c = fgetc(f)) {
+ if (!c_isspace(c)) {
+ break;
+ }
+ if (c == '\n') {
+ break;
+ }
+ }
+
+ return c;
+}
+
+static int next_end_of_line(FILE *f)
+{
+ int c;
+
+ for (c = fgetc(f); c != EOF; c = fgetc(f)) {
+ if (c == '\n') {
+ break;
+ }
+ }
+ return c;
+}
+
+static bool make_space(char **buf, size_t *buflen, size_t position)
+{
+ char *tmp;
+
+ if (position < *buflen) {
+ return true;
+ }
+ tmp = realloc(*buf, (*buflen) * 2);
+ if (tmp == NULL) {
+ return false;
+ }
+ *buf = tmp;
+ *buflen *= 2;
+ return true;
+}
+
+/*
+ * Get a conf line into *pbuf (which must be a malloc'ed buffer already).
+ *
+ * Ignores leading spaces
+ * Ignores comment lines
+ * Ignores empty lines
+ * Takes care of continuation lines
+ * Zaps multiple spaces into one
+ */
+
+static int get_line(FILE *f, char **pbuf, size_t *pbuflen)
+{
+ int c;
+ char *buf;
+ size_t buflen, pos;
+
+ buf = *pbuf;
+ buflen = *pbuflen;
+ pos = 0;
+
+next_line:
+
+ c = next_content(f);
+ if (c == EOF) {
+ return ENOENT;
+ }
+
+ if ((c == '#') || (c == ';')) {
+ /*
+ * Line starting with a comment, skip
+ */
+ c = next_end_of_line(f);
+ if (c == EOF) {
+ return ENOENT;
+ }
+ goto next_line;
+ }
+
+ if (c == '\n') {
+ /*
+ * Blank line, skip
+ */
+ goto next_line;
+ }
+
+ for ( ; c != EOF ; c = fgetc(f)) {
+
+ if (c == '\n') {
+
+ if ((pos > 0) && (buf[pos-1] == '\\')) {
+ /*
+ * Line ends in "\". Continuation.
+ */
+ pos -= 1;
+ continue;
+ }
+
+ if ((pos > 1) && (buf[pos-2] == '\\') &&
+ c_isspace(buf[pos-1])) {
+ /*
+ * Line ends in "\ ". Mind that we zap
+ * multiple spaces into one. Continuation.
+ */
+ pos -= 2;
+ continue;
+ }
+
+ /*
+ * No continuation, done with the line
+ */
+ break;
+ }
+
+ if ((pos > 0) && c_isspace(buf[pos-1]) && c_isspace(c)) {
+ /*
+ * Zap multiple spaces to one
+ */
+ continue;
+ }
+
+ if (!make_space(&buf, &buflen, pos)) {
+ return ENOMEM;
+ }
+ buf[pos++] = c;
+ }
+
+ if (!make_space(&buf, &buflen, pos)) {
+ return ENOMEM;
+ }
+ buf[pos++] = '\0';
+
+ *pbuf = buf;
+ return 0;
+}
+
+static bool parse_section(
+ char *buf, bool (*sfunc)(const char *section, void *private_data),
+ void *private_data)
+{
+ char *p, *q;
+
+ p = buf+1; /* skip [ */
+
+ q = strchr(p, ']');
+ if (q == NULL) {
+ return false;
+ }
+ *q = '\0';
+
+ return sfunc(p, private_data);
+}
+
+static char *trim_one_space(char *buf)
+{
+ size_t len;
+
+ if (c_isspace(buf[0])) {
+ buf += 1;
+ }
+ len = strlen(buf);
+ if (len == 0) {
+ return buf;
+ }
+ if (c_isspace(buf[len-1])) {
+ buf[len-1] = '\0';
+ }
+
+ return buf;
+}
+
+static bool parse_param(char *buf,
+ bool allow_empty_value,
+ bool (*pfunc)(const char *name, const char *value,
+ void *private_data),
+ void *private_data)
+{
+ char *equals;
+ char *name;
+ const char *value;
+ size_t len;
+ bool no_value = false;
+
+ equals = strchr(buf, '=');
+ if (equals != NULL) {
+ *equals = '\0';
+ } else {
+ if (allow_empty_value) {
+ no_value = true;
+ } else {
+ return true;
+ }
+ }
+
+ name = trim_one_space(buf);
+ len = strlen(buf);
+ if (len == 0) {
+ return false;
+ }
+
+ if (no_value) {
+ value = "";
+ } else {
+ value = trim_one_space(equals+1);
+ }
+
+ return pfunc(name, value, private_data);
+}
+
+bool tini_parse(FILE *f,
+ bool allow_empty_value,
+ bool (*sfunc)(const char *section, void *private_data),
+ bool (*pfunc)(const char *name, const char *value,
+ void *private_data),
+ void *private_data)
+{
+ char *buf;
+ size_t buflen;
+
+ buflen = 256;
+
+ buf = malloc(buflen);
+ if (buf == NULL) {
+ return false;
+ }
+
+ while (true) {
+ int ret;
+ bool ok;
+
+ ret = get_line(f, &buf, &buflen);
+
+ if (ret == ENOENT) {
+ /* No lines anymore */
+ break;
+ }
+
+ if (ret != 0) {
+ /* Real error */
+ free(buf);
+ return false;
+ }
+
+ switch(buf[0]) {
+ case 0:
+ continue;
+ break;
+ case '[':
+ ok = parse_section(buf, sfunc, private_data);
+ break;
+ default:
+ ok = parse_param(buf, allow_empty_value, pfunc, private_data);
+ break;
+ }
+
+ if (!ok) {
+ free(buf);
+ return false;
+ }
+ }
+ free(buf);
+ return true;
+}
diff --git a/lib/util/tini.h b/lib/util/tini.h
new file mode 100644
index 0000000..36fc080
--- /dev/null
+++ b/lib/util/tini.h
@@ -0,0 +1,45 @@
+/*
+ * Trivial smb.conf parsing code
+ *
+ * Copyright Volker Lendecke <vl@samba.org> 2014
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+
+bool tini_parse(FILE *f,
+ bool allow_empty_value,
+ bool (*sfunc)(const char *section, void *private_data),
+ bool (*pfunc)(const char *name, const char *value,
+ void *private_data),
+ void *private_data);
diff --git a/lib/util/tiniparser.c b/lib/util/tiniparser.c
new file mode 100644
index 0000000..428ccff
--- /dev/null
+++ b/lib/util/tiniparser.c
@@ -0,0 +1,390 @@
+/*
+ * Trivial smb.conf parsing code
+ * iniparser compatibility layer.
+ *
+ * Copyright Jeremy Allison <jra@samba.org> 2014
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License Version 3 or later, in which case the provisions
+ * of the GPL are required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <stddef.h>
+#include "tini.h"
+#include "tiniparser.h"
+
+struct tiniparser_entry {
+ struct tiniparser_entry *next_entry;
+ char *key;
+ char *value;
+};
+
+struct tiniparser_section {
+ struct tiniparser_section *next_section;
+ struct tiniparser_entry *entry_list;
+ char section_name[];
+};
+
+struct tiniparser_dictionary {
+ struct tiniparser_section *section_list;
+};
+
+/*
+ * Find a section from a given key.
+ * Also return start of subkey.
+ * Return NULL if section name can't be found,
+ * if no section name given, or no subkey given.
+ */
+
+static struct tiniparser_section *find_section(struct tiniparser_dictionary *d,
+ const char *key,
+ const char **subkey)
+{
+ struct tiniparser_section *curr_section;
+ const char *p;
+ size_t section_len;
+
+ if (key == NULL) {
+ return NULL;
+ }
+ p = strchr(key, ':');
+ if (p == NULL) {
+ /* No section. */
+ return NULL;
+ }
+
+ section_len = p - key;
+ /* Ensure we have at least one character of section name. */
+ if (section_len == 0) {
+ return NULL;
+ }
+ /* Ensure we have at least one character of subkey. */
+ if (p[1] == '\0') {
+ return NULL;
+ }
+
+ for (curr_section = d->section_list;
+ curr_section;
+ curr_section = curr_section->next_section) {
+ /*
+ * Check if the key section matches the
+ * section name *exactly* (with terminating
+ * null after section_len characters.
+ */
+ if ((strncasecmp(key, curr_section->section_name, section_len) == 0) &&
+ (curr_section->section_name[section_len] == '\0')) {
+ *subkey = p+1;
+ return curr_section;
+ }
+ }
+ return NULL;
+}
+
+static struct tiniparser_entry *find_entry(struct tiniparser_section *section,
+ const char *key)
+{
+ struct tiniparser_entry *curr_entry;
+
+ for (curr_entry = section->entry_list;
+ curr_entry;
+ curr_entry = curr_entry->next_entry) {
+ if (strcasecmp(key,
+ curr_entry->key) == 0) {
+ return curr_entry;
+ }
+ }
+ return NULL;
+}
+
+const char *tiniparser_getstring(struct tiniparser_dictionary *d,
+ const char *key,
+ const char *default_value)
+{
+ struct tiniparser_section *section;
+ struct tiniparser_entry *entry;
+ const char *subkey;
+
+ section = find_section(d, key, &subkey);
+ if (section == NULL) {
+ return default_value;
+ }
+
+ entry = find_entry(section, subkey);
+ if (entry == NULL) {
+ return default_value;
+ }
+
+ return entry->value;
+}
+
+
+bool tiniparser_getboolean(struct tiniparser_dictionary *d,
+ const char *key,
+ bool default_value)
+{
+ const char *value = tiniparser_getstring(d, key, NULL);
+
+ if (value == NULL) {
+ return default_value;
+ }
+
+ switch(value[0]) {
+ case '1':
+ case 'T':
+ case 't':
+ case 'y':
+ case 'Y':
+ return true;
+ case '0':
+ case 'F':
+ case 'f':
+ case 'n':
+ case 'N':
+ return false;
+ default:
+ break;
+ }
+
+ return default_value;
+}
+
+int tiniparser_getint(struct tiniparser_dictionary *d,
+ const char *key,
+ int default_value)
+{
+ const char *value = tiniparser_getstring(d, key, NULL);
+
+ if (value == NULL) {
+ return default_value;
+ }
+
+ return (int)strtol(value, NULL, 0);
+}
+
+static bool value_parser(const char *key,
+ const char *value,
+ void *private_data)
+{
+ struct tiniparser_dictionary *d =
+ (struct tiniparser_dictionary *)private_data;
+ struct tiniparser_section *section = d->section_list;
+ struct tiniparser_entry *entry = NULL;
+ size_t val_len;
+ size_t key_len;
+
+ if (section == NULL) {
+ return false;
+ }
+ if (key == NULL) {
+ return false;
+ }
+ if (value == NULL) {
+ return false;
+ }
+
+ key_len = strlen(key) + 1;
+ val_len = strlen(value) + 1;
+
+ entry = find_entry(section, key);
+ if (entry) {
+ /* Replace current value. */
+ char *new_val = malloc(val_len);
+ if (new_val == NULL) {
+ return false;
+ }
+ memcpy(new_val, value, val_len);
+ free(entry->value);
+ entry->value = new_val;
+ return true;
+ }
+
+ /* Create a new entry. */
+ entry = malloc(sizeof(struct tiniparser_entry));
+ if (entry == NULL) {
+ return false;
+ }
+ entry->key = malloc(key_len);
+ if (entry->key == NULL) {
+ free(entry);
+ return false;
+ }
+ memcpy(entry->key, key, key_len);
+
+ entry->value = malloc(val_len);
+ if (entry->value == NULL) {
+ free(entry->key);
+ free(entry);
+ return false;
+ }
+ memcpy(entry->value, value, val_len);
+
+ entry->next_entry = section->entry_list;
+ section->entry_list = entry;
+ return true;
+}
+
+static bool section_parser(const char *section_name,
+ void *private_data)
+{
+ struct tiniparser_section **pp_section;
+ struct tiniparser_section *new_section;
+ struct tiniparser_dictionary *d =
+ (struct tiniparser_dictionary *)private_data;
+ size_t section_name_len;
+
+ if (section_name == NULL) {
+ return false;
+ }
+
+ /* Section names can't contain ':' */
+ if (strchr(section_name, ':') != NULL) {
+ return false;
+ }
+
+ /* Do we already have this section ? */
+ for (pp_section = &d->section_list;
+ *pp_section;
+ pp_section = &(*pp_section)->next_section) {
+ if (strcasecmp(section_name,
+ (*pp_section)->section_name) == 0) {
+ /*
+ * Move to the front of the list for
+ * value_parser() to find it.
+ */
+
+ /* First save current entry. */
+ struct tiniparser_section *curr_section = *pp_section;
+
+ /* Now unlink current entry from list. */
+ *pp_section = curr_section->next_section;
+
+ /* Make current entry next point to whole list. */
+ curr_section->next_section = d->section_list;
+
+ /* And replace list with current entry at start. */
+ d->section_list = curr_section;
+
+ return true;
+ }
+ }
+
+ section_name_len = strlen(section_name) + 1;
+
+ /* Create new section. */
+ new_section = malloc(
+ offsetof(struct tiniparser_section, section_name) +
+ section_name_len);
+ if (new_section == NULL) {
+ return false;
+ }
+
+ memcpy(new_section->section_name, section_name, section_name_len);
+
+ new_section->entry_list = NULL;
+
+ /* Add it to the head of the singly linked list. */
+ new_section->next_section = d->section_list;
+ d->section_list = new_section;
+ return true;
+}
+
+struct tiniparser_dictionary *tiniparser_load_stream(FILE *fp)
+{
+ bool ret;
+ struct tiniparser_dictionary *d = NULL;
+
+ d = malloc(sizeof(struct tiniparser_dictionary));
+ if (d == NULL) {
+ return NULL;
+ }
+ d->section_list = NULL;
+
+ ret = tini_parse(fp,
+ false,
+ section_parser,
+ value_parser,
+ d);
+ if (ret == false) {
+ tiniparser_freedict(d);
+ d = NULL;
+ }
+ return d;
+}
+
+struct tiniparser_dictionary *tiniparser_load(const char *filename)
+{
+ struct tiniparser_dictionary *d;
+ FILE *fp = fopen(filename, "r");
+
+ if (fp == NULL) {
+ return NULL;
+ }
+
+ d = tiniparser_load_stream(fp);
+
+ fclose(fp);
+
+ return d;
+}
+
+void tiniparser_freedict(struct tiniparser_dictionary *d)
+{
+ struct tiniparser_section *curr_section, *next_section;
+
+ if (d == NULL) {
+ return;
+ }
+
+ for (curr_section = d->section_list;
+ curr_section;
+ curr_section = next_section) {
+ struct tiniparser_entry *curr_entry, *next_entry;
+
+ next_section = curr_section->next_section;
+
+ for (curr_entry = curr_section->entry_list;
+ curr_entry;
+ curr_entry = next_entry) {
+ next_entry = curr_entry->next_entry;
+
+ free(curr_entry->key);
+ free(curr_entry->value);
+ free(curr_entry);
+ }
+ free(curr_section);
+ }
+ free(d);
+}
diff --git a/lib/util/tiniparser.h b/lib/util/tiniparser.h
new file mode 100644
index 0000000..5356b22
--- /dev/null
+++ b/lib/util/tiniparser.h
@@ -0,0 +1,56 @@
+#ifndef _TINIPARSER_H_
+#define _TINIPARSER_H_
+/*
+ * Trivial smb.conf parsing code
+ * iniparser compatibility layer.
+ *
+ * Copyright Jeremy Allison <jra@samba.org> 2014
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+struct tiniparser_dictionary;
+
+bool tiniparser_getboolean(struct tiniparser_dictionary *d,
+ const char *key,
+ bool default_value);
+const char *tiniparser_getstring(struct tiniparser_dictionary *d,
+ const char *key,
+ const char *default_value);
+int tiniparser_getint(struct tiniparser_dictionary *d,
+ const char *key,
+ int default_value);
+struct tiniparser_dictionary *tiniparser_load_stream(FILE *fp);
+struct tiniparser_dictionary *tiniparser_load(const char *filename);
+void tiniparser_freedict(struct tiniparser_dictionary *d);
+
+#endif
diff --git a/lib/util/tsort.h b/lib/util/tsort.h
new file mode 100644
index 0000000..811d6cd
--- /dev/null
+++ b/lib/util/tsort.h
@@ -0,0 +1,40 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ typesafe qsort
+
+ Copyright (C) Andrew Tridgell 2010
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _TSORT_H
+#define _TSORT_H
+#include <assert.h>
+
+/*
+ a wrapper around qsort() that ensures the comparison function is
+ type safe.
+ */
+#ifndef TYPESAFE_QSORT
+#define TYPESAFE_QSORT(base, numel, comparison) \
+do { \
+ if (numel > 1) { \
+ qsort(base, numel, sizeof((base)[0]), (int (*)(const void *, const void *))comparison); \
+ assert(comparison(&((base)[0]), &((base)[1])) <= 0); \
+ } \
+} while (0)
+#endif
+
+#endif
diff --git a/lib/util/unix_match.c b/lib/util/unix_match.c
new file mode 100644
index 0000000..38edc18
--- /dev/null
+++ b/lib/util/unix_match.c
@@ -0,0 +1,183 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Jeremy Allison 2001
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include <talloc.h>
+#include "lib/util/talloc_stack.h"
+#include "lib/util/charset/charset.h"
+#include "lib/util/unix_match.h"
+
+/*********************************************************
+ Recursive routine that is called by unix_wild_match.
+*********************************************************/
+
+static bool unix_do_match(const char *regexp, const char *str)
+{
+ const char *p;
+
+ for( p = regexp; *p && *str; ) {
+
+ switch(*p) {
+ case '?':
+ str++;
+ p++;
+ break;
+
+ case '*':
+
+ /*
+ * Look for a character matching
+ * the one after the '*'.
+ */
+ p++;
+ if(!*p) {
+ return true; /* Automatic match */
+ }
+ while(*str) {
+
+ while(*str && (*p != *str)) {
+ str++;
+ }
+
+ /*
+ * Patch from weidel@multichart.de.
+ * In the case of the regexp
+ * '*XX*' we want to ensure there are
+ * at least 2 'X' characters in the
+ * string after the '*' for a match to
+ * be made.
+ */
+
+ {
+ int matchcount=0;
+
+ /*
+ * Eat all the characters that
+ * match, but count how many
+ * there were.
+ */
+
+ while(*str && (*p == *str)) {
+ str++;
+ matchcount++;
+ }
+
+ /*
+ * Now check that if the regexp
+ * had n identical characters
+ * that matchcount had at least
+ * that many matches.
+ */
+
+ while (*(p+1) && (*(p+1)==*p)) {
+ p++;
+ matchcount--;
+ }
+
+ if ( matchcount <= 0 ) {
+ return false;
+ }
+ }
+
+ /*
+ * We've eaten the match char
+ * after the '*'
+ */
+ str--;
+
+ if(unix_do_match(p, str)) {
+ return true;
+ }
+
+ if(!*str) {
+ return false;
+ } else {
+ str++;
+ }
+ }
+ return false;
+
+ default:
+ if(*str != *p) {
+ return false;
+ }
+ str++;
+ p++;
+ break;
+ }
+ }
+
+ if(!*p && !*str) {
+ return true;
+ }
+
+ if (!*p && str[0] == '.' && str[1] == 0) {
+ return true;
+ }
+
+ if (!*str && *p == '?') {
+ while (*p == '?') {
+ p++;
+ }
+ return(!*p);
+ }
+
+ if(!*str && (*p == '*' && p[1] == '\0')) {
+ return true;
+ }
+
+ return false;
+}
+
+/*******************************************************************
+ Simple case insensitive interface to a UNIX wildcard matcher.
+ Returns True if match, False if not.
+*******************************************************************/
+
+bool unix_wild_match(const char *pattern, const char *string)
+{
+ TALLOC_CTX *ctx = talloc_stackframe();
+ char *p2;
+ char *s2;
+ char *p;
+ bool ret = false;
+
+ p2 = strlower_talloc(ctx, pattern);
+ s2 = strlower_talloc(ctx, string);
+ if (!p2 || !s2) {
+ TALLOC_FREE(ctx);
+ return false;
+ }
+
+ /* Remove any *? and ** from the pattern as they are meaningless */
+ for(p = p2; *p; p++) {
+ while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
+ memmove(&p[1], &p[2], strlen(&p[2])+1);
+ }
+ }
+
+ if (p2[0] == '*' && p2[1] == '\0') {
+ TALLOC_FREE(ctx);
+ return true;
+ }
+
+ ret = unix_do_match(p2, s2);
+ TALLOC_FREE(ctx);
+ return ret;
+}
diff --git a/lib/util/unix_match.h b/lib/util/unix_match.h
new file mode 100644
index 0000000..a7b6935
--- /dev/null
+++ b/lib/util/unix_match.h
@@ -0,0 +1,25 @@
+/*
+ Unix SMB/CIFS implementation.
+ Utility functions for Samba
+ Copyright (C) Jeremy Allison 2001
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _UNIX_MASK_H_
+#define _UNIX_MASK_H_
+
+bool unix_wild_match(const char *pattern, const char *string);
+
+#endif
diff --git a/lib/util/unix_privs.c b/lib/util/unix_privs.c
new file mode 100644
index 0000000..9f28432
--- /dev/null
+++ b/lib/util/unix_privs.c
@@ -0,0 +1,92 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ gain/lose root privileges
+
+ Copyright (C) Andrew Tridgell 2004
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include <talloc.h>
+#include "lib/util/fault.h"
+#include "system/passwd.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "../lib/util/unix_privs.h"
+#include "../lib/util/setid.h"
+
+/**
+ * @file
+ * @brief Gaining/losing root privileges
+ */
+
+/*
+ there are times when smbd needs to temporarily gain root privileges
+ to do some operation. To do this you call root_privileges(), which
+ returns a talloc handle. To restore your previous privileges
+ talloc_free() this pointer.
+
+ Note that this call is considered successful even if it does not
+ manage to gain root privileges, but it will call smb_abort() if it
+ fails to restore the privileges afterwards. The logic is that
+ failing to gain root access can be caught by whatever operation
+ needs to be run as root failing, but failing to lose the root
+ privileges is dangerous.
+
+ This also means that this code is safe to be called from completely
+ unprivileged processes.
+*/
+
+struct saved_state {
+ uid_t uid;
+};
+
+static int privileges_destructor(struct saved_state *s)
+{
+ if (geteuid() != s->uid &&
+ samba_seteuid(s->uid) != 0) {
+ smb_panic("Failed to restore privileges");
+ }
+ return 0;
+}
+
+/**
+ * Obtain root privileges for the current process.
+ *
+ * The privileges can be dropped by talloc_free()-ing the
+ * token returned by this function
+ */
+void *root_privileges(void)
+{
+ struct saved_state *s;
+ s = talloc(NULL, struct saved_state);
+ if (!s) return NULL;
+ s->uid = geteuid();
+ if (s->uid != 0) {
+ samba_seteuid(0);
+ }
+ talloc_set_destructor(s, privileges_destructor);
+ return s;
+}
+
+uid_t root_privileges_original_uid(void *s)
+{
+ struct saved_state *saved = talloc_get_type_abort(s, struct saved_state);
+ return saved->uid;
+}
diff --git a/lib/util/util.c b/lib/util/util.c
new file mode 100644
index 0000000..5f9310e
--- /dev/null
+++ b/lib/util/util.c
@@ -0,0 +1,1335 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 2001-2002
+ Copyright (C) Simo Sorce 2001-2011
+ Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
+ Copyright (C) James J Myers 2003
+ Copyright (C) Volker Lendecke 2010
+ Copyright (C) Swen Schillig 2019
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include <talloc.h>
+#include <tevent.h>
+#include "system/network.h"
+#include "system/filesys.h"
+#include "system/locale.h"
+#include "system/shmem.h"
+#include "system/passwd.h"
+#include "system/time.h"
+#include "system/wait.h"
+#include "debug.h"
+#include "samba_util.h"
+#include "lib/util/select.h"
+#include <libgen.h>
+#include <gnutls/gnutls.h>
+
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
+
+#undef malloc
+#undef strcasecmp
+#undef strncasecmp
+#undef strdup
+#undef realloc
+#undef calloc
+
+/**
+ * @file
+ * @brief Misc utility functions
+ */
+
+/**
+ Find a suitable temporary directory. The result should be copied immediately
+ as it may be overwritten by a subsequent call.
+**/
+_PUBLIC_ const char *tmpdir(void)
+{
+ char *p;
+ if ((p = getenv("TMPDIR")))
+ return p;
+ return "/tmp";
+}
+
+
+/**
+ Create a tmp file, open it and immediately unlink it.
+ If dir is NULL uses tmpdir()
+ Returns the file descriptor or -1 on error.
+**/
+int create_unlink_tmp(const char *dir)
+{
+ size_t len = strlen(dir ? dir : (dir = tmpdir()));
+ char fname[len+25];
+ int fd;
+ mode_t mask;
+
+ len = snprintf(fname, sizeof(fname), "%s/listenerlock_XXXXXX", dir);
+ if (len >= sizeof(fname)) {
+ errno = ENOMEM;
+ return -1;
+ }
+ mask = umask(S_IRWXO | S_IRWXG);
+ fd = mkstemp(fname);
+ umask(mask);
+ if (fd == -1) {
+ return -1;
+ }
+ if (unlink(fname) == -1) {
+ int sys_errno = errno;
+ close(fd);
+ errno = sys_errno;
+ return -1;
+ }
+ return fd;
+}
+
+
+/**
+ Check if a file exists - call vfs_file_exist for samba files.
+**/
+_PUBLIC_ bool file_exist(const char *fname)
+{
+ struct stat st;
+
+ if (stat(fname, &st) != 0) {
+ return false;
+ }
+
+ return ((S_ISREG(st.st_mode)) || (S_ISFIFO(st.st_mode)));
+}
+
+/**
+ * @brief Return a files modification time.
+ *
+ * @param fname The name of the file.
+ *
+ * @param mt A pointer to store the modification time.
+ *
+ * @return 0 on success, errno otherwise.
+ */
+_PUBLIC_ int file_modtime(const char *fname, struct timespec *mt)
+{
+ struct stat st = {0};
+
+ if (stat(fname, &st) != 0) {
+ return errno;
+ }
+
+ *mt = get_mtimespec(&st);
+ return 0;
+}
+
+/**
+ Check file permissions.
+**/
+
+_PUBLIC_ bool file_check_permissions(const char *fname,
+ uid_t uid,
+ mode_t file_perms,
+ struct stat *pst)
+{
+ int ret;
+ struct stat st;
+
+ if (pst == NULL) {
+ pst = &st;
+ }
+
+ ZERO_STRUCTP(pst);
+
+ ret = stat(fname, pst);
+ if (ret != 0) {
+ DEBUG(0, ("stat failed on file '%s': %s\n",
+ fname, strerror(errno)));
+ return false;
+ }
+
+ if (pst->st_uid != uid && !uid_wrapper_enabled()) {
+ DEBUG(0, ("invalid ownership of file '%s': "
+ "owned by uid %u, should be %u\n",
+ fname, (unsigned int)pst->st_uid,
+ (unsigned int)uid));
+ return false;
+ }
+
+ if ((pst->st_mode & 0777) != file_perms) {
+ DEBUG(0, ("invalid permissions on file "
+ "'%s': has 0%o should be 0%o\n", fname,
+ (unsigned int)(pst->st_mode & 0777),
+ (unsigned int)file_perms));
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ Check if a directory exists.
+**/
+
+_PUBLIC_ bool directory_exist(const char *dname)
+{
+ struct stat st;
+ bool ret;
+
+ if (stat(dname,&st) != 0) {
+ return false;
+ }
+
+ ret = S_ISDIR(st.st_mode);
+ if(!ret)
+ errno = ENOTDIR;
+ return ret;
+}
+
+/**
+ * Try to create the specified directory if it didn't exist.
+ * A symlink to a directory is also accepted as a valid existing directory.
+ *
+ * @retval true if the directory already existed
+ * or was successfully created.
+ */
+_PUBLIC_ bool directory_create_or_exist(const char *dname,
+ mode_t dir_perms)
+{
+ int ret;
+ mode_t old_umask;
+
+ /* Create directory */
+ old_umask = umask(0);
+ ret = mkdir(dname, dir_perms);
+ if (ret == -1 && errno != EEXIST) {
+ int dbg_level = geteuid() == 0 ? DBGLVL_ERR : DBGLVL_NOTICE;
+
+ DBG_PREFIX(dbg_level,
+ ("mkdir failed on directory %s: %s\n",
+ dname,
+ strerror(errno)));
+ umask(old_umask);
+ return false;
+ }
+ umask(old_umask);
+
+ if (ret != 0 && errno == EEXIST) {
+ struct stat sbuf;
+
+ ret = lstat(dname, &sbuf);
+ if (ret != 0) {
+ return false;
+ }
+
+ if (S_ISDIR(sbuf.st_mode)) {
+ return true;
+ }
+
+ if (S_ISLNK(sbuf.st_mode)) {
+ ret = stat(dname, &sbuf);
+ if (ret != 0) {
+ return false;
+ }
+
+ if (S_ISDIR(sbuf.st_mode)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ return true;
+}
+
+_PUBLIC_ bool directory_create_or_exists_recursive(
+ const char *dname,
+ mode_t dir_perms)
+{
+ bool ok;
+
+ ok = directory_create_or_exist(dname, dir_perms);
+ if (!ok) {
+ if (!directory_exist(dname)) {
+ char tmp[PATH_MAX] = {0};
+ char *parent = NULL;
+ size_t n;
+
+ /* Use the null context */
+ n = strlcpy(tmp, dname, sizeof(tmp));
+ if (n < strlen(dname)) {
+ DBG_ERR("Path too long!\n");
+ return false;
+ }
+
+ parent = dirname(tmp);
+ if (parent == NULL) {
+ DBG_ERR("Failed to create dirname!\n");
+ return false;
+ }
+
+ ok = directory_create_or_exists_recursive(parent,
+ dir_perms);
+ if (!ok) {
+ return false;
+ }
+
+ ok = directory_create_or_exist(dname, dir_perms);
+ }
+ }
+
+ return ok;
+}
+
+/**
+ * @brief Try to create a specified directory if it doesn't exist.
+ *
+ * The function creates a directory with the given uid and permissions if it
+ * doesn't exist. If it exists it makes sure the uid and permissions are
+ * correct and it will fail if they are different.
+ *
+ * @param[in] dname The directory to create.
+ *
+ * @param[in] uid The uid the directory needs to belong too.
+ *
+ * @param[in] dir_perms The expected permissions of the directory.
+ *
+ * @return True on success, false on error.
+ */
+_PUBLIC_ bool directory_create_or_exist_strict(const char *dname,
+ uid_t uid,
+ mode_t dir_perms)
+{
+ struct stat st;
+ bool ok;
+ int rc;
+
+ ok = directory_create_or_exist(dname, dir_perms);
+ if (!ok) {
+ return false;
+ }
+
+ rc = lstat(dname, &st);
+ if (rc == -1) {
+ DEBUG(0, ("lstat failed on created directory %s: %s\n",
+ dname, strerror(errno)));
+ return false;
+ }
+
+ /* Check ownership and permission on existing directory */
+ if (!S_ISDIR(st.st_mode)) {
+ DEBUG(0, ("directory %s isn't a directory\n",
+ dname));
+ return false;
+ }
+ if (st.st_uid != uid && !uid_wrapper_enabled()) {
+ DBG_NOTICE("invalid ownership on directory "
+ "%s\n", dname);
+ return false;
+ }
+ if ((st.st_mode & 0777) != dir_perms) {
+ DEBUG(0, ("invalid permissions on directory "
+ "'%s': has 0%o should be 0%o\n", dname,
+ (unsigned int)(st.st_mode & 0777), (unsigned int)dir_perms));
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ Sleep for a specified number of milliseconds.
+**/
+
+_PUBLIC_ void smb_msleep(unsigned int t)
+{
+ sys_poll_intr(NULL, 0, t);
+}
+
+/**
+ Get my own name, return in talloc'ed storage.
+**/
+
+_PUBLIC_ char *get_myname(TALLOC_CTX *ctx)
+{
+ char *p;
+ char hostname[HOST_NAME_MAX];
+
+ /* get my host name */
+ if (gethostname(hostname, sizeof(hostname)) == -1) {
+ DEBUG(0,("gethostname failed\n"));
+ return NULL;
+ }
+
+ /* Ensure null termination. */
+ hostname[sizeof(hostname)-1] = '\0';
+
+ /* split off any parts after an initial . */
+ p = strchr_m(hostname, '.');
+ if (p) {
+ *p = 0;
+ }
+
+ return talloc_strdup(ctx, hostname);
+}
+
+/**
+ Check if a process exists. Does this work on all unixes?
+**/
+
+_PUBLIC_ bool process_exists_by_pid(pid_t pid)
+{
+ /* Doing kill with a non-positive pid causes messages to be
+ * sent to places we don't want. */
+ if (pid <= 0) {
+ return false;
+ }
+ return(kill(pid,0) == 0 || errno != ESRCH);
+}
+
+/**
+ Simple routine to do POSIX file locking. Cruft in NFS and 64->32 bit mapping
+ is dealt with in posix.c
+**/
+
+_PUBLIC_ bool fcntl_lock(int fd, int op, off_t offset, off_t count, int type)
+{
+ struct flock lock;
+ int ret;
+
+ DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
+
+ lock.l_type = type;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = offset;
+ lock.l_len = count;
+ lock.l_pid = 0;
+
+ ret = fcntl(fd,op,&lock);
+
+ if (ret == -1 && errno != 0)
+ DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
+
+ /* a lock query */
+ if (op == F_GETLK) {
+ if ((ret != -1) &&
+ (lock.l_type != F_UNLCK) &&
+ (lock.l_pid != 0) &&
+ (lock.l_pid != tevent_cached_getpid())) {
+ DEBUG(3,("fcntl_lock: fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
+ return true;
+ }
+
+ /* it must be not locked or locked by me */
+ return false;
+ }
+
+ /* a lock set or unset */
+ if (ret == -1) {
+ DEBUG(3,("fcntl_lock: lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
+ (double)offset,(double)count,op,type,strerror(errno)));
+ return false;
+ }
+
+ /* everything went OK */
+ DEBUG(8,("fcntl_lock: Lock call successful\n"));
+
+ return true;
+}
+
+struct debug_channel_level {
+ int channel;
+ int level;
+};
+
+static void debugadd_channel_cb(const char *buf, void *private_data)
+{
+ struct debug_channel_level *dcl =
+ (struct debug_channel_level *)private_data;
+
+ DEBUGADDC(dcl->channel, dcl->level,("%s", buf));
+}
+
+static void debugadd_cb(const char *buf, void *private_data)
+{
+ int *plevel = (int *)private_data;
+ DEBUGADD(*plevel, ("%s", buf));
+}
+
+void print_asc_cb(const uint8_t *buf, int len,
+ void (*cb)(const char *buf, void *private_data),
+ void *private_data)
+{
+ int i;
+ char s[2];
+ s[1] = 0;
+
+ for (i=0; i<len; i++) {
+ s[0] = isprint(buf[i]) ? buf[i] : '.';
+ cb(s, private_data);
+ }
+}
+
+void print_asc(int level, const uint8_t *buf,int len)
+{
+ print_asc_cb(buf, len, debugadd_cb, &level);
+}
+
+static void dump_data_block16(const char *prefix, size_t idx,
+ const uint8_t *buf, size_t len,
+ void (*cb)(const char *buf, void *private_data),
+ void *private_data)
+{
+ char tmp[16];
+ size_t i;
+
+ SMB_ASSERT(len <= 16);
+
+ snprintf(tmp, sizeof(tmp), "%s[%04zX]", prefix, idx);
+ cb(tmp, private_data);
+
+ for (i=0; i<16; i++) {
+ if (i == 8) {
+ cb(" ", private_data);
+ }
+ if (i < len) {
+ snprintf(tmp, sizeof(tmp), " %02X", (int)buf[i]);
+ } else {
+ snprintf(tmp, sizeof(tmp), " ");
+ }
+ cb(tmp, private_data);
+ }
+
+ cb(" ", private_data);
+
+ if (len == 0) {
+ cb("EMPTY BLOCK\n", private_data);
+ return;
+ }
+
+ for (i=0; i<len; i++) {
+ if (i == 8) {
+ cb(" ", private_data);
+ }
+ print_asc_cb(&buf[i], 1, cb, private_data);
+ }
+
+ cb("\n", private_data);
+}
+
+/**
+ * Write dump of binary data to a callback
+ */
+void dump_data_cb(const uint8_t *buf, int len,
+ bool omit_zero_bytes,
+ void (*cb)(const char *buf, void *private_data),
+ void *private_data)
+{
+ int i=0;
+ bool skipped = false;
+
+ if (len<=0) return;
+
+ for (i=0;i<len;i+=16) {
+ size_t remaining_len = len - i;
+ size_t this_len = MIN(remaining_len, 16);
+ const uint8_t *this_buf = &buf[i];
+
+ if ((omit_zero_bytes == true) &&
+ (i > 0) && (remaining_len > 16) &&
+ (this_len == 16) && all_zero(this_buf, 16))
+ {
+ if (!skipped) {
+ cb("skipping zero buffer bytes\n",
+ private_data);
+ skipped = true;
+ }
+ continue;
+ }
+
+ skipped = false;
+ dump_data_block16("", i, this_buf, this_len,
+ cb, private_data);
+ }
+}
+
+/**
+ * Write dump of binary data to the log file.
+ *
+ * The data is only written if the log level is at least level.
+ */
+_PUBLIC_ void dump_data(int level, const uint8_t *buf, int len)
+{
+ if (!DEBUGLVL(level)) {
+ return;
+ }
+ dump_data_cb(buf, len, false, debugadd_cb, &level);
+}
+
+/**
+ * Write dump of binary data to the log file.
+ *
+ * The data is only written if the log level is at least level for
+ * debug class dbgc_class.
+ */
+_PUBLIC_ void dump_data_dbgc(int dbgc_class, int level, const uint8_t *buf, int len)
+{
+ struct debug_channel_level dcl = { dbgc_class, level };
+
+ if (!DEBUGLVLC(dbgc_class, level)) {
+ return;
+ }
+ dump_data_cb(buf, len, false, debugadd_channel_cb, &dcl);
+}
+
+/**
+ * Write dump of binary data to the log file.
+ *
+ * The data is only written if the log level is at least level.
+ * 16 zero bytes in a row are omitted
+ */
+_PUBLIC_ void dump_data_skip_zeros(int level, const uint8_t *buf, int len)
+{
+ if (!DEBUGLVL(level)) {
+ return;
+ }
+ dump_data_cb(buf, len, true, debugadd_cb, &level);
+}
+
+static void fprintf_cb(const char *buf, void *private_data)
+{
+ FILE *f = (FILE *)private_data;
+ fprintf(f, "%s", buf);
+}
+
+void dump_data_file(const uint8_t *buf, int len, bool omit_zero_bytes,
+ FILE *f)
+{
+ dump_data_cb(buf, len, omit_zero_bytes, fprintf_cb, f);
+}
+
+/**
+ * Write dump of compared binary data to a callback
+ */
+void dump_data_diff_cb(const uint8_t *buf1, size_t len1,
+ const uint8_t *buf2, size_t len2,
+ bool omit_zero_bytes,
+ void (*cb)(const char *buf, void *private_data),
+ void *private_data)
+{
+ size_t len = MAX(len1, len2);
+ size_t i;
+ bool skipped = false;
+
+ for (i=0; i<len; i+=16) {
+ size_t remaining_len = len - i;
+ size_t remaining_len1 = 0;
+ size_t this_len1 = 0;
+ const uint8_t *this_buf1 = NULL;
+ size_t remaining_len2 = 0;
+ size_t this_len2 = 0;
+ const uint8_t *this_buf2 = NULL;
+
+ if (i < len1) {
+ remaining_len1 = len1 - i;
+ this_len1 = MIN(remaining_len1, 16);
+ this_buf1 = &buf1[i];
+ }
+ if (i < len2) {
+ remaining_len2 = len2 - i;
+ this_len2 = MIN(remaining_len2, 16);
+ this_buf2 = &buf2[i];
+ }
+
+ if ((omit_zero_bytes == true) &&
+ (i > 0) && (remaining_len > 16) &&
+ (this_len1 == 16) && all_zero(this_buf1, 16) &&
+ (this_len2 == 16) && all_zero(this_buf2, 16))
+ {
+ if (!skipped) {
+ cb("skipping zero buffer bytes\n",
+ private_data);
+ skipped = true;
+ }
+ continue;
+ }
+
+ skipped = false;
+
+ if ((this_len1 == this_len2) &&
+ (memcmp(this_buf1, this_buf2, this_len1) == 0))
+ {
+ dump_data_block16(" ", i, this_buf1, this_len1,
+ cb, private_data);
+ continue;
+ }
+
+ dump_data_block16("-", i, this_buf1, this_len1,
+ cb, private_data);
+ dump_data_block16("+", i, this_buf2, this_len2,
+ cb, private_data);
+ }
+}
+
+_PUBLIC_ void dump_data_diff(int dbgc_class, int level,
+ bool omit_zero_bytes,
+ const uint8_t *buf1, size_t len1,
+ const uint8_t *buf2, size_t len2)
+{
+ struct debug_channel_level dcl = { dbgc_class, level };
+
+ if (!DEBUGLVLC(dbgc_class, level)) {
+ return;
+ }
+ dump_data_diff_cb(buf1, len1, buf2, len2, true, debugadd_channel_cb, &dcl);
+}
+
+_PUBLIC_ void dump_data_file_diff(FILE *f,
+ bool omit_zero_bytes,
+ const uint8_t *buf1, size_t len1,
+ const uint8_t *buf2, size_t len2)
+{
+ dump_data_diff_cb(buf1, len1, buf2, len2, omit_zero_bytes, fprintf_cb, f);
+}
+
+/**
+ malloc that aborts with smb_panic on fail or zero size.
+**/
+
+_PUBLIC_ void *smb_xmalloc(size_t size)
+{
+ void *p;
+ if (size == 0)
+ smb_panic("smb_xmalloc: called with zero size.\n");
+ if ((p = malloc(size)) == NULL)
+ smb_panic("smb_xmalloc: malloc fail.\n");
+ return p;
+}
+
+/**
+ Memdup with smb_panic on fail.
+**/
+
+_PUBLIC_ void *smb_xmemdup(const void *p, size_t size)
+{
+ void *p2;
+ p2 = smb_xmalloc(size);
+ memcpy(p2, p, size);
+ return p2;
+}
+
+/**
+ strdup that aborts on malloc fail.
+**/
+
+char *smb_xstrdup(const char *s)
+{
+#if defined(PARANOID_MALLOC_CHECKER)
+#ifdef strdup
+#undef strdup
+#endif
+#endif
+
+#ifndef HAVE_STRDUP
+#define strdup rep_strdup
+#endif
+
+ char *s1 = strdup(s);
+#if defined(PARANOID_MALLOC_CHECKER)
+#ifdef strdup
+#undef strdup
+#endif
+#define strdup(s) __ERROR_DONT_USE_STRDUP_DIRECTLY
+#endif
+ if (!s1) {
+ smb_panic("smb_xstrdup: malloc failed");
+ }
+ return s1;
+
+}
+
+/**
+ strndup that aborts on malloc fail.
+**/
+
+char *smb_xstrndup(const char *s, size_t n)
+{
+#if defined(PARANOID_MALLOC_CHECKER)
+#ifdef strndup
+#undef strndup
+#endif
+#endif
+
+#if (defined(BROKEN_STRNDUP) || !defined(HAVE_STRNDUP))
+#undef HAVE_STRNDUP
+#define strndup rep_strndup
+#endif
+
+ char *s1 = strndup(s, n);
+#if defined(PARANOID_MALLOC_CHECKER)
+#ifdef strndup
+#undef strndup
+#endif
+#define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
+#endif
+ if (!s1) {
+ smb_panic("smb_xstrndup: malloc failed");
+ }
+ return s1;
+}
+
+
+
+/**
+ Like strdup but for memory.
+**/
+
+_PUBLIC_ void *smb_memdup(const void *p, size_t size)
+{
+ void *p2;
+ if (size == 0)
+ return NULL;
+ p2 = malloc(size);
+ if (!p2)
+ return NULL;
+ memcpy(p2, p, size);
+ return p2;
+}
+
+/**
+ * Write a password to the log file.
+ *
+ * @note Only actually does something if DEBUG_PASSWORD was defined during
+ * compile-time.
+ */
+_PUBLIC_ void dump_data_pw(const char *msg, const uint8_t * data, size_t len)
+{
+#ifdef DEBUG_PASSWORD
+ DEBUG(11, ("%s", msg));
+ if (data != NULL && len > 0)
+ {
+ dump_data(11, data, len);
+ }
+#endif
+}
+
+static void dump_data_addbuf_cb(const char *buf, void *private_data)
+{
+ char **str = private_data;
+ talloc_asprintf_addbuf(str, "%s", buf);
+}
+
+_PUBLIC_ void dump_data_addbuf(const uint8_t *buf, size_t buflen, char **str)
+{
+ dump_data_cb(buf, buflen, false, dump_data_addbuf_cb, str);
+}
+
+
+/**
+ * see if a range of memory is all zero. A NULL pointer is considered
+ * to be all zero
+ */
+_PUBLIC_ bool all_zero(const uint8_t *ptr, size_t size)
+{
+ size_t i;
+ if (!ptr) return true;
+ for (i=0;i<size;i++) {
+ if (ptr[i]) return false;
+ }
+ return true;
+}
+
+/**
+ realloc an array, checking for integer overflow in the array size
+*/
+_PUBLIC_ void *realloc_array(void *ptr, size_t el_size, unsigned count, bool free_on_fail)
+{
+#define MAX_MALLOC_SIZE 0x7fffffff
+ if (count == 0 ||
+ count >= MAX_MALLOC_SIZE/el_size) {
+ if (free_on_fail)
+ SAFE_FREE(ptr);
+ return NULL;
+ }
+ if (!ptr) {
+ return malloc(el_size * count);
+ }
+ return realloc(ptr, el_size * count);
+}
+
+/****************************************************************************
+ Type-safe malloc.
+****************************************************************************/
+
+void *malloc_array(size_t el_size, unsigned int count)
+{
+ return realloc_array(NULL, el_size, count, false);
+}
+
+/****************************************************************************
+ Type-safe memalign
+****************************************************************************/
+
+void *memalign_array(size_t el_size, size_t align, unsigned int count)
+{
+ if (el_size == 0 || count >= MAX_MALLOC_SIZE/el_size) {
+ return NULL;
+ }
+
+ return memalign(align, el_size*count);
+}
+
+/****************************************************************************
+ Type-safe calloc.
+****************************************************************************/
+
+void *calloc_array(size_t size, size_t nmemb)
+{
+ if (nmemb >= MAX_MALLOC_SIZE/size) {
+ return NULL;
+ }
+ if (size == 0 || nmemb == 0) {
+ return NULL;
+ }
+ return calloc(nmemb, size);
+}
+
+/**
+ Trim the specified elements off the front and back of a string.
+**/
+_PUBLIC_ bool trim_string(char *s, const char *front, const char *back)
+{
+ bool ret = false;
+ size_t front_len;
+ size_t back_len;
+ size_t len;
+
+ /* Ignore null or empty strings. */
+ if (!s || (s[0] == '\0')) {
+ return false;
+ }
+ len = strlen(s);
+
+ front_len = front? strlen(front) : 0;
+ back_len = back? strlen(back) : 0;
+
+ if (front_len) {
+ size_t front_trim = 0;
+
+ while (strncmp(s+front_trim, front, front_len)==0) {
+ front_trim += front_len;
+ }
+ if (front_trim > 0) {
+ /* Must use memmove here as src & dest can
+ * easily overlap. Found by valgrind. JRA. */
+ memmove(s, s+front_trim, (len-front_trim)+1);
+ len -= front_trim;
+ ret=true;
+ }
+ }
+
+ if (back_len) {
+ while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
+ s[len-back_len]='\0';
+ len -= back_len;
+ ret=true;
+ }
+ }
+ return ret;
+}
+
+/**
+ Find the number of 'c' chars in a string
+**/
+_PUBLIC_ _PURE_ size_t count_chars(const char *s, char c)
+{
+ size_t count = 0;
+
+ while (*s) {
+ if (*s == c) count++;
+ s ++;
+ }
+
+ return count;
+}
+
+/**
+ * Routine to get hex characters and turn them into a byte array.
+ * the array can be variable length.
+ * - "0xnn" or "0Xnn" is specially catered for.
+ * - The first non-hex-digit character (apart from possibly leading "0x"
+ * finishes the conversion and skips the rest of the input.
+ * - A single hex-digit character at the end of the string is skipped.
+ *
+ * valid examples: "0A5D15"; "0x123456"
+ */
+_PUBLIC_ size_t strhex_to_str(char *p, size_t p_len, const char *strhex, size_t strhex_len)
+{
+ size_t i = 0;
+ size_t num_chars = 0;
+
+ /* skip leading 0x prefix */
+ if (strncasecmp(strhex, "0x", 2) == 0) {
+ i += 2; /* skip two chars */
+ }
+
+ while ((i < strhex_len) && (num_chars < p_len)) {
+ bool ok = hex_byte(&strhex[i], (uint8_t *)&p[num_chars]);
+ if (!ok) {
+ break;
+ }
+ i += 2;
+ num_chars += 1;
+ }
+
+ return num_chars;
+}
+
+/**
+ * Parse a hex string and return a data blob.
+ */
+_PUBLIC_ DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex)
+{
+ DATA_BLOB ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
+ if (ret_blob.data == NULL) {
+ /* ret_blob.length is already 0 */
+ return ret_blob;
+ }
+ ret_blob.length = strhex_to_str((char *)ret_blob.data, ret_blob.length,
+ strhex,
+ strlen(strhex));
+
+ return ret_blob;
+}
+
+/**
+ * Parse a hex dump and return a data blob. Hex dump is structured as
+ * is generated from dump_data_cb() elsewhere in this file
+ *
+ */
+_PUBLIC_ DATA_BLOB hexdump_to_data_blob(TALLOC_CTX *mem_ctx, const char *hexdump, size_t hexdump_len)
+{
+ DATA_BLOB ret_blob = { 0 };
+ size_t i = 0;
+ size_t char_count = 0;
+ /* hexdump line length is 77 chars long. We then use the ASCII representation of the bytes
+ * at the end of the final line to calculate how many are in that line, minus the extra space
+ * and newline. */
+ size_t hexdump_byte_count = (16 * (hexdump_len / 77));
+ if (hexdump_len % 77) {
+ hexdump_byte_count += ((hexdump_len % 77) - 59 - 2);
+ }
+
+ ret_blob = data_blob_talloc(mem_ctx, NULL, hexdump_byte_count+1);
+ for (; i+1 < hexdump_len && hexdump[i] != 0 && hexdump[i+1] != 0; i++) {
+ if ((i%77) == 0)
+ i += 7; /* Skip the offset at the start of the line */
+ if ((i%77) < 56) { /* position 56 is after both hex chunks */
+ if (hexdump[i] != ' ') {
+ char_count += strhex_to_str((char *)&ret_blob.data[char_count],
+ hexdump_byte_count - char_count,
+ &hexdump[i], 2);
+ i += 2;
+ } else {
+ i++;
+ }
+ } else {
+ i++;
+ }
+ }
+ ret_blob.length = char_count;
+
+ return ret_blob;
+}
+
+/**
+ * Print a buf in hex. Assumes dst is at least (srclen*2)+1 large.
+ */
+_PUBLIC_ void hex_encode_buf(char *dst, const uint8_t *src, size_t srclen)
+{
+ size_t i;
+ for (i=0; i<srclen; i++) {
+ snprintf(dst + i*2, 3, "%02X", src[i]);
+ }
+ /*
+ * Ensure 0-termination for 0-length buffers
+ */
+ dst[srclen*2] = '\0';
+}
+
+/**
+ * talloc version of hex_encode_buf()
+ */
+_PUBLIC_ char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
+{
+ char *hex_buffer;
+
+ hex_buffer = talloc_array(mem_ctx, char, (len*2)+1);
+ if (!hex_buffer) {
+ return NULL;
+ }
+ hex_encode_buf(hex_buffer, buff_in, len);
+ talloc_set_name_const(hex_buffer, hex_buffer);
+ return hex_buffer;
+}
+
+/**
+ variant of strcmp() that handles NULL ptrs
+**/
+_PUBLIC_ int strcmp_safe(const char *s1, const char *s2)
+{
+ if (s1 == s2) {
+ return 0;
+ }
+ if (s1 == NULL || s2 == NULL) {
+ return s1?-1:1;
+ }
+ return strcmp(s1, s2);
+}
+
+
+/**
+return the number of bytes occupied by a buffer in ASCII format
+the result includes the null termination
+limited by 'n' bytes
+**/
+_PUBLIC_ size_t ascii_len_n(const char *src, size_t n)
+{
+ size_t len;
+
+ len = strnlen(src, n);
+ if (len+1 <= n) {
+ len += 1;
+ }
+
+ return len;
+}
+
+_PUBLIC_ bool mem_equal_const_time(const void *s1, const void *s2, size_t n)
+{
+ /* Ensure we won't overflow the unsigned index used by gnutls. */
+ SMB_ASSERT(n <= UINT_MAX);
+
+ return gnutls_memcmp(s1, s2, n) == 0;
+}
+
+struct anonymous_shared_header {
+ union {
+ size_t length;
+ uint8_t pad[16];
+ } u;
+};
+
+/* Map a shared memory buffer of at least nelem counters. */
+void *anonymous_shared_allocate(size_t orig_bufsz)
+{
+ void *ptr;
+ void *buf;
+ size_t pagesz = getpagesize();
+ size_t pagecnt;
+ size_t bufsz = orig_bufsz;
+ struct anonymous_shared_header *hdr;
+
+ bufsz += sizeof(*hdr);
+
+ /* round up to full pages */
+ pagecnt = bufsz / pagesz;
+ if (bufsz % pagesz) {
+ pagecnt += 1;
+ }
+ bufsz = pagesz * pagecnt;
+
+ if (orig_bufsz >= bufsz) {
+ /* integer wrap */
+ errno = ENOMEM;
+ return NULL;
+ }
+
+#ifdef MAP_ANON
+ /* BSD */
+ buf = mmap(NULL, bufsz, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED,
+ -1 /* fd */, 0 /* offset */);
+#else
+{
+ int saved_errno;
+ int fd;
+
+ fd = open("/dev/zero", O_RDWR);
+ if (fd == -1) {
+ return NULL;
+ }
+
+ buf = mmap(NULL, bufsz, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
+ fd, 0 /* offset */);
+ saved_errno = errno;
+ close(fd);
+ errno = saved_errno;
+}
+#endif
+
+ if (buf == MAP_FAILED) {
+ return NULL;
+ }
+
+ hdr = (struct anonymous_shared_header *)buf;
+ hdr->u.length = bufsz;
+
+ ptr = (void *)(&hdr[1]);
+
+ return ptr;
+}
+
+void *anonymous_shared_resize(void *ptr, size_t new_size, bool maymove)
+{
+#ifdef HAVE_MREMAP
+ void *buf;
+ size_t pagesz = getpagesize();
+ size_t pagecnt;
+ size_t bufsz;
+ struct anonymous_shared_header *hdr;
+ int flags = 0;
+
+ if (ptr == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ hdr = (struct anonymous_shared_header *)ptr;
+ hdr--;
+ if (hdr->u.length > (new_size + sizeof(*hdr))) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ bufsz = new_size + sizeof(*hdr);
+
+ /* round up to full pages */
+ pagecnt = bufsz / pagesz;
+ if (bufsz % pagesz) {
+ pagecnt += 1;
+ }
+ bufsz = pagesz * pagecnt;
+
+ if (new_size >= bufsz) {
+ /* integer wrap */
+ errno = ENOSPC;
+ return NULL;
+ }
+
+ if (bufsz <= hdr->u.length) {
+ return ptr;
+ }
+
+ if (maymove) {
+ flags = MREMAP_MAYMOVE;
+ }
+
+ buf = mremap(hdr, hdr->u.length, bufsz, flags);
+
+ if (buf == MAP_FAILED) {
+ errno = ENOSPC;
+ return NULL;
+ }
+
+ hdr = (struct anonymous_shared_header *)buf;
+ hdr->u.length = bufsz;
+
+ ptr = (void *)(&hdr[1]);
+
+ return ptr;
+#else
+ errno = ENOSPC;
+ return NULL;
+#endif
+}
+
+void anonymous_shared_free(void *ptr)
+{
+ struct anonymous_shared_header *hdr;
+
+ if (ptr == NULL) {
+ return;
+ }
+
+ hdr = (struct anonymous_shared_header *)ptr;
+
+ hdr--;
+
+ munmap(hdr, hdr->u.length);
+}
+
+#ifdef DEVELOPER
+/* used when you want a debugger started at a particular point in the
+ code. Mostly useful in code that runs as a child process, where
+ normal gdb attach is harder to organise.
+*/
+void samba_start_debugger(void)
+{
+ int ready_pipe[2];
+ char c;
+ int ret;
+ pid_t pid;
+
+ ret = pipe(ready_pipe);
+ SMB_ASSERT(ret == 0);
+
+ pid = fork();
+ SMB_ASSERT(pid >= 0);
+
+ if (pid) {
+ c = 0;
+
+ ret = close(ready_pipe[0]);
+ SMB_ASSERT(ret == 0);
+#if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
+ /*
+ * Make sure the child process can attach a debugger.
+ *
+ * We don't check the error code as the debugger
+ * will tell us if it can't attach.
+ */
+ (void)prctl(PR_SET_PTRACER, pid, 0, 0, 0);
+#endif
+ ret = write(ready_pipe[1], &c, 1);
+ SMB_ASSERT(ret == 1);
+
+ ret = close(ready_pipe[1]);
+ SMB_ASSERT(ret == 0);
+
+ /* Wait for gdb to attach. */
+ sleep(2);
+ } else {
+ char *cmd = NULL;
+
+ ret = close(ready_pipe[1]);
+ SMB_ASSERT(ret == 0);
+
+ ret = read(ready_pipe[0], &c, 1);
+ SMB_ASSERT(ret == 1);
+
+ ret = close(ready_pipe[0]);
+ SMB_ASSERT(ret == 0);
+
+ ret = asprintf(&cmd, "gdb --pid %u", getppid());
+ SMB_ASSERT(ret != -1);
+
+ execlp("xterm", "xterm", "-e", cmd, (char *) NULL);
+ smb_panic("execlp() failed");
+ }
+}
+#endif
diff --git a/lib/util/util.h b/lib/util/util.h
new file mode 100644
index 0000000..59d24a8
--- /dev/null
+++ b/lib/util/util.h
@@ -0,0 +1,94 @@
+/*
+ Unix SMB/CIFS implementation.
+ Utility functions for Samba
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Jelmer Vernooij 2005
+ Copyright (C) Swen Schillig 2019
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __UTIL_SAMBA_UTIL_H__
+#define __UTIL_SAMBA_UTIL_H__
+
+/**
+ * Write dump of binary data to a callback
+ */
+void dump_data_cb(const uint8_t *buf, int len,
+ bool omit_zero_bytes,
+ void (*cb)(const char *buf, void *private_data),
+ void *private_data);
+
+/**
+ * Write dump of binary data to a FILE
+ */
+void dump_data_file(const uint8_t *buf, int len, bool omit_zero_bytes,
+ FILE *f);
+
+/**
+ * Write dump of binary data to the log file.
+ *
+ * The data is only written if the log level is at least level.
+ */
+_PUBLIC_ void dump_data(int level, const uint8_t *buf,int len);
+
+/**
+ * Write dump of binary data to the log file.
+ *
+ * The data is only written if the log level is at least level for
+ * debug class dbgc_class.
+ */
+_PUBLIC_ void dump_data_dbgc(int dbgc_class, int level, const uint8_t *buf, int len);
+
+/**
+ * Write dump of compared binary data to a callback
+ */
+void dump_data_diff_cb(const uint8_t *buf1, size_t len1,
+ const uint8_t *buf2, size_t len2,
+ bool omit_zero_bytes,
+ void (*cb)(const char *buf, void *private_data),
+ void *private_data);
+
+/**
+ * Write dump of compared binary data to the log file.
+ *
+ * The data is only written if the log level is at least level for
+ * debug class dbgc_class.
+ */
+_PUBLIC_ void dump_data_diff(int dbgc_class, int level,
+ bool omit_zero_bytes,
+ const uint8_t *buf1, size_t len1,
+ const uint8_t *buf2, size_t len2);
+
+/**
+ * Write dump of compared binary data to the given file handle
+ */
+_PUBLIC_ void dump_data_file_diff(FILE *f,
+ bool omit_zero_bytes,
+ const uint8_t *buf1, size_t len1,
+ const uint8_t *buf2, size_t len2);
+
+/**
+ * Write a password to the log file.
+ *
+ * @note Only actually does something if DEBUG_PASSWORD was defined during
+ * compile-time.
+ */
+_PUBLIC_ void dump_data_pw(const char *msg, const uint8_t * data, size_t len);
+
+/**
+ * Dump data to "str" via talloc_asprintf_addbuf()
+ */
+_PUBLIC_ void dump_data_addbuf(const uint8_t *buf, size_t buflen, char **str);
+#endif
diff --git a/lib/util/util_file.c b/lib/util/util_file.c
new file mode 100644
index 0000000..0e54dff
--- /dev/null
+++ b/lib/util/util_file.c
@@ -0,0 +1,498 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
+ *
+ * Added afdgets() Jelmer Vernooij 2005
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "replace.h"
+#include "system/shmem.h"
+#include "system/filesys.h"
+#include <talloc.h>
+#include "lib/util/samba_util.h"
+#include "lib/util/sys_popen.h"
+#include "lib/util/sys_rw.h"
+#include "lib/util/debug.h"
+
+/**
+ * Read one line (data until next newline or eof) and allocate it
+ */
+_PUBLIC_ char *afdgets(int fd, TALLOC_CTX *mem_ctx, size_t hint)
+{
+ char *data = NULL;
+ ssize_t alloc_size = 0, offset = 0, ret;
+ int p;
+
+ if (hint <= 0) hint = 0x100;
+
+ do {
+ alloc_size += hint;
+
+ data = talloc_realloc(mem_ctx, data, char, alloc_size);
+
+ if (!data)
+ return NULL;
+
+ ret = read(fd, data + offset, hint);
+
+ if (ret == 0) {
+ return NULL;
+ }
+
+ if (ret == -1) {
+ talloc_free(data);
+ return NULL;
+ }
+
+ /* Find newline */
+ for (p = 0; p < ret; p++) {
+ if (data[offset + p] == '\n')
+ break;
+ }
+
+ if (p < ret) {
+ data[offset + p] = '\0';
+
+ /* Go back to position of newline */
+ lseek(fd, p - ret + 1, SEEK_CUR);
+ return data;
+ }
+
+ offset += ret;
+
+ } while ((size_t)ret == hint);
+
+ data[offset] = '\0';
+
+ return data;
+}
+
+char *fgets_slash(TALLOC_CTX *mem_ctx, char *s2, size_t maxlen, FILE *f)
+{
+ char *s = s2;
+ size_t len = 0;
+ int c;
+ bool start_of_line = true;
+
+ if (feof(f)) {
+ return NULL;
+ }
+
+ if (maxlen < 2) {
+ return NULL;
+ }
+
+ if (s2 == NULL) {
+ maxlen = MIN(maxlen,8);
+ s = talloc_array(mem_ctx, char, maxlen);
+ }
+
+ if (s == NULL) {
+ return NULL;
+ }
+
+ *s = 0;
+
+ while (len < maxlen-1) {
+ c = getc(f);
+ switch (c)
+ {
+ case '\r':
+ break;
+ case '\n':
+ while (len > 0 && s[len-1] == ' ') {
+ s[--len] = 0;
+ }
+ if (len > 0 && s[len-1] == '\\') {
+ s[--len] = 0;
+ start_of_line = true;
+ break;
+ }
+ return s;
+ case EOF:
+ if (len <= 0 && (s2 == NULL)) {
+ TALLOC_FREE(s);
+ }
+ return (len>0) ? s : NULL;
+ case ' ':
+ if (start_of_line) {
+ break;
+ }
+
+ FALL_THROUGH;
+ default:
+ start_of_line = false;
+ s[len++] = c;
+ s[len] = 0;
+ }
+ if ((s2 == NULL) && (len > maxlen-3)) {
+ size_t m;
+ char *t;
+
+ m = maxlen * 2;
+ if (m < maxlen) {
+ DBG_ERR("length overflow\n");
+ TALLOC_FREE(s);
+ return NULL;
+ }
+ maxlen = m;
+
+ t = talloc_realloc(mem_ctx, s, char, maxlen);
+ if (t == NULL) {
+ DBG_ERR("failed to expand buffer!\n");
+ TALLOC_FREE(s);
+ return NULL;
+ }
+
+ s = t;
+ }
+ }
+
+ return s;
+}
+
+/**
+load a file into memory from a fd.
+**/
+_PUBLIC_ char *fd_load(int fd, size_t *psize, size_t maxsize, TALLOC_CTX *mem_ctx)
+{
+ FILE *file;
+ char *p = NULL;
+ size_t size = 0;
+ size_t chunk = 1024;
+ int err;
+ int fd_dup;
+
+ if (maxsize == 0) {
+ maxsize = SIZE_MAX;
+ }
+
+ fd_dup = dup(fd);
+ if (fd_dup == -1) {
+ return NULL;
+ }
+
+ file = fdopen(fd_dup, "r");
+ if (file == NULL) {
+ close(fd_dup);
+ return NULL;
+ }
+
+ while (size < maxsize) {
+ size_t newbufsize;
+ size_t nread;
+
+ chunk = MIN(chunk, (maxsize - size));
+
+ newbufsize = size + (chunk+1); /* chunk+1 can't overflow */
+ if (newbufsize < size) {
+ goto fail; /* overflow */
+ }
+
+ p = talloc_realloc(mem_ctx, p, char, newbufsize);
+ if (p == NULL) {
+ goto fail;
+ }
+
+ nread = fread(p+size, 1, chunk, file);
+ size += nread;
+
+ if (nread != chunk) {
+ break;
+ }
+ }
+
+ err = ferror(file);
+ if (err != 0) {
+ goto fail;
+ }
+
+ p[size] = '\0';
+
+ if (psize != NULL) {
+ *psize = size;
+ }
+
+ fclose(file);
+ return p;
+
+fail:
+ TALLOC_FREE(p);
+ fclose(file);
+ return NULL;
+}
+
+/**
+load a file into memory
+**/
+_PUBLIC_ char *file_load(const char *fname, size_t *size, size_t maxsize, TALLOC_CTX *mem_ctx)
+{
+ int fd;
+ char *p;
+
+ if (!fname || !*fname) return NULL;
+
+ fd = open(fname,O_RDONLY);
+ if (fd == -1) return NULL;
+
+ p = fd_load(fd, size, maxsize, mem_ctx);
+
+ close(fd);
+
+ return p;
+}
+
+/**
+parse a buffer into lines
+'p' will be freed on error, and otherwise will be made a child of the returned array
+**/
+static char **file_lines_parse_internal(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx)
+{
+ unsigned int i;
+ char *s, **ret;
+
+ if (!p) return NULL;
+
+ for (s = p, i=0; s < p+size; s++) {
+ if (s[0] == '\n') i++;
+ }
+
+ ret = talloc_zero_array(mem_ctx, char *, i+2);
+ if (!ret) {
+ talloc_free(p);
+ return NULL;
+ }
+
+ talloc_steal(ret, p);
+
+ ret[0] = p;
+ for (s = p, i=1; s < p+size; s++) {
+ if (s[0] == '\n') {
+ s[0] = 0;
+ ret[i] = s+1;
+ i++;
+ }
+ if (s[0] == '\r') s[0] = 0;
+ }
+
+ /* remove any blank lines at the end */
+ while (i > 0 && ret[i-1][0] == 0) {
+ i--;
+ }
+
+ if (numlines) *numlines = i;
+
+ return ret;
+}
+
+
+/**
+load a file into memory and return an array of pointers to lines in the file
+must be freed with talloc_free().
+**/
+_PUBLIC_ char **file_lines_load(const char *fname, int *numlines, size_t maxsize, TALLOC_CTX *mem_ctx)
+{
+ char *p;
+ size_t size;
+
+ p = file_load(fname, &size, maxsize, mem_ctx);
+ if (!p) return NULL;
+
+ return file_lines_parse_internal(p, size, numlines, mem_ctx);
+}
+
+/**
+load a fd into memory and return an array of pointers to lines in the file
+must be freed with talloc_free(). If convert is true calls unix_to_dos on
+the list.
+**/
+_PUBLIC_ char **fd_lines_load(int fd, int *numlines, size_t maxsize, TALLOC_CTX *mem_ctx)
+{
+ char *p;
+ size_t size;
+
+ p = fd_load(fd, &size, maxsize, mem_ctx);
+ if (!p) return NULL;
+
+ return file_lines_parse_internal(p, size, numlines, mem_ctx);
+}
+
+_PUBLIC_ char **file_lines_parse(const char *p_in,
+ size_t size,
+ int *numlines,
+ TALLOC_CTX *mem_ctx)
+{
+ /*
+ * Copy the incoming string so it can end up
+ * being owned by the returned pointer and
+ * freed when that is.
+ */
+ char *p = talloc_strdup(mem_ctx, p_in);
+ if (p == NULL) {
+ return NULL;
+ }
+ return file_lines_parse_internal(p, size, numlines, mem_ctx);
+}
+
+_PUBLIC_ bool file_save_mode(const char *fname, const void *packet,
+ size_t length, mode_t mode)
+{
+ ssize_t num_written;
+ int fd;
+ fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, mode);
+ if (fd == -1) {
+ return false;
+ }
+ num_written = write(fd, packet, length);
+ if (num_written == -1 || (size_t)num_written != length) {
+ close(fd);
+ return false;
+ }
+ close(fd);
+ return true;
+}
+
+/**
+ save a lump of data into a file. Mostly used for debugging
+*/
+_PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length)
+{
+ return file_save_mode(fname, packet, length, 0644);
+}
+
+_PUBLIC_ int vfdprintf(int fd, const char *format, va_list ap)
+{
+ char *p;
+ int len, ret;
+ va_list ap2;
+
+ va_copy(ap2, ap);
+ len = vasprintf(&p, format, ap2);
+ va_end(ap2);
+ if (len <= 0) return len;
+ ret = write(fd, p, len);
+ SAFE_FREE(p);
+ return ret;
+}
+
+_PUBLIC_ int fdprintf(int fd, const char *format, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, format);
+ ret = vfdprintf(fd, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+
+/*
+ compare two files, return true if the two files have the same content
+ */
+bool file_compare(const char *path1, const char *path2)
+{
+ FILE *f1 = NULL, *f2 = NULL;
+ uint8_t buf1[1024], buf2[1024];
+ bool ret = false;
+
+ f1 = fopen(path1, "r");
+ if (f1 == NULL) {
+ goto done;
+ }
+ f2 = fopen(path2, "r");
+ if (f2 == NULL) {
+ goto done;
+ }
+
+ while (!feof(f1)) {
+ size_t n1 = fread(buf1, 1, sizeof(buf1), f1);
+ size_t n2 = fread(buf2, 1, sizeof(buf2), f2);
+
+ if (n1 != n2) {
+ goto done;
+ }
+ if (n1 == 0) {
+ ret = (feof(f1) && feof(f2));
+ goto done;
+ }
+ if (memcmp(buf1, buf2, n1) != 0) {
+ goto done;
+ }
+ if (n1 < sizeof(buf1)) {
+ bool has_error = (ferror(f1) || ferror(f2));
+ if (has_error) {
+ goto done;
+ }
+ }
+ }
+ ret = true;
+done:
+ if (f2 != NULL) {
+ fclose(f2);
+ }
+ if (f1 != NULL) {
+ fclose(f1);
+ }
+ return ret;
+}
+
+/**
+ Load from a pipe into memory.
+**/
+char *file_ploadv(char * const argl[], size_t *size)
+{
+ int fd, n;
+ char *p = NULL;
+ char buf[1024];
+ size_t total;
+
+ fd = sys_popenv(argl);
+ if (fd == -1) {
+ return NULL;
+ }
+
+ total = 0;
+
+ while ((n = sys_read(fd, buf, sizeof(buf))) > 0) {
+ p = talloc_realloc(NULL, p, char, total + n + 1);
+ if (p == NULL) {
+ DBG_ERR("failed to expand buffer!\n");
+ close(fd);
+ return NULL;
+ }
+ memcpy(p+total, buf, n);
+ total += n;
+ }
+
+ if (p != NULL) {
+ p[total] = 0;
+ }
+
+ /*
+ * FIXME: Perhaps ought to check that the command completed
+ * successfully (returned 0); if not the data may be
+ * truncated.
+ */
+ sys_pclose(fd);
+
+ if (size) {
+ *size = total;
+ }
+
+ return p;
+}
diff --git a/lib/util/util_id.c b/lib/util/util_id.c
new file mode 100644
index 0000000..19486f9
--- /dev/null
+++ b/lib/util/util_id.c
@@ -0,0 +1,89 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Helper routines for uid and gid arrays
+
+ Copyright (C) Guenther Deschner 2009
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "lib/util/samba_util.h"
+
+/****************************************************************************
+ Add a gid to an array of gids if it's not already there.
+****************************************************************************/
+
+bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
+ gid_t **gids, uint32_t *num_gids)
+{
+ uint32_t i;
+
+ if ((*num_gids != 0) && (*gids == NULL)) {
+ /*
+ * A former call to this routine has failed to allocate memory
+ */
+ return false;
+ }
+
+ for (i=0; i<*num_gids; i++) {
+ if ((*gids)[i] == gid) {
+ return true;
+ }
+ }
+
+ *gids = talloc_realloc(mem_ctx, *gids, gid_t, *num_gids+1);
+ if (*gids == NULL) {
+ *num_gids = 0;
+ return false;
+ }
+
+ (*gids)[*num_gids] = gid;
+ *num_gids += 1;
+ return true;
+}
+
+/****************************************************************************
+ Add a uid to an array of uids if it's not already there.
+****************************************************************************/
+
+bool add_uid_to_array_unique(TALLOC_CTX *mem_ctx, uid_t uid,
+ uid_t **uids, uint32_t *num_uids)
+{
+ uint32_t i;
+
+ if ((*num_uids != 0) && (*uids == NULL)) {
+ /*
+ * A former call to this routine has failed to allocate memory
+ */
+ return false;
+ }
+
+ for (i=0; i<*num_uids; i++) {
+ if ((*uids)[i] == uid) {
+ return true;
+ }
+ }
+
+ *uids = talloc_realloc(mem_ctx, *uids, uid_t, *num_uids+1);
+ if (*uids == NULL) {
+ *num_uids = 0;
+ return false;
+ }
+
+ (*uids)[*num_uids] = uid;
+ *num_uids += 1;
+ return true;
+}
diff --git a/lib/util/util_ldb.c b/lib/util/util_ldb.c
new file mode 100644
index 0000000..1fd5422
--- /dev/null
+++ b/lib/util/util_ldb.c
@@ -0,0 +1,114 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ common share info functions
+
+ Copyright (C) Andrew Tridgell 2004
+ Copyright (C) Tim Potter 2004
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include <ldb.h>
+#include "lib/util/util_ldb.h"
+#include "lib/util/debug.h"
+
+/*
+ * search the LDB for the specified attributes - va_list variant
+ */
+int gendb_search_v(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_dn *basedn,
+ struct ldb_message ***msgs,
+ const char * const *attrs,
+ const char *format,
+ va_list ap)
+{
+ enum ldb_scope scope = LDB_SCOPE_SUBTREE;
+ struct ldb_result *res;
+ char *expr = NULL;
+ int ret;
+
+ if (format) {
+ expr = talloc_vasprintf(mem_ctx, format, ap);
+ if (expr == NULL) {
+ return -1;
+ }
+ } else {
+ scope = LDB_SCOPE_BASE;
+ }
+
+ res = NULL;
+
+ ret = ldb_search(ldb, mem_ctx, &res, basedn, scope, attrs,
+ expr?"%s":NULL, expr);
+
+ if (ret == LDB_SUCCESS) {
+ DBG_DEBUG("%s %s -> %d\n",
+ basedn?ldb_dn_get_linearized(basedn):"NULL",
+ expr?expr:"NULL", res->count);
+
+ ret = res->count;
+ if (msgs != NULL) {
+ *msgs = talloc_steal(mem_ctx, res->msgs);
+ }
+ talloc_free(res);
+ } else if (scope == LDB_SCOPE_BASE && ret == LDB_ERR_NO_SUCH_OBJECT) {
+ ret = 0;
+ if (msgs != NULL) *msgs = NULL;
+ } else {
+ DBG_INFO("search failed: %s\n",
+ ldb_errstring(ldb));
+ ret = -1;
+ if (msgs != NULL) *msgs = NULL;
+ }
+
+ talloc_free(expr);
+
+ return ret;
+}
+
+/*
+ * search the LDB for the specified attributes - varargs variant
+ */
+int gendb_search(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_dn *basedn,
+ struct ldb_message ***res,
+ const char * const *attrs,
+ const char *format, ...)
+{
+ va_list ap;
+ int count;
+
+ va_start(ap, format);
+ count = gendb_search_v(ldb, mem_ctx, basedn, res, attrs, format, ap);
+ va_end(ap);
+
+ return count;
+}
+
+/*
+ * search the LDB for a specified record (by DN)
+ */
+int gendb_search_dn(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_dn *dn,
+ struct ldb_message ***res,
+ const char * const *attrs)
+{
+ return gendb_search(ldb, mem_ctx, dn, res, attrs, NULL);
+}
+
diff --git a/lib/util/util_ldb.h b/lib/util/util_ldb.h
new file mode 100644
index 0000000..6691644
--- /dev/null
+++ b/lib/util/util_ldb.h
@@ -0,0 +1,50 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ common share info functions
+
+ Copyright (C) Andrew Tridgell 2004
+ Copyright (C) Tim Potter 2004
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef __LIB_UTIL_UTIL_LDB_H__
+#define __LIB_UTIL_UTIL_LDB_H__
+
+struct ldb_dn;
+
+/* The following definitions come from lib/util/util_ldb.c */
+
+int gendb_search_v(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_dn *basedn,
+ struct ldb_message ***msgs,
+ const char * const *attrs,
+ const char *format,
+ va_list ap) PRINTF_ATTRIBUTE(6,0);
+int gendb_search(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_dn *basedn,
+ struct ldb_message ***res,
+ const char * const *attrs,
+ const char *format, ...) PRINTF_ATTRIBUTE(6,7);
+int gendb_search_dn(struct ldb_context *ldb,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_dn *dn,
+ struct ldb_message ***res,
+ const char * const *attrs);
+
+#endif /* __LIB_UTIL_UTIL_LDB_H__ */
diff --git a/lib/util/util_net.c b/lib/util/util_net.c
new file mode 100644
index 0000000..48c9552
--- /dev/null
+++ b/lib/util/util_net.c
@@ -0,0 +1,1240 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 1992-2007
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
+ Copyright (C) James J Myers 2003
+ Copyright (C) Tim Potter 2000-2001
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "system/network.h"
+#include "system/locale.h"
+#include "system/filesys.h"
+#include "system/select.h"
+#include "lib/util/select.h"
+#include "lib/util/util_net.h"
+
+#undef strcasecmp
+#undef strncasecmp
+
+/*******************************************************************
+ Set an address to INADDR_ANY.
+******************************************************************/
+
+void zero_sockaddr(struct sockaddr_storage *pss)
+{
+ /* Ensure we're at least a valid sockaddr-storage. */
+ *pss = (struct sockaddr_storage) { .ss_family = AF_INET };
+}
+
+static char *normalize_ipv6_literal(const char *str, char *buf, size_t *_len)
+{
+#define IPv6_LITERAL_NET ".ipv6-literal.net"
+ const size_t llen = sizeof(IPv6_LITERAL_NET) - 1;
+ size_t len = *_len;
+ int cmp;
+ size_t i;
+ size_t idx_chars = 0;
+ size_t cnt_delimiter = 0;
+ size_t cnt_chars = 0;
+
+ if (len <= llen) {
+ return NULL;
+ }
+
+ /* ignore a trailing '.' */
+ if (str[len - 1] == '.') {
+ len -= 1;
+ }
+
+ len -= llen;
+ if (len >= INET6_ADDRSTRLEN) {
+ return NULL;
+ }
+ if (len < 2) {
+ return NULL;
+ }
+
+ cmp = strncasecmp(&str[len], IPv6_LITERAL_NET, llen);
+ if (cmp != 0) {
+ return NULL;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (idx_chars != 0) {
+ break;
+ }
+
+ switch (str[i]) {
+ case '-':
+ buf[i] = ':';
+ cnt_chars = 0;
+ cnt_delimiter += 1;
+ break;
+ case 's':
+ buf[i] = SCOPE_DELIMITER;
+ idx_chars += 1;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'a':
+ case 'A':
+ case 'b':
+ case 'B':
+ case 'c':
+ case 'C':
+ case 'd':
+ case 'D':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'F':
+ buf[i] = str[i];
+ cnt_chars += 1;
+ break;
+ default:
+ return NULL;
+ }
+ if (cnt_chars > 4) {
+ return NULL;
+ }
+ if (cnt_delimiter > 7) {
+ return NULL;
+ }
+ }
+
+ if (cnt_delimiter < 2) {
+ return NULL;
+ }
+
+ for (; idx_chars != 0 && i < len; i++) {
+ switch (str[i]) {
+ case SCOPE_DELIMITER:
+ case ':':
+ return NULL;
+ default:
+ buf[i] = str[i];
+ idx_chars += 1;
+ break;
+ }
+ }
+
+ if (idx_chars == 1) {
+ return NULL;
+ }
+
+ buf[i] = '\0';
+ *_len = len;
+ return buf;
+}
+
+/**
+ * Wrap getaddrinfo...
+ */
+bool interpret_string_addr_internal(struct addrinfo **ppres,
+ const char *str, int flags)
+{
+ int ret;
+ struct addrinfo hints;
+#if defined(HAVE_IPV6)
+ char addr[INET6_ADDRSTRLEN*2] = { 0, };
+ unsigned int scope_id = 0;
+ size_t len = strlen(str);
+#endif
+
+ ZERO_STRUCT(hints);
+
+ /* By default make sure it supports TCP. */
+ hints.ai_socktype = SOCK_STREAM;
+
+ /* always try as a numeric host first. This prevents unnecessary name
+ * lookups, and also ensures we accept IPv6 addresses */
+ hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
+
+#if defined(HAVE_IPV6)
+ if (len < sizeof(addr)) {
+ char *p = NULL;
+
+ p = normalize_ipv6_literal(str, addr, &len);
+ if (p != NULL) {
+ hints.ai_family = AF_INET6;
+ str = p;
+ }
+ }
+
+ if (strchr_m(str, ':')) {
+ char *p = strchr_m(str, SCOPE_DELIMITER);
+
+ /*
+ * Cope with link-local.
+ * This is IP:v6:addr%ifname.
+ */
+
+ if (p && (p > str) && ((scope_id = if_nametoindex(p+1)) != 0)) {
+ /* Length of string we want to copy.
+ This is IP:v6:addr (removing the %ifname).
+ */
+ len = PTR_DIFF(p,str);
+
+ if (len+1 > sizeof(addr)) {
+ /* string+nul too long for array. */
+ return false;
+ }
+ if (str != addr) {
+ memcpy(addr, str, len);
+ }
+ addr[len] = '\0';
+
+ str = addr;
+ }
+ }
+#endif
+
+ ret = getaddrinfo(str, NULL, &hints, ppres);
+ if (ret == 0) {
+#if defined(HAVE_IPV6)
+ struct sockaddr_in6 *ps6 = NULL;
+
+ if (scope_id == 0) {
+ return true;
+ }
+ if (ppres == NULL) {
+ return true;
+ }
+ if ((*ppres) == NULL) {
+ return true;
+ }
+ if ((*ppres)->ai_addr->sa_family != AF_INET6) {
+ return true;
+ }
+
+ ps6 = (struct sockaddr_in6 *)(*ppres)->ai_addr;
+
+ if (IN6_IS_ADDR_LINKLOCAL(&ps6->sin6_addr) &&
+ ps6->sin6_scope_id == 0) {
+ ps6->sin6_scope_id = scope_id;
+ }
+#endif
+
+ return true;
+ }
+
+ hints.ai_flags = flags;
+
+ /* Linux man page on getaddrinfo() says port will be
+ uninitialized when service string is NULL */
+
+ ret = getaddrinfo(str, NULL,
+ &hints,
+ ppres);
+
+ if (ret) {
+ DEBUG(3, ("interpret_string_addr_internal: "
+ "getaddrinfo failed for name %s (flags %d) [%s]\n",
+ str, flags, gai_strerror(ret)));
+ return false;
+ }
+ return true;
+}
+
+/*******************************************************************
+ Map a text hostname or IP address (IPv4 or IPv6) into a
+ struct sockaddr_storage. Takes a flag which allows it to
+ prefer an IPv4 address (needed for DC's).
+******************************************************************/
+
+static bool interpret_string_addr_pref(struct sockaddr_storage *pss,
+ const char *str,
+ int flags,
+ bool prefer_ipv4)
+{
+ struct addrinfo *res = NULL;
+ int int_flags;
+
+ zero_sockaddr(pss);
+
+ if (flags & AI_NUMERICHOST) {
+ int_flags = flags;
+ } else {
+ int_flags = flags|AI_ADDRCONFIG;
+ }
+
+ if (!interpret_string_addr_internal(&res, str, int_flags)) {
+ return false;
+ }
+ if (!res) {
+ return false;
+ }
+
+ if (prefer_ipv4) {
+ struct addrinfo *p;
+
+ for (p = res; p; p = p->ai_next) {
+ if (p->ai_family == AF_INET) {
+ memcpy(pss, p->ai_addr, p->ai_addrlen);
+ break;
+ }
+ }
+ if (p == NULL) {
+ /* Copy the first sockaddr. */
+ memcpy(pss, res->ai_addr, res->ai_addrlen);
+ }
+ } else {
+ /* Copy the first sockaddr. */
+ memcpy(pss, res->ai_addr, res->ai_addrlen);
+ }
+
+ freeaddrinfo(res);
+ return true;
+}
+
+/*******************************************************************
+ Map a text hostname or IP address (IPv4 or IPv6) into a
+ struct sockaddr_storage. Address agnostic version.
+******************************************************************/
+
+bool interpret_string_addr(struct sockaddr_storage *pss,
+ const char *str,
+ int flags)
+{
+ return interpret_string_addr_pref(pss,
+ str,
+ flags,
+ false);
+}
+
+/*******************************************************************
+ Map a text hostname or IP address (IPv4 or IPv6) into a
+ struct sockaddr_storage. Version that prefers IPv4.
+******************************************************************/
+
+bool interpret_string_addr_prefer_ipv4(struct sockaddr_storage *pss,
+ const char *str,
+ int flags)
+{
+ return interpret_string_addr_pref(pss,
+ str,
+ flags,
+ true);
+}
+
+/**
+ * Interpret an internet address or name into an IP address in 4 byte form.
+ * RETURNS IN NETWORK BYTE ORDER (big endian).
+ */
+
+uint32_t interpret_addr(const char *str)
+{
+ uint32_t ret;
+
+ /* If it's in the form of an IP address then
+ * get the lib to interpret it */
+ if (is_ipaddress_v4(str)) {
+ struct in_addr dest;
+
+ if (inet_pton(AF_INET, str, &dest) <= 0) {
+ /* Error - this shouldn't happen ! */
+ DEBUG(0,("interpret_addr: inet_pton failed "
+ "host %s\n",
+ str));
+ return 0;
+ }
+ ret = dest.s_addr; /* NETWORK BYTE ORDER ! */
+ } else {
+ /* Otherwise assume it's a network name of some sort and use
+ getaddrinfo. */
+ struct addrinfo *res = NULL;
+ struct addrinfo *res_list = NULL;
+ if (!interpret_string_addr_internal(&res_list,
+ str,
+ AI_ADDRCONFIG)) {
+ DEBUG(3,("interpret_addr: Unknown host. %s\n",str));
+ return 0;
+ }
+
+ /* Find the first IPv4 address. */
+ for (res = res_list; res; res = res->ai_next) {
+ if (res->ai_family != AF_INET) {
+ continue;
+ }
+ if (res->ai_addr == NULL) {
+ continue;
+ }
+ break;
+ }
+ if(res == NULL) {
+ DEBUG(3,("interpret_addr: host address is "
+ "invalid for host %s\n",str));
+ if (res_list) {
+ freeaddrinfo(res_list);
+ }
+ return 0;
+ }
+ memcpy((char *)&ret,
+ &((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr,
+ sizeof(ret));
+ if (res_list) {
+ freeaddrinfo(res_list);
+ }
+ }
+
+ /* This is so bogus - all callers need fixing... JRA. */
+ if (ret == (uint32_t)-1) {
+ return 0;
+ }
+
+ return ret;
+}
+
+/**
+ A convenient addition to interpret_addr().
+**/
+_PUBLIC_ struct in_addr interpret_addr2(const char *str)
+{
+ struct in_addr ret;
+ uint32_t a = interpret_addr(str);
+ ret.s_addr = a;
+ return ret;
+}
+
+/**
+ Check if an IP is the 0.0.0.0.
+**/
+
+_PUBLIC_ bool is_zero_ip_v4(struct in_addr ip)
+{
+ return ip.s_addr == 0;
+}
+
+/**
+ Are two IPs on the same subnet?
+**/
+
+_PUBLIC_ bool same_net_v4(struct in_addr ip1, struct in_addr ip2, struct in_addr mask)
+{
+ uint32_t net1,net2,nmask;
+
+ nmask = ntohl(mask.s_addr);
+ net1 = ntohl(ip1.s_addr);
+ net2 = ntohl(ip2.s_addr);
+
+ return((net1 & nmask) == (net2 & nmask));
+}
+
+/**
+ * Return true if a string could be an IPv4 address.
+ */
+
+bool is_ipaddress_v4(const char *str)
+{
+ int ret = -1;
+ struct in_addr dest;
+
+ ret = inet_pton(AF_INET, str, &dest);
+ if (ret > 0) {
+ return true;
+ }
+ return false;
+}
+
+bool is_ipv6_literal(const char *str)
+{
+#if defined(HAVE_IPV6)
+ char buf[INET6_ADDRSTRLEN*2] = { 0, };
+ size_t len = strlen(str);
+ char *p = NULL;
+
+ if (len >= sizeof(buf)) {
+ return false;
+ }
+
+ p = normalize_ipv6_literal(str, buf, &len);
+ if (p == NULL) {
+ return false;
+ }
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+/**
+ * Return true if a string could be a IPv6 address.
+ */
+
+bool is_ipaddress_v6(const char *str)
+{
+#if defined(HAVE_IPV6)
+ int ret = -1;
+ char *p = NULL;
+ char buf[INET6_ADDRSTRLEN] = { 0, };
+ size_t len;
+ const char *addr = str;
+ const char *idxs = NULL;
+ unsigned int idx = 0;
+ struct in6_addr ip6;
+
+ p = strchr_m(str, ':');
+ if (p == NULL) {
+ return is_ipv6_literal(str);
+ }
+
+ p = strchr_m(str, SCOPE_DELIMITER);
+ if (p && (p > str)) {
+ len = PTR_DIFF(p, str);
+ idxs = p + 1;
+ } else {
+ len = strlen(str);
+ }
+
+ if (len >= sizeof(buf)) {
+ return false;
+ }
+ if (idxs != NULL) {
+ strncpy(buf, str, len);
+ addr = buf;
+ }
+
+ /*
+ * Cope with link-local.
+ * This is IP:v6:addr%ifidx.
+ */
+ if (idxs != NULL) {
+ char c;
+
+ ret = sscanf(idxs, "%5u%c", &idx, &c);
+ if (ret != 1) {
+ idx = 0;
+ }
+
+ if (idx > 0 && idx < UINT16_MAX) {
+ /* a valid index */
+ idxs = NULL;
+ }
+ }
+
+ /*
+ * Cope with link-local.
+ * This is IP:v6:addr%ifname.
+ */
+ if (idxs != NULL) {
+ idx = if_nametoindex(idxs);
+
+ if (idx > 0) {
+ /* a valid index */
+ idxs = NULL;
+ }
+ }
+
+ if (idxs != NULL) {
+ return false;
+ }
+
+ ret = inet_pton(AF_INET6, addr, &ip6);
+ if (ret <= 0) {
+ return false;
+ }
+
+ return true;
+#else
+ return false;
+#endif
+}
+
+/**
+ * Return true if a string could be an IPv4 or IPv6 address.
+ */
+
+bool is_ipaddress(const char *str)
+{
+ return is_ipaddress_v4(str) || is_ipaddress_v6(str);
+}
+
+/**
+ * Is a sockaddr a broadcast address ?
+ */
+
+bool is_broadcast_addr(const struct sockaddr *pss)
+{
+#if defined(HAVE_IPV6)
+ if (pss->sa_family == AF_INET6) {
+ const struct in6_addr *sin6 =
+ &((const struct sockaddr_in6 *)pss)->sin6_addr;
+ return IN6_IS_ADDR_MULTICAST(sin6);
+ }
+#endif
+ if (pss->sa_family == AF_INET) {
+ uint32_t addr =
+ ntohl(((const struct sockaddr_in *)pss)->sin_addr.s_addr);
+ return addr == INADDR_BROADCAST;
+ }
+ return false;
+}
+
+/**
+ * Check if an IPv7 is 127.0.0.1
+ */
+bool is_loopback_ip_v4(struct in_addr ip)
+{
+ struct in_addr a;
+ a.s_addr = htonl(INADDR_LOOPBACK);
+ return(ip.s_addr == a.s_addr);
+}
+
+/**
+ * Check if a struct sockaddr is the loopback address.
+ */
+bool is_loopback_addr(const struct sockaddr *pss)
+{
+#if defined(HAVE_IPV6)
+ if (pss->sa_family == AF_INET6) {
+ const struct in6_addr *pin6 =
+ &((const struct sockaddr_in6 *)pss)->sin6_addr;
+ return IN6_IS_ADDR_LOOPBACK(pin6);
+ }
+#endif
+ if (pss->sa_family == AF_INET) {
+ const struct in_addr *pin = &((const struct sockaddr_in *)pss)->sin_addr;
+ return is_loopback_ip_v4(*pin);
+ }
+ return false;
+}
+
+/**
+ * Check if a struct sockaddr has an unspecified address.
+ */
+bool is_zero_addr(const struct sockaddr_storage *pss)
+{
+#if defined(HAVE_IPV6)
+ if (pss->ss_family == AF_INET6) {
+ const struct in6_addr *pin6 =
+ &((const struct sockaddr_in6 *)pss)->sin6_addr;
+ return IN6_IS_ADDR_UNSPECIFIED(pin6);
+ }
+#endif
+ if (pss->ss_family == AF_INET) {
+ const struct in_addr *pin = &((const struct sockaddr_in *)pss)->sin_addr;
+ return is_zero_ip_v4(*pin);
+ }
+ if (pss->ss_family == AF_UNSPEC) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Set an IP to 0.0.0.0.
+ */
+void zero_ip_v4(struct in_addr *ip)
+{
+ ZERO_STRUCTP(ip);
+}
+
+bool is_linklocal_addr(const struct sockaddr_storage *pss)
+{
+#ifdef HAVE_IPV6
+ if (pss->ss_family == AF_INET6) {
+ const struct in6_addr *pin6 =
+ &((const struct sockaddr_in6 *)pss)->sin6_addr;
+ return IN6_IS_ADDR_LINKLOCAL(pin6);
+ }
+#endif
+ if (pss->ss_family == AF_INET) {
+ const struct in_addr *pin =
+ &((const struct sockaddr_in *)pss)->sin_addr;
+ struct in_addr ll_addr;
+ struct in_addr mask_addr;
+
+ /* 169.254.0.0/16, is link local, see RFC 3927 */
+ ll_addr.s_addr = 0xa9fe0000;
+ mask_addr.s_addr = 0xffff0000;
+ return same_net_v4(*pin, ll_addr, mask_addr);
+ }
+ return false;
+}
+
+/**
+ * Convert an IPv4 struct in_addr to a struct sockaddr_storage.
+ */
+void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss,
+ struct in_addr ip)
+{
+ struct sockaddr_in *sa = (struct sockaddr_in *)ss;
+ ZERO_STRUCTP(ss);
+ sa->sin_family = AF_INET;
+ sa->sin_addr = ip;
+}
+
+#if defined(HAVE_IPV6)
+/**
+ * Convert an IPv6 struct in_addr to a struct sockaddr_storage.
+ */
+void in6_addr_to_sockaddr_storage(struct sockaddr_storage *ss,
+ struct in6_addr ip)
+{
+ struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss;
+ memset(ss, '\0', sizeof(*ss));
+ sa->sin6_family = AF_INET6;
+ sa->sin6_addr = ip;
+}
+#endif
+
+/**
+ * Are two IPs on the same subnet?
+ */
+bool same_net(const struct sockaddr *ip1,
+ const struct sockaddr *ip2,
+ const struct sockaddr *mask)
+{
+ if (ip1->sa_family != ip2->sa_family) {
+ /* Never on the same net. */
+ return false;
+ }
+
+#if defined(HAVE_IPV6)
+ if (ip1->sa_family == AF_INET6) {
+ struct sockaddr_in6 ip1_6 = *(const struct sockaddr_in6 *)ip1;
+ struct sockaddr_in6 ip2_6 = *(const struct sockaddr_in6 *)ip2;
+ struct sockaddr_in6 mask_6 = *(const struct sockaddr_in6 *)mask;
+ char *p1 = (char *)&ip1_6.sin6_addr;
+ char *p2 = (char *)&ip2_6.sin6_addr;
+ char *m = (char *)&mask_6.sin6_addr;
+ size_t i;
+
+ for (i = 0; i < sizeof(struct in6_addr); i++) {
+ *p1++ &= *m;
+ *p2++ &= *m;
+ m++;
+ }
+ return (memcmp(&ip1_6.sin6_addr,
+ &ip2_6.sin6_addr,
+ sizeof(struct in6_addr)) == 0);
+ }
+#endif
+ if (ip1->sa_family == AF_INET) {
+ return same_net_v4(((const struct sockaddr_in *)ip1)->sin_addr,
+ ((const struct sockaddr_in *)ip2)->sin_addr,
+ ((const struct sockaddr_in *)mask)->sin_addr);
+ }
+ return false;
+}
+
+/**
+ * Are two sockaddr 's the same family and address ? Ignore port etc.
+ */
+
+bool sockaddr_equal(const struct sockaddr *ip1,
+ const struct sockaddr *ip2)
+{
+ if (ip1->sa_family != ip2->sa_family) {
+ /* Never the same. */
+ return false;
+ }
+
+#if defined(HAVE_IPV6)
+ if (ip1->sa_family == AF_INET6) {
+ return (memcmp(&((const struct sockaddr_in6 *)ip1)->sin6_addr,
+ &((const struct sockaddr_in6 *)ip2)->sin6_addr,
+ sizeof(struct in6_addr)) == 0);
+ }
+#endif
+ if (ip1->sa_family == AF_INET) {
+ return (memcmp(&((const struct sockaddr_in *)ip1)->sin_addr,
+ &((const struct sockaddr_in *)ip2)->sin_addr,
+ sizeof(struct in_addr)) == 0);
+ }
+ return false;
+}
+
+/**
+ * Is an IP address the INADDR_ANY or in6addr_any value ?
+ */
+bool is_address_any(const struct sockaddr *psa)
+{
+#if defined(HAVE_IPV6)
+ if (psa->sa_family == AF_INET6) {
+ const struct sockaddr_in6 *si6 = (const struct sockaddr_in6 *)psa;
+ if (memcmp(&in6addr_any,
+ &si6->sin6_addr,
+ sizeof(in6addr_any)) == 0) {
+ return true;
+ }
+ return false;
+ }
+#endif
+ if (psa->sa_family == AF_INET) {
+ const struct sockaddr_in *si = (const struct sockaddr_in *)psa;
+ if (si->sin_addr.s_addr == INADDR_ANY) {
+ return true;
+ }
+ return false;
+ }
+ return false;
+}
+
+void set_sockaddr_port(struct sockaddr *psa, uint16_t port)
+{
+#if defined(HAVE_IPV6)
+ if (psa->sa_family == AF_INET6) {
+ ((struct sockaddr_in6 *)psa)->sin6_port = htons(port);
+ }
+#endif
+ if (psa->sa_family == AF_INET) {
+ ((struct sockaddr_in *)psa)->sin_port = htons(port);
+ }
+}
+
+
+/****************************************************************************
+ Get a port number in host byte order from a sockaddr_storage.
+****************************************************************************/
+
+uint16_t get_sockaddr_port(const struct sockaddr_storage *pss)
+{
+ uint16_t port = 0;
+
+ if (pss->ss_family != AF_INET) {
+#if defined(HAVE_IPV6)
+ /* IPv6 */
+ const struct sockaddr_in6 *sa6 =
+ (const struct sockaddr_in6 *)pss;
+ port = ntohs(sa6->sin6_port);
+#endif
+ } else {
+ const struct sockaddr_in *sa =
+ (const struct sockaddr_in *)pss;
+ port = ntohs(sa->sin_port);
+ }
+ return port;
+}
+
+/****************************************************************************
+ Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_sockaddr_len(char *dest,
+ size_t destlen,
+ const struct sockaddr *psa,
+ socklen_t psalen)
+{
+ if (destlen > 0) {
+ dest[0] = '\0';
+ }
+ (void)sys_getnameinfo(psa,
+ psalen,
+ dest, destlen,
+ NULL, 0,
+ NI_NUMERICHOST);
+ return dest;
+}
+
+/****************************************************************************
+ Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_sockaddr(char *dest,
+ size_t destlen,
+ const struct sockaddr_storage *psa)
+{
+ return print_sockaddr_len(dest, destlen, (const struct sockaddr *)psa,
+ sizeof(struct sockaddr_storage));
+}
+
+/****************************************************************************
+ Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_canonical_sockaddr(TALLOC_CTX *ctx,
+ const struct sockaddr_storage *pss)
+{
+ char addr[INET6_ADDRSTRLEN];
+ char *dest = NULL;
+ int ret;
+
+ /* Linux getnameinfo() man pages says port is uninitialized if
+ service name is NULL. */
+
+ ret = sys_getnameinfo((const struct sockaddr *)pss,
+ sizeof(struct sockaddr_storage),
+ addr, sizeof(addr),
+ NULL, 0,
+ NI_NUMERICHOST);
+ if (ret != 0) {
+ return NULL;
+ }
+
+ if (pss->ss_family != AF_INET) {
+#if defined(HAVE_IPV6)
+ dest = talloc_asprintf(ctx, "[%s]", addr);
+#else
+ return NULL;
+#endif
+ } else {
+ dest = talloc_asprintf(ctx, "%s", addr);
+ }
+
+ return dest;
+}
+
+enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
+
+typedef struct smb_socket_option {
+ const char *name;
+ int level;
+ int option;
+ int value;
+ int opttype;
+} smb_socket_option;
+
+static const smb_socket_option socket_options[] = {
+ {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
+ {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
+ {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
+#ifdef TCP_NODELAY
+ {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
+#endif
+#ifdef TCP_KEEPCNT
+ {"TCP_KEEPCNT", IPPROTO_TCP, TCP_KEEPCNT, 0, OPT_INT},
+#endif
+#ifdef TCP_KEEPIDLE
+ {"TCP_KEEPIDLE", IPPROTO_TCP, TCP_KEEPIDLE, 0, OPT_INT},
+#endif
+#ifdef TCP_KEEPINTVL
+ {"TCP_KEEPINTVL", IPPROTO_TCP, TCP_KEEPINTVL, 0, OPT_INT},
+#endif
+#ifdef IPTOS_LOWDELAY
+ {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
+#endif
+#ifdef IPTOS_THROUGHPUT
+ {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
+#endif
+#ifdef SO_REUSEPORT
+ {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL},
+#endif
+#ifdef SO_SNDBUF
+ {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
+#endif
+#ifdef SO_RCVBUF
+ {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
+#endif
+#ifdef SO_SNDLOWAT
+ {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
+#endif
+#ifdef SO_RCVLOWAT
+ {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
+#endif
+#ifdef SO_SNDTIMEO
+ {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
+#endif
+#ifdef SO_RCVTIMEO
+ {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
+#endif
+#ifdef TCP_FASTACK
+ {"TCP_FASTACK", IPPROTO_TCP, TCP_FASTACK, 0, OPT_INT},
+#endif
+#ifdef TCP_QUICKACK
+ {"TCP_QUICKACK", IPPROTO_TCP, TCP_QUICKACK, 0, OPT_BOOL},
+#endif
+#ifdef TCP_NODELAYACK
+ {"TCP_NODELAYACK", IPPROTO_TCP, TCP_NODELAYACK, 0, OPT_BOOL},
+#endif
+#ifdef TCP_KEEPALIVE_THRESHOLD
+ {"TCP_KEEPALIVE_THRESHOLD", IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD, 0, OPT_INT},
+#endif
+#ifdef TCP_KEEPALIVE_ABORT_THRESHOLD
+ {"TCP_KEEPALIVE_ABORT_THRESHOLD", IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD, 0, OPT_INT},
+#endif
+#ifdef TCP_DEFER_ACCEPT
+ {"TCP_DEFER_ACCEPT", IPPROTO_TCP, TCP_DEFER_ACCEPT, 0, OPT_INT},
+#endif
+#ifdef TCP_USER_TIMEOUT
+ {"TCP_USER_TIMEOUT", IPPROTO_TCP, TCP_USER_TIMEOUT, 0, OPT_INT},
+#endif
+ {NULL,0,0,0,0}};
+
+/****************************************************************************
+ Print socket options.
+****************************************************************************/
+
+static void print_socket_options(TALLOC_CTX *ctx, int s)
+{
+ const smb_socket_option *p = &socket_options[0];
+ char *str = NULL;
+
+ if (DEBUGLEVEL < 5) {
+ return;
+ }
+
+ str = talloc_strdup(ctx, "");
+ if (str == NULL) {
+ DBG_WARNING("talloc failed\n");
+ goto done;
+ }
+
+ for (; p->name != NULL; p++) {
+ int ret, val;
+ socklen_t vlen = sizeof(val);
+
+ ret = getsockopt(s, p->level, p->option, (void *)&val, &vlen);
+ if (ret == -1) {
+ DBG_INFO("Could not test socket option %s: %s.\n",
+ p->name, strerror(errno));
+ continue;
+ }
+
+ talloc_asprintf_addbuf(
+ &str,
+ "%s%s=%d",
+ str[0] != '\0' ? ", " : "",
+ p->name,
+ val);
+ }
+
+ DEBUG(5, ("socket options: %s\n", str));
+done:
+ TALLOC_FREE(str);
+ }
+
+/****************************************************************************
+ Set user socket options.
+****************************************************************************/
+
+void set_socket_options(int fd, const char *options)
+{
+ TALLOC_CTX *ctx = talloc_new(NULL);
+ char *tok;
+
+ while (next_token_talloc(ctx, &options, &tok," \t,")) {
+ int ret=0,i;
+ int value = 1;
+ char *p;
+ bool got_value = false;
+
+ if ((p = strchr_m(tok,'='))) {
+ *p = 0;
+ value = atoi(p+1);
+ got_value = true;
+ }
+
+ for (i=0;socket_options[i].name;i++)
+ if (strequal(socket_options[i].name,tok))
+ break;
+
+ if (!socket_options[i].name) {
+ DEBUG(0,("Unknown socket option %s\n",tok));
+ continue;
+ }
+
+ switch (socket_options[i].opttype) {
+ case OPT_BOOL:
+ case OPT_INT:
+ ret = setsockopt(fd,socket_options[i].level,
+ socket_options[i].option,
+ (char *)&value,sizeof(int));
+ break;
+
+ case OPT_ON:
+ if (got_value)
+ DEBUG(0,("syntax error - %s "
+ "does not take a value\n",tok));
+
+ {
+ int on = socket_options[i].value;
+ ret = setsockopt(fd,socket_options[i].level,
+ socket_options[i].option,
+ (char *)&on,sizeof(int));
+ }
+ break;
+ }
+
+ if (ret != 0) {
+ /* be aware that some systems like Solaris return
+ * EINVAL to a setsockopt() call when the client
+ * sent a RST previously - no need to worry */
+ DEBUG(2,("Failed to set socket option %s (Error %s)\n",
+ tok, strerror(errno) ));
+ }
+ }
+
+ print_socket_options(ctx, fd);
+ TALLOC_FREE(ctx);
+}
+
+/*
+ * Utility function that copes only with AF_INET and AF_INET6
+ * as that's all we're going to get out of DNS / NetBIOS / WINS
+ * name resolution functions.
+ */
+
+bool sockaddr_storage_to_samba_sockaddr(
+ struct samba_sockaddr *sa, const struct sockaddr_storage *ss)
+{
+ sa->u.ss = *ss;
+
+ switch (ss->ss_family) {
+ case AF_INET:
+ sa->sa_socklen = sizeof(struct sockaddr_in);
+ break;
+#ifdef HAVE_IPV6
+ case AF_INET6:
+ sa->sa_socklen = sizeof(struct sockaddr_in6);
+ break;
+#endif
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool samba_sockaddr_set_port(struct samba_sockaddr *sa, uint16_t port)
+{
+ if (sa->u.sa.sa_family == AF_INET) {
+ sa->u.in.sin_port = htons(port);
+ return true;
+ }
+#ifdef HAVE_IPV6
+ if (sa->u.sa.sa_family == AF_INET6) {
+ sa->u.in6.sin6_port = htons(port);
+ return true;
+ }
+#endif
+ return false;
+}
+
+bool samba_sockaddr_get_port(const struct samba_sockaddr *sa, uint16_t *port)
+{
+ if (sa->u.sa.sa_family == AF_INET) {
+ *port = ntohs(sa->u.in.sin_port);
+ return true;
+ }
+#ifdef HAVE_IPV6
+ if (sa->u.sa.sa_family == AF_INET6) {
+ *port = ntohs(sa->u.in6.sin6_port);
+ return true;
+ }
+#endif
+ return false;
+}
+
+int samba_socket_poll_error(int fd)
+{
+ struct pollfd pfd = {
+ .fd = fd,
+#ifdef POLLRDHUP
+ .events = POLLRDHUP, /* POLLERR and POLLHUP are not needed */
+#endif
+ };
+ int ret;
+
+ errno = 0;
+ ret = sys_poll_intr(&pfd, 1, 0);
+ if (ret == 0) {
+ return 0;
+ }
+ if (ret != 1) {
+ return POLLNVAL;
+ }
+
+ if (pfd.revents & POLLERR) {
+ return POLLERR;
+ }
+ if (pfd.revents & POLLHUP) {
+ return POLLHUP;
+ }
+#ifdef POLLRDHUP
+ if (pfd.revents & POLLRDHUP) {
+ return POLLRDHUP;
+ }
+#endif
+
+ /* should never be reached! */
+ return POLLNVAL;
+}
+
+int samba_socket_sock_error(int fd)
+{
+ int ret, error = 0;
+ socklen_t len = sizeof(error);
+
+ /*
+ * if no data is available check if the socket is in error state. For
+ * dgram sockets it's the way to return ICMP error messages of
+ * connected sockets to the caller.
+ */
+ ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);
+ if (ret == -1) {
+ return ret;
+ }
+ if (error != 0) {
+ errno = error;
+ return -1;
+ }
+ return 0;
+}
+
+int samba_socket_poll_or_sock_error(int fd)
+{
+ int ret;
+ int poll_error = 0;
+
+ poll_error = samba_socket_poll_error(fd);
+ if (poll_error == 0) {
+ return 0;
+ }
+
+#ifdef POLLRDHUP
+ if (poll_error == POLLRDHUP) {
+ errno = ECONNRESET;
+ return -1;
+ }
+#endif
+
+ if (poll_error == POLLHUP) {
+ errno = EPIPE;
+ return -1;
+ }
+
+ /*
+ * POLLERR and POLLNVAL fallback to
+ * getsockopt(fd, SOL_SOCKET, SO_ERROR)
+ * and force EPIPE as fallback.
+ */
+
+ errno = 0;
+ ret = samba_socket_sock_error(fd);
+ if (ret == 0) {
+ errno = EPIPE;
+ }
+
+ if (errno == 0) {
+ errno = EPIPE;
+ }
+
+ return -1;
+}
diff --git a/lib/util/util_net.h b/lib/util/util_net.h
new file mode 100644
index 0000000..1aed45a
--- /dev/null
+++ b/lib/util/util_net.h
@@ -0,0 +1,145 @@
+/*
+ Unix SMB/CIFS implementation.
+ Utility functions for Samba
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Jelmer Vernooij 2005
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_UTIL_NET_H_
+#define _SAMBA_UTIL_NET_H_
+
+#include "system/network.h"
+
+struct samba_sockaddr {
+ socklen_t sa_socklen;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in in;
+#ifdef HAVE_IPV6
+ struct sockaddr_in6 in6;
+#endif
+ struct sockaddr_un un;
+ struct sockaddr_storage ss;
+ } u;
+};
+
+/* The following definitions come from lib/util/util_net.c */
+
+void zero_sockaddr(struct sockaddr_storage *pss);
+
+bool interpret_string_addr_internal(struct addrinfo **ppres,
+ const char *str, int flags);
+
+bool interpret_string_addr(struct sockaddr_storage *pss,
+ const char *str,
+ int flags);
+
+/*******************************************************************
+ Map a text hostname or IP address (IPv4 or IPv6) into a
+ struct sockaddr_storage. Version that prefers IPv4.
+******************************************************************/
+
+bool interpret_string_addr_prefer_ipv4(struct sockaddr_storage *pss,
+ const char *str,
+ int flags);
+
+void set_sockaddr_port(struct sockaddr *psa, uint16_t port);
+
+/**
+ Check if an IP is the 0.0.0.0.
+**/
+_PUBLIC_ bool is_zero_ip_v4(struct in_addr ip);
+
+void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss,
+ struct in_addr ip);
+#if defined(HAVE_IPV6)
+/**
+ * Convert an IPv6 struct in_addr to a struct sockaddr_storage.
+ */
+void in6_addr_to_sockaddr_storage(struct sockaddr_storage *ss,
+ struct in6_addr ip);
+#endif
+/**
+ Are two IPs on the same subnet?
+**/
+_PUBLIC_ bool same_net_v4(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
+
+/**
+ Return true if a string could be a pure IP address.
+**/
+_PUBLIC_ bool is_ipaddress(const char *str);
+
+bool is_broadcast_addr(const struct sockaddr *pss);
+bool is_loopback_ip_v4(struct in_addr ip);
+bool is_loopback_addr(const struct sockaddr *pss);
+bool is_zero_addr(const struct sockaddr_storage *pss);
+void zero_ip_v4(struct in_addr *ip);
+bool is_linklocal_addr(const struct sockaddr_storage *pss);
+/**
+ Interpret an internet address or name into an IP address in 4 byte form.
+**/
+_PUBLIC_ uint32_t interpret_addr(const char *str);
+
+/**
+ A convenient addition to interpret_addr().
+**/
+_PUBLIC_ struct in_addr interpret_addr2(const char *str);
+
+_PUBLIC_ bool is_ipaddress_v4(const char *str);
+_PUBLIC_ bool is_ipv6_literal(const char *str);
+_PUBLIC_ bool is_ipaddress_v6(const char *str);
+
+bool is_address_any(const struct sockaddr *psa);
+bool same_net(const struct sockaddr *ip1,
+ const struct sockaddr *ip2,
+ const struct sockaddr *mask);
+bool sockaddr_equal(const struct sockaddr *ip1,
+ const struct sockaddr *ip2);
+
+bool is_address_any(const struct sockaddr *psa);
+uint16_t get_sockaddr_port(const struct sockaddr_storage *pss);
+char *print_sockaddr_len(char *dest,
+ size_t destlen,
+ const struct sockaddr *psa,
+ socklen_t psalen);
+char *print_sockaddr(char *dest,
+ size_t destlen,
+ const struct sockaddr_storage *psa);
+char *print_canonical_sockaddr(TALLOC_CTX *ctx,
+ const struct sockaddr_storage *pss);
+
+void set_socket_options(int fd, const char *options);
+
+bool sockaddr_storage_to_samba_sockaddr(
+ struct samba_sockaddr *sa, const struct sockaddr_storage *ss);
+bool samba_sockaddr_set_port(struct samba_sockaddr *sa, uint16_t port);
+bool samba_sockaddr_get_port(const struct samba_sockaddr *sa, uint16_t *port);
+
+/*
+ * check for POLLERR or POLL*HUP
+ */
+int samba_socket_poll_error(int fd);
+/*
+ * getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len)
+ */
+int samba_socket_sock_error(int fd);
+/*
+ * check for POLL*HUP and fallback to
+ * getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len)
+ */
+int samba_socket_poll_or_sock_error(int fd);
+
+#endif /* _SAMBA_UTIL_NET_H_ */
diff --git a/lib/util/util_paths.c b/lib/util/util_paths.c
new file mode 100644
index 0000000..ce93028
--- /dev/null
+++ b/lib/util/util_paths.c
@@ -0,0 +1,170 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 2001-2007
+ Copyright (C) Simo Sorce 2001
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+ Copyright (C) James Peach 2006
+ Copyright (c) 2020 Andreas Schneider <asn@samba.org>
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "dynconfig/dynconfig.h"
+#include "lib/util/util_paths.h"
+#include "system/passwd.h"
+#include "system/filesys.h"
+
+/**
+ * @brief Returns an absolute path to a file in the Samba modules directory.
+ *
+ * @param name File to find, relative to MODULESDIR.
+ *
+ * @retval Pointer to a string containing the full path.
+ **/
+
+char *modules_path(TALLOC_CTX *mem_ctx, const char *name)
+{
+ return talloc_asprintf(mem_ctx, "%s/%s", get_dyn_MODULESDIR(), name);
+}
+
+/**
+ * @brief Returns an absolute path to a file in the Samba data directory.
+ *
+ * @param name File to find, relative to CODEPAGEDIR.
+ *
+ * @retval Pointer to a talloc'ed string containing the full path.
+ **/
+
+char *data_path(TALLOC_CTX *mem_ctx, const char *name)
+{
+ return talloc_asprintf(mem_ctx, "%s/%s", get_dyn_CODEPAGEDIR(), name);
+}
+
+/**
+ * @brief Returns the platform specific shared library extension.
+ *
+ * @retval Pointer to a const char * containing the extension.
+ **/
+
+const char *shlib_ext(void)
+{
+ return get_dyn_SHLIBEXT();
+}
+
+static char *get_user_home_dir(TALLOC_CTX *mem_ctx)
+{
+ struct passwd pwd = {0};
+ struct passwd *pwdbuf = NULL;
+ char *buf = NULL;
+ char *out = NULL;
+ long int initlen;
+ size_t len;
+ int rc;
+
+ initlen = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (initlen == -1) {
+ len = 1024;
+ } else {
+ len = (size_t)initlen;
+ }
+ buf = talloc_size(mem_ctx, len);
+ if (buf == NULL) {
+ return NULL;
+ }
+
+ rc = getpwuid_r(getuid(), &pwd, buf, len, &pwdbuf);
+ while (rc == ERANGE) {
+ size_t newlen = 2 * len;
+ if (newlen < len) {
+ /* Overflow */
+ goto done;
+ }
+ len = newlen;
+ buf = talloc_realloc_size(mem_ctx, buf, len);
+ if (buf == NULL) {
+ goto done;
+ }
+ rc = getpwuid_r(getuid(), &pwd, buf, len, &pwdbuf);
+ }
+ if (rc != 0 || pwdbuf == NULL ) {
+ const char *szPath = getenv("HOME");
+ if (szPath == NULL) {
+ goto done;
+ }
+ len = strnlen(szPath, PATH_MAX);
+ if (len >= PATH_MAX) {
+ goto done;
+ }
+ out = talloc_strdup(mem_ctx, szPath);
+ goto done;
+ }
+
+ out = talloc_strdup(mem_ctx, pwd.pw_dir);
+done:
+ TALLOC_FREE(buf);
+ return out;
+}
+
+char *path_expand_tilde(TALLOC_CTX *mem_ctx, const char *d)
+{
+ char *h = NULL, *r = NULL;
+ const char *p = NULL;
+ struct stat sb = {0};
+ int rc;
+
+ if (d[0] != '~') {
+ return talloc_strdup(mem_ctx, d);
+ }
+ d++;
+
+ /* handle ~user/path */
+ p = strchr(d, '/');
+ if (p != NULL && p > d) {
+ struct passwd *pw;
+ size_t s = p - d;
+ char u[128];
+
+ if (s >= sizeof(u)) {
+ return NULL;
+ }
+ memcpy(u, d, s);
+ u[s] = '\0';
+
+ pw = getpwnam(u);
+ if (pw == NULL) {
+ return NULL;
+ }
+ h = talloc_strdup(mem_ctx, pw->pw_dir);
+ } else {
+ p = d;
+ h = get_user_home_dir(mem_ctx);
+ }
+ if (h == NULL) {
+ return NULL;
+ }
+
+ rc = stat(h, &sb);
+ if (rc != 0) {
+ TALLOC_FREE(h);
+ return NULL;
+ }
+
+ r = talloc_asprintf(mem_ctx, "%s%s", h, p);
+ TALLOC_FREE(h);
+
+ return r;
+}
diff --git a/lib/util/util_paths.h b/lib/util/util_paths.h
new file mode 100644
index 0000000..cf34f69
--- /dev/null
+++ b/lib/util/util_paths.h
@@ -0,0 +1,63 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Samba utility functions
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Copyright (C) Jeremy Allison 2001-2007
+ * Copyright (C) Simo Sorce 2001
+ * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+ * Copyright (C) James Peach 2006
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIB_UTIL_PATHS_H__
+#define __LIB_UTIL_PATHS_H__
+
+#include <talloc.h>
+
+/**
+ * @brief Returns an absolute path to a file in the Samba modules directory.
+ *
+ * @param name File to find, relative to MODULESDIR.
+ *
+ * @retval Pointer to a string containing the full path.
+ **/
+char *modules_path(TALLOC_CTX *mem_ctx, const char *name);
+
+/**
+ * @brief Returns an absolute path to a file in the Samba data directory.
+ *
+ * @param name File to find, relative to CODEPAGEDIR.
+ *
+ * @retval Pointer to a talloc'ed string containing the full path.
+ **/
+char *data_path(TALLOC_CTX *mem_ctx, const char *name);
+
+/**
+ * @brief Returns the platform specific shared library extension.
+ *
+ * @retval Pointer to a const char * containing the extension.
+ **/
+const char *shlib_ext(void);
+
+/**
+ * @brief Expand a directory starting with a tilde '~'
+ *
+ * @param[in] d The directory to expand.
+ *
+ * @return The expanded directory, NULL on error.
+ */
+char *path_expand_tilde(TALLOC_CTX *mem_ctx, const char *d);
+
+#endif
diff --git a/lib/util/util_process.c b/lib/util/util_process.c
new file mode 100644
index 0000000..a10b85c
--- /dev/null
+++ b/lib/util/util_process.c
@@ -0,0 +1,101 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Process utils.
+ *
+ * Copyright (c) 2013 Andreas Schneider <asn@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "util_process.h"
+#include "replace.h"
+
+#ifdef HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
+
+/*
+ * These variables are static so that we can access them
+ * with process_get_short_title() and process_get_long_title(). The
+ * purpose of this is to allow smb_panic_log() to print them.
+ */
+static char short_comment[16] = {0,};
+static char long_comment[256] = {0,};
+static char binary_name[256];
+
+void process_set_title(const char *short_format, const char *long_format, ...)
+{
+#if defined(HAVE_PRCTL) && defined(PR_SET_NAME)
+ if (short_format != NULL) {
+ va_list ap;
+
+ va_start(ap, long_format);
+ vsnprintf(short_comment, sizeof(short_comment), short_format, ap);
+ va_end(ap);
+
+ prctl(PR_SET_NAME, (unsigned long) short_comment, 0, 0, 0);
+ }
+#endif
+
+ if (long_format != NULL) {
+ va_list ap;
+
+ va_start(ap, long_format);
+ vsnprintf(long_comment, sizeof(long_comment), long_format, ap);
+ va_end(ap);
+
+ setproctitle("%s", long_comment);
+ }
+}
+
+const char *process_get_short_title(void)
+{
+ return short_comment;
+}
+
+const char *process_get_long_title(void)
+{
+ return long_comment;
+}
+
+/*
+ * This is just for debugging in a panic, so we don't want to do
+ * anything more than return a fixed pointer, so we save a copy to a
+ * static variable.
+ */
+void process_save_binary_name(const char *progname)
+{
+ strlcpy(binary_name, progname, sizeof(binary_name));
+}
+
+/* Samba binaries will set this during popt handling */
+const char *process_get_saved_binary_name(void)
+{
+ return binary_name;
+}
+
+
+int prctl_set_comment(const char *comment_format, ...)
+{
+ char comment[16];
+ va_list ap;
+
+ va_start(ap, comment_format);
+ vsnprintf(comment, sizeof(comment), comment_format, ap);
+ va_end(ap);
+
+ process_set_title("%s", "%s", comment);
+ return 0;
+}
diff --git a/lib/util/util_process.h b/lib/util/util_process.h
new file mode 100644
index 0000000..4da135b
--- /dev/null
+++ b/lib/util/util_process.h
@@ -0,0 +1,84 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Process utils.
+ *
+ * Copyright (c) 2013 Andreas Schneider <asn@samba.org>
+ *
+ * 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 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SAMBA_UTIL_PROCESS_H
+#define _SAMBA_UTIL_PROCESS_H
+
+#include "replace.h"
+
+/**
+ * @brief Set the process comment name.
+ *
+ * @param[in] comment The comment to set which shouldn't be longer than 16
+ * 16 characters (including \0).
+ *
+ * @return -1 on error, 0 on success.
+ */
+int prctl_set_comment(const char *comment_format, ...) PRINTF_ATTRIBUTE(1,2);
+
+/**
+ * @brief Set the process comment name and longname
+ *
+ * @param[in] short_format The comment to set which shouldn't be longer than 16
+ * 16 characters (including \0).
+ * @param[in] long_format The format string and arguments to produce the long
+ * form of the process name.
+ *
+ * @return -1 on error, 0 on success.
+ */
+void process_set_title(const char *short_format, const char *long_format, ...)
+ PRINTF_ATTRIBUTE(1,3) PRINTF_ATTRIBUTE(2,3);
+
+/**
+ * @brief Get the process comment name set from process_set_title()
+ *
+ * @return process comment name
+ */
+const char *process_get_short_title(void);
+
+/**
+ * @brief Get the process longname set from process_set_title()
+ *
+ * @return process longname
+ */
+const char *process_get_long_title(void);
+
+/*
+ * @brief Save the binary name for later printing in smb_panic()
+ *
+ * @param[in] progname The binary name at process startup
+ *
+ * This is just for debugging in a panic, so we don't want to do
+ * anything more than return a fixed pointer, so we save a copy to a
+ * static variable.
+ */
+void process_save_binary_name(const char *progname);
+
+/**
+ * @brief Get the binary name set at startup process_save_binary_name()
+ *
+ * @return binary name set at startup
+ */
+/* Samba binaries will set this during popt handling */
+const char *process_get_saved_binary_name(void);
+
+
+#endif
diff --git a/lib/util/util_pw.c b/lib/util/util_pw.c
new file mode 100644
index 0000000..8035de4
--- /dev/null
+++ b/lib/util/util_pw.c
@@ -0,0 +1,99 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Safe versions of getpw* calls
+
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 1998-2005
+ Copyright (C) Andrew Bartlett 2002
+ Copyright (C) Timur Bakeyev 2005
+ Copyright (C) Bjoern Jacke 2006-2007
+
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include <talloc.h>
+#include "system/passwd.h"
+#include "lib/util/util_pw.h"
+
+struct passwd *tcopy_passwd(TALLOC_CTX *mem_ctx,
+ const struct passwd *from)
+{
+ struct passwd *ret;
+ size_t len = 0;
+
+ len += strlen(from->pw_name)+1;
+ len += strlen(from->pw_passwd)+1;
+ len += strlen(from->pw_gecos)+1;
+ len += strlen(from->pw_dir)+1;
+ len += strlen(from->pw_shell)+1;
+
+ ret = talloc_pooled_object(mem_ctx, struct passwd, 5, len);
+
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ ret->pw_name = talloc_strdup(ret, from->pw_name);
+ ret->pw_passwd = talloc_strdup(ret, from->pw_passwd);
+ ret->pw_uid = from->pw_uid;
+ ret->pw_gid = from->pw_gid;
+ ret->pw_gecos = talloc_strdup(ret, from->pw_gecos);
+ ret->pw_dir = talloc_strdup(ret, from->pw_dir);
+ ret->pw_shell = talloc_strdup(ret, from->pw_shell);
+
+ return ret;
+}
+
+struct passwd *getpwnam_alloc(TALLOC_CTX *mem_ctx, const char *name)
+{
+ struct passwd *temp;
+
+ temp = getpwnam(name);
+
+ if (!temp) {
+#if 0
+ if (errno == ENOMEM) {
+ /* what now? */
+ }
+#endif
+ return NULL;
+ }
+
+ return tcopy_passwd(mem_ctx, temp);
+}
+
+/****************************************************************************
+ talloc'ed version of getpwuid.
+****************************************************************************/
+
+struct passwd *getpwuid_alloc(TALLOC_CTX *mem_ctx, uid_t uid)
+{
+ struct passwd *temp;
+
+ temp = getpwuid(uid);
+
+ if (!temp) {
+#if 0
+ if (errno == ENOMEM) {
+ /* what now? */
+ }
+#endif
+ return NULL;
+ }
+
+ return tcopy_passwd(mem_ctx, temp);
+}
diff --git a/lib/util/util_pw.h b/lib/util/util_pw.h
new file mode 100644
index 0000000..fae4da9
--- /dev/null
+++ b/lib/util/util_pw.h
@@ -0,0 +1,32 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Safe versions of getpw* calls
+
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Jeremy Allison 1997-2001.
+ Copyright (C) Andrew Bartlett 2002
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LIB_UTIL_UTIL_PW_H__
+#define __LIB_UTIL_UTIL_PW_H__
+
+struct passwd *tcopy_passwd(TALLOC_CTX *mem_ctx,
+ const struct passwd *from);
+struct passwd *getpwnam_alloc(TALLOC_CTX *mem_ctx, const char *name);
+struct passwd *getpwuid_alloc(TALLOC_CTX *mem_ctx, uid_t uid);
+
+#endif /* __LIB_UTIL_UTIL_PW_H__ */
diff --git a/lib/util/util_runcmd.c b/lib/util/util_runcmd.c
new file mode 100644
index 0000000..ea2e8ee
--- /dev/null
+++ b/lib/util/util_runcmd.c
@@ -0,0 +1,379 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ run a child command
+
+ Copyright (C) Andrew Tridgell 2010
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+ this runs a child command with stdout and stderr going to the Samba
+ log
+ */
+
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/wait.h"
+#include <tevent.h>
+#include "lib/util/samba_util.h"
+#include "lib/util/debug.h"
+#include "../lib/util/tevent_unix.h"
+#include "../lib/util/tfork.h"
+#include "../lib/util/sys_rw.h"
+
+struct samba_runcmd_state {
+ int stdout_log_level;
+ int stderr_log_level;
+ struct tevent_fd *fde_stdout;
+ struct tevent_fd *fde_stderr;
+ struct tevent_fd *fde_status;
+ int fd_stdin, fd_stdout, fd_stderr, fd_status;
+ char *arg0;
+ pid_t pid;
+ struct tfork *tfork;
+ char buf[1024];
+ uint16_t buf_used;
+};
+
+static void samba_runcmd_cleanup_fn(struct tevent_req *req,
+ enum tevent_req_state req_state)
+{
+ struct samba_runcmd_state *state = tevent_req_data(
+ req, struct samba_runcmd_state);
+
+ if (state->tfork != NULL) {
+ tfork_destroy(&state->tfork);
+ }
+ state->pid = -1;
+
+ if (state->fd_stdin != -1) {
+ close(state->fd_stdin);
+ state->fd_stdin = -1;
+ }
+}
+
+int samba_runcmd_export_stdin(struct tevent_req *req)
+{
+ struct samba_runcmd_state *state = tevent_req_data(req,
+ struct samba_runcmd_state);
+ int ret = state->fd_stdin;
+
+ state->fd_stdin = -1;
+
+ return ret;
+}
+
+static void samba_runcmd_io_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data);
+
+/*
+ run a command as a child process, with a timeout.
+
+ any stdout/stderr from the child will appear in the Samba logs with
+ the specified log levels
+ */
+struct tevent_req *samba_runcmd_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct timeval endtime,
+ int stdout_log_level,
+ int stderr_log_level,
+ const char * const *argv0, ...)
+{
+ struct tevent_req *req;
+ struct samba_runcmd_state *state;
+ int p1[2], p2[2], p3[2];
+ char **argv;
+ va_list ap;
+
+ if (argv0 == NULL) {
+ return NULL;
+ }
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct samba_runcmd_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ state->stdout_log_level = stdout_log_level;
+ state->stderr_log_level = stderr_log_level;
+ state->fd_stdin = -1;
+
+ state->arg0 = talloc_strdup(state, argv0[0]);
+ if (tevent_req_nomem(state->arg0, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ if (pipe(p1) != 0) {
+ tevent_req_error(req, errno);
+ return tevent_req_post(req, ev);
+ }
+ if (pipe(p2) != 0) {
+ close(p1[0]);
+ close(p1[1]);
+ tevent_req_error(req, errno);
+ return tevent_req_post(req, ev);
+ }
+ if (pipe(p3) != 0) {
+ close(p1[0]);
+ close(p1[1]);
+ close(p2[0]);
+ close(p2[1]);
+ tevent_req_error(req, errno);
+ return tevent_req_post(req, ev);
+ }
+
+ state->tfork = tfork_create();
+ if (state->tfork == NULL) {
+ close(p1[0]);
+ close(p1[1]);
+ close(p2[0]);
+ close(p2[1]);
+ close(p3[0]);
+ close(p3[1]);
+ tevent_req_error(req, errno);
+ return tevent_req_post(req, ev);
+ }
+ state->pid = tfork_child_pid(state->tfork);
+ if (state->pid != 0) {
+ /* the parent */
+ close(p1[1]);
+ close(p2[1]);
+ close(p3[0]);
+ state->fd_stdout = p1[0];
+ state->fd_stderr = p2[0];
+ state->fd_stdin = p3[1];
+ state->fd_status = tfork_event_fd(state->tfork);
+
+ set_blocking(state->fd_stdout, false);
+ set_blocking(state->fd_stderr, false);
+ set_blocking(state->fd_stdin, false);
+ set_blocking(state->fd_status, false);
+
+ smb_set_close_on_exec(state->fd_stdin);
+ smb_set_close_on_exec(state->fd_stdout);
+ smb_set_close_on_exec(state->fd_stderr);
+ smb_set_close_on_exec(state->fd_status);
+
+ tevent_req_set_cleanup_fn(req, samba_runcmd_cleanup_fn);
+
+ state->fde_stdout = tevent_add_fd(ev, state,
+ state->fd_stdout,
+ TEVENT_FD_READ,
+ samba_runcmd_io_handler,
+ req);
+ if (tevent_req_nomem(state->fde_stdout, req)) {
+ close(state->fd_stdout);
+ close(state->fd_stderr);
+ close(state->fd_status);
+ return tevent_req_post(req, ev);
+ }
+ tevent_fd_set_auto_close(state->fde_stdout);
+
+ state->fde_stderr = tevent_add_fd(ev, state,
+ state->fd_stderr,
+ TEVENT_FD_READ,
+ samba_runcmd_io_handler,
+ req);
+ if (tevent_req_nomem(state->fde_stdout, req)) {
+ close(state->fd_stdout);
+ close(state->fd_stderr);
+ close(state->fd_status);
+ return tevent_req_post(req, ev);
+ }
+ tevent_fd_set_auto_close(state->fde_stderr);
+
+ state->fde_status = tevent_add_fd(ev, state,
+ state->fd_status,
+ TEVENT_FD_READ,
+ samba_runcmd_io_handler,
+ req);
+ if (tevent_req_nomem(state->fde_stdout, req)) {
+ close(state->fd_stdout);
+ close(state->fd_stderr);
+ close(state->fd_status);
+ return tevent_req_post(req, ev);
+ }
+ tevent_fd_set_auto_close(state->fde_status);
+
+ if (!timeval_is_zero(&endtime)) {
+ tevent_req_set_endtime(req, ev, endtime);
+ }
+
+ return req;
+ }
+
+ /* the child */
+ close(p1[0]);
+ close(p2[0]);
+ close(p3[1]);
+ close(0);
+ close(1);
+ close(2);
+
+ /* we want to ensure that all of the network sockets we had
+ open are closed */
+ tevent_re_initialise(ev);
+
+ /* setup for logging to go to the parents debug log */
+ dup2(p3[0], 0);
+ dup2(p1[1], 1);
+ dup2(p2[1], 2);
+
+ close(p1[1]);
+ close(p2[1]);
+ close(p3[0]);
+
+ argv = str_list_copy(state, discard_const_p(const char *, argv0));
+ if (!argv) {
+ fprintf(stderr, "Out of memory in child\n");
+ _exit(255);
+ }
+
+ va_start(ap, argv0);
+ while (1) {
+ const char **l;
+ char *arg = va_arg(ap, char *);
+ if (arg == NULL) break;
+ l = discard_const_p(const char *, argv);
+ l = str_list_add(l, arg);
+ if (l == NULL) {
+ fprintf(stderr, "Out of memory in child\n");
+ _exit(255);
+ }
+ argv = discard_const_p(char *, l);
+ }
+ va_end(ap);
+
+ (void)execvp(state->arg0, argv);
+ fprintf(stderr, "Failed to exec child - %s\n", strerror(errno));
+ _exit(255);
+ return NULL;
+}
+
+/*
+ handle stdout/stderr from the child
+ */
+static void samba_runcmd_io_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data)
+{
+ struct tevent_req *req = talloc_get_type_abort(private_data,
+ struct tevent_req);
+ struct samba_runcmd_state *state = tevent_req_data(req,
+ struct samba_runcmd_state);
+ int level;
+ char *p;
+ int n, fd;
+
+ if (!(flags & TEVENT_FD_READ)) {
+ return;
+ }
+
+ if (fde == state->fde_stdout) {
+ level = state->stdout_log_level;
+ fd = state->fd_stdout;
+ } else if (fde == state->fde_stderr) {
+ level = state->stderr_log_level;
+ fd = state->fd_stderr;
+ } else {
+ int status;
+
+ status = tfork_status(&state->tfork, false);
+ if (status == -1) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ return;
+ }
+ DBG_ERR("Bad read on status pipe\n");
+ tevent_req_error(req, errno);
+ return;
+ }
+ state->pid = -1;
+ TALLOC_FREE(fde);
+
+ if (WIFEXITED(status)) {
+ status = WEXITSTATUS(status);
+ } else if (WIFSIGNALED(status)) {
+ status = WTERMSIG(status);
+ } else {
+ status = ECHILD;
+ }
+
+ DBG_NOTICE("Child %s exited %d\n", state->arg0, status);
+ if (status != 0) {
+ tevent_req_error(req, status);
+ return;
+ }
+
+ tevent_req_done(req);
+ return;
+ }
+
+ n = read(fd, &state->buf[state->buf_used],
+ sizeof(state->buf) - state->buf_used);
+ if (n > 0) {
+ state->buf_used += n;
+ } else if (n == 0) {
+ if (fde == state->fde_stdout) {
+ talloc_free(fde);
+ state->fde_stdout = NULL;
+ return;
+ }
+ if (fde == state->fde_stderr) {
+ talloc_free(fde);
+ state->fde_stderr = NULL;
+ return;
+ }
+ return;
+ }
+
+ while (state->buf_used > 0 &&
+ (p = (char *)memchr(state->buf, '\n', state->buf_used)) != NULL) {
+ int n1 = (p - state->buf)+1;
+ int n2 = n1 - 1;
+ /* swallow \r from child processes */
+ if (n2 > 0 && state->buf[n2-1] == '\r') {
+ n2--;
+ }
+ DEBUG(level,("%s: %*.*s\n", state->arg0, n2, n2, state->buf));
+ memmove(state->buf, p+1, sizeof(state->buf) - n1);
+ state->buf_used -= n1;
+ }
+
+ /* the buffer could have completely filled - unfortunately we have
+ no choice but to dump it out straight away */
+ if (state->buf_used == sizeof(state->buf)) {
+ DEBUG(level,("%s: %*.*s\n",
+ state->arg0, state->buf_used,
+ state->buf_used, state->buf));
+ state->buf_used = 0;
+ }
+}
+
+int samba_runcmd_recv(struct tevent_req *req, int *perrno)
+{
+ if (tevent_req_is_unix_error(req, perrno)) {
+ tevent_req_received(req);
+ return -1;
+ }
+
+ tevent_req_received(req);
+ return 0;
+}
diff --git a/lib/util/util_str.c b/lib/util/util_str.c
new file mode 100644
index 0000000..7c1d15d
--- /dev/null
+++ b/lib/util/util_str.c
@@ -0,0 +1,307 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+
+ Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) Simo Sorce 2001-2002
+ Copyright (C) Martin Pool 2003
+ Copyright (C) James Peach 2005
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "lib/util/samba_util.h"
+#include "system/locale.h"
+#include "smb_strtox.h"
+#undef strncasecmp
+#undef strcasemp
+
+/**
+ * @file
+ * @brief String utilities.
+ **/
+
+/**
+ * Parse a string containing a boolean value.
+ *
+ * val will be set to the read value.
+ *
+ * @retval true if a boolean value was parsed, false otherwise.
+ */
+_PUBLIC_ bool conv_str_bool(const char * str, bool * val)
+{
+ char * end = NULL;
+ long lval;
+
+ if (str == NULL || *str == '\0') {
+ return false;
+ }
+
+ lval = strtol(str, &end, 10 /* base */);
+ if (end == NULL || *end != '\0' || end == str) {
+ return set_boolean(str, val);
+ }
+
+ *val = (lval) ? true : false;
+ return true;
+}
+
+/**
+ * Convert a size specification like 16K into an integral number of bytes.
+ **/
+_PUBLIC_ bool conv_str_size_error(const char * str, uint64_t * val)
+{
+ char * end = NULL;
+ unsigned long long lval;
+ int error = 0;
+
+ if (str == NULL || *str == '\0') {
+ return false;
+ }
+
+ lval = smb_strtoull(str, &end, 10, &error, SMB_STR_STANDARD);
+ if (error != 0) {
+ return false;
+ }
+
+ if (*end) {
+ if (strwicmp(end, "K") == 0) {
+ lval *= 1024ULL;
+ } else if (strwicmp(end, "M") == 0) {
+ lval *= (1024ULL * 1024ULL);
+ } else if (strwicmp(end, "G") == 0) {
+ lval *= (1024ULL * 1024ULL * 1024ULL);
+ } else if (strwicmp(end, "T") == 0) {
+ lval *= (1024ULL * 1024ULL * 1024ULL * 1024ULL);
+ } else if (strwicmp(end, "P") == 0) {
+ lval *= (1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL);
+ } else {
+ return false;
+ }
+ }
+
+ *val = (uint64_t)lval;
+ return true;
+}
+
+/**
+ * Parse a uint64_t value from a string
+ *
+ * val will be set to the value read.
+ *
+ * @retval true if parsing was successful, false otherwise
+ */
+_PUBLIC_ bool conv_str_u64(const char * str, uint64_t * val)
+{
+ unsigned long long lval;
+ int error = 0;
+
+ if (str == NULL || *str == '\0') {
+ return false;
+ }
+
+ lval = smb_strtoull(str, NULL, 10, &error, SMB_STR_FULL_STR_CONV);
+ if (error != 0) {
+ return false;
+ }
+
+ *val = (uint64_t)lval;
+ return true;
+}
+
+/**
+ * Compare 2 strings.
+ *
+ * @note The comparison is case-insensitive.
+ **/
+_PUBLIC_ bool strequal(const char *s1, const char *s2)
+{
+ if (s1 == s2)
+ return true;
+ if (!s1 || !s2)
+ return false;
+
+ return strcasecmp_m(s1,s2) == 0;
+}
+
+/**
+ * @file
+ * @brief String utilities.
+ **/
+
+static bool next_token_internal_talloc(TALLOC_CTX *ctx,
+ const char **ptr,
+ char **pp_buff,
+ const char *sep,
+ bool ltrim)
+{
+ const char *s;
+ const char *saved_s;
+ char *pbuf;
+ bool quoted;
+ size_t len=1;
+
+ *pp_buff = NULL;
+ if (!ptr) {
+ return(false);
+ }
+
+ s = *ptr;
+
+ /* default to simple separators */
+ if (!sep) {
+ sep = " \t\n\r";
+ }
+
+ /* find the first non sep char, if left-trimming is requested */
+ if (ltrim) {
+ while (*s && strchr_m(sep,*s)) {
+ s++;
+ }
+ }
+
+ /* nothing left? */
+ if (!*s) {
+ return false;
+ }
+
+ /* When restarting we need to go from here. */
+ saved_s = s;
+
+ /* Work out the length needed. */
+ for (quoted = false; *s &&
+ (quoted || !strchr_m(sep,*s)); s++) {
+ if (*s == '\"') {
+ quoted = !quoted;
+ } else {
+ len++;
+ }
+ }
+
+ /* We started with len = 1 so we have space for the nul. */
+ *pp_buff = talloc_array(ctx, char, len);
+ if (!*pp_buff) {
+ return false;
+ }
+
+ /* copy over the token */
+ pbuf = *pp_buff;
+ s = saved_s;
+ for (quoted = false; *s &&
+ (quoted || !strchr_m(sep,*s)); s++) {
+ if ( *s == '\"' ) {
+ quoted = !quoted;
+ } else {
+ *pbuf++ = *s;
+ }
+ }
+
+ *ptr = (*s) ? s+1 : s;
+ *pbuf = 0;
+
+ return true;
+}
+
+bool next_token_talloc(TALLOC_CTX *ctx,
+ const char **ptr,
+ char **pp_buff,
+ const char *sep)
+{
+ return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
+}
+
+/*
+ * Get the next token from a string, return false if none found. Handles
+ * double-quotes. This version does not trim leading separator characters
+ * before looking for a token.
+ */
+
+bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
+ const char **ptr,
+ char **pp_buff,
+ const char *sep)
+{
+ return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
+}
+
+/**
+ * Get the next token from a string, return False if none found.
+ * Handles double-quotes.
+ *
+ * Based on a routine by GJC@VILLAGE.COM.
+ * Extensively modified by Andrew.Tridgell@anu.edu.au
+ **/
+_PUBLIC_ bool next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
+{
+ const char *s;
+ bool quoted;
+ size_t len=1;
+
+ if (!ptr)
+ return false;
+
+ s = *ptr;
+
+ /* default to simple separators */
+ if (!sep)
+ sep = " \t\n\r";
+
+ /* find the first non sep char */
+ while (*s && strchr_m(sep,*s))
+ s++;
+
+ /* nothing left? */
+ if (!*s)
+ return false;
+
+ /* copy over the token */
+ for (quoted = false; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
+ if (*s == '\"') {
+ quoted = !quoted;
+ } else {
+ len++;
+ *buff++ = *s;
+ }
+ }
+
+ *ptr = (*s) ? s+1 : s;
+ *buff = 0;
+
+ return true;
+}
+
+/**
+ Set a boolean variable from the text value stored in the passed string.
+ Returns true in success, false if the passed string does not correctly
+ represent a boolean.
+**/
+
+_PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean)
+{
+ if (strwicmp(boolean_string, "yes") == 0 ||
+ strwicmp(boolean_string, "true") == 0 ||
+ strwicmp(boolean_string, "on") == 0 ||
+ strwicmp(boolean_string, "1") == 0) {
+ *boolean = true;
+ return true;
+ } else if (strwicmp(boolean_string, "no") == 0 ||
+ strwicmp(boolean_string, "false") == 0 ||
+ strwicmp(boolean_string, "off") == 0 ||
+ strwicmp(boolean_string, "0") == 0) {
+ *boolean = false;
+ return true;
+ }
+ return false;
+}
diff --git a/lib/util/util_str_common.c b/lib/util/util_str_common.c
new file mode 100644
index 0000000..bf66647
--- /dev/null
+++ b/lib/util/util_str_common.c
@@ -0,0 +1,154 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+
+ Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) Simo Sorce 2001-2002
+ Copyright (C) Martin Pool 2003
+ Copyright (C) James Peach 2005
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/locale.h"
+#include "lib/util/samba_util.h"
+
+/**
+Do a case-insensitive, whitespace-ignoring ASCII string compare.
+**/
+_PUBLIC_ int strwicmp(const char *psz1, const char *psz2)
+{
+ /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
+ /* appropriate value. */
+ if (psz1 == psz2)
+ return (0);
+ else if (psz1 == NULL)
+ return (-1);
+ else if (psz2 == NULL)
+ return (1);
+
+ /* sync the strings on first non-whitespace */
+ while (1) {
+ while (isspace((int)*psz1))
+ psz1++;
+ while (isspace((int)*psz2))
+ psz2++;
+
+ /*
+ * This does not do a genuine multi-byte comparison,
+ * instead it just uses the fast-path for ASCII in
+ * these common routines
+ */
+ if (toupper_m((unsigned char)*psz1) != toupper_m((unsigned char)*psz2)
+ || *psz1 == '\0'
+ || *psz2 == '\0')
+ break;
+ psz1++;
+ psz2++;
+ }
+ return (*psz1 - *psz2);
+}
+
+/**
+ String replace.
+ NOTE: oldc and newc must be 7 bit characters
+**/
+void string_replace( char *s, char oldc, char newc )
+{
+ while (*s != '\0') {
+ size_t c_size;
+ next_codepoint(s, &c_size);
+
+ if (c_size == 1) {
+ if (*s == oldc) {
+ *s = newc;
+ }
+ }
+ s += c_size;
+ }
+}
+
+
+/**
+ Paranoid strcpy into a buffer of given length (includes terminating
+ zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
+ and replaces with '_'. Deliberately does *NOT* check for multibyte
+ characters. Treats src as an array of bytes, not as a multibyte
+ string. Any byte >0x7f is automatically converted to '_'.
+ other_safe_chars must also contain an ascii string (bytes<0x7f).
+**/
+
+char *alpha_strcpy(char *dest,
+ const char *src,
+ const char *other_safe_chars,
+ size_t maxlength)
+{
+ size_t len, i;
+
+ if (!dest) {
+ smb_panic("ERROR: NULL dest in alpha_strcpy");
+ }
+
+ if (!src) {
+ *dest = 0;
+ return dest;
+ }
+
+ len = strlen(src);
+ if (len >= maxlength)
+ len = maxlength - 1;
+
+ if (!other_safe_chars)
+ other_safe_chars = "";
+
+ for(i = 0; i < len; i++) {
+ int val = (src[i] & 0xff);
+ if (val > 0x7f) {
+ dest[i] = '_';
+ continue;
+ }
+ if (isupper(val) || islower(val) ||
+ isdigit(val) || strchr(other_safe_chars, val))
+ dest[i] = src[i];
+ else
+ dest[i] = '_';
+ }
+
+ dest[i] = '\0';
+
+ return dest;
+}
+
+char *talloc_alpha_strcpy(TALLOC_CTX *mem_ctx,
+ const char *src,
+ const char *other_safe_chars)
+{
+ char *dest = NULL;
+ size_t slen;
+
+ if (src == NULL) {
+ return NULL;
+ }
+
+ slen = strlen(src);
+
+ dest = talloc_zero_size(mem_ctx, slen + 1);
+ if (dest == NULL) {
+ return NULL;
+ }
+
+ alpha_strcpy(dest, src, other_safe_chars, slen + 1);
+ return dest;
+}
diff --git a/lib/util/util_str_escape.c b/lib/util/util_str_escape.c
new file mode 100644
index 0000000..750d64b
--- /dev/null
+++ b/lib/util/util_str_escape.c
@@ -0,0 +1,127 @@
+/*
+ Samba string escaping routines
+
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "lib/util/debug.h"
+#include "lib/util/util_str_escape.h"
+
+
+/*
+ * Calculate the encoded length of a character for log_escape
+ *
+ */
+static size_t encoded_length(char c)
+{
+ if (c != '\\' && c > 0x1F) {
+ return 1;
+ } else {
+ switch (c) {
+ case '\a':
+ case '\b':
+ case '\f':
+ case '\n':
+ case '\r':
+ case '\t':
+ case '\v':
+ case '\\':
+ return 2; /* C escape sequence */
+ default:
+ return 4; /* hex escape \xhh */
+ }
+ }
+}
+
+/*
+ * Escape any control characters in the inputs to prevent them from
+ * interfering with the log output.
+ */
+char *log_escape(TALLOC_CTX *frame, const char *in)
+{
+ size_t size = 0; /* Space to allocate for the escaped data */
+ char *encoded = NULL; /* The encoded string */
+ const char *c;
+ char *e;
+
+ if (in == NULL) {
+ return NULL;
+ }
+
+ /* Calculate the size required for the escaped array */
+ c = in;
+ while (*c) {
+ size += encoded_length( *c);
+ c++;
+ }
+ size++;
+
+ encoded = talloc_array( frame, char, size);
+ if (encoded == NULL) {
+ DBG_ERR( "Out of memory allocating encoded string\n");
+ return NULL;
+ }
+
+ c = in;
+ e = encoded;
+ while (*c) {
+ if (*c != '\\' && *c > 0x1F) {
+ *e++ = *c++;
+ } else {
+ switch (*c) {
+ case '\a':
+ *e++ = '\\';
+ *e++ = 'a';
+ break;
+ case '\b':
+ *e++ = '\\';
+ *e++ = 'b';
+ break;
+ case '\f':
+ *e++ = '\\';
+ *e++ = 'f';
+ break;
+ case '\n':
+ *e++ = '\\';
+ *e++ = 'n';
+ break;
+ case '\r':
+ *e++ = '\\';
+ *e++ = 'r';
+ break;
+ case '\t':
+ *e++ = '\\';
+ *e++ = 't';
+ break;
+ case '\v':
+ *e++ = '\\';
+ *e++ = 'v';
+ break;
+ case '\\':
+ *e++ = '\\';
+ *e++ = '\\';
+ break;
+ default:
+ snprintf(e, 5, "\\x%02X", *c);
+ e += 4;
+ }
+ c++;
+ }
+ }
+ *e = '\0';
+ return encoded;
+}
diff --git a/lib/util/util_str_escape.h b/lib/util/util_str_escape.h
new file mode 100644
index 0000000..0b4c596
--- /dev/null
+++ b/lib/util/util_str_escape.h
@@ -0,0 +1,27 @@
+/*
+ Samba string escaping routines
+
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_UTIL_STR_ESCAPE_H
+#define _SAMBA_UTIL_STR_ESCAPE_H
+
+#include <talloc.h>
+
+char *log_escape(TALLOC_CTX *frame, const char *in);
+
+#endif
diff --git a/lib/util/util_str_hex.c b/lib/util/util_str_hex.c
new file mode 100644
index 0000000..553fb30
--- /dev/null
+++ b/lib/util/util_str_hex.c
@@ -0,0 +1,69 @@
+#include "replace.h"
+#include "util_str_hex.h"
+#include "lib/util/data_blob.h"
+#include "librpc/gen_ndr/misc.h"
+
+static bool hex_uint16(const char *in, uint16_t *out)
+{
+ uint8_t hi=0, lo=0;
+ bool ok = hex_byte(in, &hi) && hex_byte(in+2, &lo);
+ *out = (((uint16_t)hi)<<8) + lo;
+ return ok;
+}
+
+bool hex_uint32(const char *in, uint32_t *out)
+{
+ uint16_t hi=0, lo=0;
+ bool ok = hex_uint16(in, &hi) && hex_uint16(in+4, &lo);
+ *out = (((uint32_t)hi)<<16) + lo;
+ return ok;
+}
+
+bool parse_guid_string(const char *s, struct GUID *guid)
+{
+ bool ok;
+ int i;
+ /* "e12b56b6-0a95-11d1-adbb-00c04fd8d5cd"
+ | | | | |
+ | | | | \ node[6]
+ | | | \_____ clock_seq[2]
+ | | \__________ time_hi_and_version
+ | \_______________ time_mid
+ \_____________________ time_low
+ */
+
+ ok = hex_uint32(s, &guid->time_low);
+ if (!ok || (s[8] != '-')) {
+ return false;
+ }
+ s += 9;
+
+ ok = hex_uint16(s, &guid->time_mid);
+ if (!ok || (s[4] != '-')) {
+ return false;
+ }
+ s += 5;
+
+ ok = hex_uint16(s, &guid->time_hi_and_version);
+ if (!ok || (s[4] != '-')) {
+ return false;
+ }
+ s += 5;
+
+ ok = hex_byte(s, &guid->clock_seq[0]) &&
+ hex_byte(s+2, &guid->clock_seq[1]);
+ if (!ok || (s[4] != '-')) {
+ return false;
+ }
+ s += 5;
+
+ for (i = 0; i < 6; i++) {
+ ok = hex_byte(s, &guid->node[i]);
+ if (!ok) {
+ return false;
+ }
+ s += 2;
+ }
+
+ return true;
+}
diff --git a/lib/util/util_str_hex.h b/lib/util/util_str_hex.h
new file mode 100644
index 0000000..7dd527f
--- /dev/null
+++ b/lib/util/util_str_hex.h
@@ -0,0 +1,5 @@
+#include "replace.h"
+
+bool hex_uint32(const char *in, uint32_t *out);
+struct GUID;
+bool parse_guid_string(const char *s, struct GUID *guid);
diff --git a/lib/util/util_strlist.c b/lib/util/util_strlist.c
new file mode 100644
index 0000000..e102002
--- /dev/null
+++ b/lib/util/util_strlist.c
@@ -0,0 +1,561 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Andrew Tridgell 2005
+ Copyright (C) Jelmer Vernooij 2005
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "debug.h"
+#include "tsort.h"
+
+#include "util_strlist.h"
+
+#undef strcasecmp
+
+/**
+ * @file
+ * @brief String list manipulation
+ */
+
+/**
+ build an empty (only NULL terminated) list of strings (for expansion with str_list_add() etc)
+*/
+_PUBLIC_ char **str_list_make_empty(TALLOC_CTX *mem_ctx)
+{
+ char **ret = talloc_zero_array(mem_ctx, char *, 1);
+ return ret;
+}
+
+/**
+ place the only element 'entry' into a new, NULL terminated string list
+*/
+_PUBLIC_ char **str_list_make_single(TALLOC_CTX *mem_ctx, const char *entry)
+{
+ char **ret = NULL;
+
+ ret = talloc_array(mem_ctx, char *, 2);
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ ret[0] = talloc_strdup(ret, entry);
+ if (!ret[0]) {
+ talloc_free(ret);
+ return NULL;
+ }
+ ret[1] = NULL;
+
+ return ret;
+}
+
+/**
+ build a null terminated list of strings from a input string and a
+ separator list. The separator list must contain characters less than
+ or equal to 0x2f for this to work correctly on multi-byte strings
+*/
+_PUBLIC_ char **str_list_make(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
+{
+ int num_elements = 0;
+ char **ret = NULL;
+
+ if (sep == NULL) {
+ sep = LIST_SEP;
+ }
+
+ ret = talloc_array(mem_ctx, char *, 1);
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ while (string && *string) {
+ size_t len = strcspn(string, sep);
+ char **ret2;
+
+ if (len == 0) {
+ string += strspn(string, sep);
+ continue;
+ }
+
+ ret2 = talloc_realloc(mem_ctx, ret, char *,
+ num_elements+2);
+ if (ret2 == NULL) {
+ talloc_free(ret);
+ return NULL;
+ }
+ ret = ret2;
+
+ ret[num_elements] = talloc_strndup(ret, string, len);
+ if (ret[num_elements] == NULL) {
+ talloc_free(ret);
+ return NULL;
+ }
+
+ num_elements++;
+ string += len;
+ }
+
+ ret[num_elements] = NULL;
+
+ return ret;
+}
+
+/**
+ * build a null terminated list of strings from an argv-like input string
+ * Entries are separated by spaces and can be enclosed by quotes.
+ * Does NOT support escaping
+ */
+_PUBLIC_ char **str_list_make_shell(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
+{
+ int num_elements = 0;
+ char **ret = NULL;
+
+ ret = talloc_array(mem_ctx, char *, 1);
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ if (sep == NULL)
+ sep = " \t\n\r";
+
+ while (string && *string) {
+ size_t len = strcspn(string, sep);
+ char *element;
+ char **ret2;
+
+ if (len == 0) {
+ string += strspn(string, sep);
+ continue;
+ }
+
+ if (*string == '\"') {
+ string++;
+ len = strcspn(string, "\"");
+ element = talloc_strndup(ret, string, len);
+ string += len + 1;
+ } else {
+ element = talloc_strndup(ret, string, len);
+ string += len;
+ }
+
+ if (element == NULL) {
+ talloc_free(ret);
+ return NULL;
+ }
+
+ ret2 = talloc_realloc(mem_ctx, ret, char *, num_elements+2);
+ if (ret2 == NULL) {
+ talloc_free(ret);
+ return NULL;
+ }
+ ret = ret2;
+
+ ret[num_elements] = element;
+
+ num_elements++;
+ }
+
+ ret[num_elements] = NULL;
+
+ return ret;
+
+}
+
+/**
+ * join a list back to one string
+ */
+_PUBLIC_ char *str_list_join(TALLOC_CTX *mem_ctx, const char **list, char separator)
+{
+ char *ret = NULL;
+ int i;
+
+ if (list[0] == NULL)
+ return talloc_strdup(mem_ctx, "");
+
+ ret = talloc_strdup(mem_ctx, list[0]);
+
+ for (i = 1; list[i]; i++) {
+ talloc_asprintf_addbuf(&ret, "%c%s", separator, list[i]);
+ }
+
+ return ret;
+}
+
+/** join a list back to one (shell-like) string; entries
+ * separated by spaces, using quotes where necessary */
+_PUBLIC_ char *str_list_join_shell(TALLOC_CTX *mem_ctx, const char **list, char sep)
+{
+ char *ret = NULL;
+ int i;
+
+ if (list[0] == NULL)
+ return talloc_strdup(mem_ctx, "");
+
+ if (strchr(list[0], ' ') || strlen(list[0]) == 0)
+ ret = talloc_asprintf(mem_ctx, "\"%s\"", list[0]);
+ else
+ ret = talloc_strdup(mem_ctx, list[0]);
+
+ for (i = 1; list[i]; i++) {
+ if (strchr(list[i], ' ') || strlen(list[i]) == 0) {
+ talloc_asprintf_addbuf(&ret, "%c\"%s\"", sep, list[i]);
+ } else {
+ talloc_asprintf_addbuf(&ret, "%c%s", sep, list[i]);
+ }
+ }
+
+ return ret;
+}
+
+/**
+ return the number of elements in a string list
+*/
+_PUBLIC_ size_t str_list_length(const char * const *list)
+{
+ size_t ret;
+ for (ret=0;list && list[ret];ret++) /* noop */ ;
+ return ret;
+}
+
+
+/**
+ copy a string list
+*/
+_PUBLIC_ char **str_list_copy(TALLOC_CTX *mem_ctx, const char **list)
+{
+ int i;
+ char **ret;
+
+ if (list == NULL)
+ return NULL;
+
+ ret = talloc_array(mem_ctx, char *, str_list_length(list)+1);
+ if (ret == NULL)
+ return NULL;
+
+ for (i=0;list && list[i];i++) {
+ ret[i] = talloc_strdup(ret, list[i]);
+ if (ret[i] == NULL) {
+ talloc_free(ret);
+ return NULL;
+ }
+ }
+ ret[i] = NULL;
+ return ret;
+}
+
+/**
+ Return true if all the elements of the list match exactly.
+ */
+_PUBLIC_ bool str_list_equal(const char * const *list1,
+ const char * const *list2)
+{
+ int i;
+
+ if (list1 == NULL || list2 == NULL) {
+ return (list1 == list2);
+ }
+
+ for (i=0;list1[i] && list2[i];i++) {
+ if (strcmp(list1[i], list2[i]) != 0) {
+ return false;
+ }
+ }
+ if (list1[i] || list2[i]) {
+ return false;
+ }
+ return true;
+}
+
+
+/**
+ add an entry to a string list
+*/
+_PUBLIC_ const char **str_list_add(const char **list, const char *s)
+{
+ size_t len = str_list_length(list);
+ const char **ret;
+
+ ret = talloc_realloc(NULL, list, const char *, len+2);
+ if (ret == NULL) return NULL;
+
+ ret[len] = talloc_strdup(ret, s);
+ if (ret[len] == NULL) return NULL;
+
+ ret[len+1] = NULL;
+
+ return ret;
+}
+
+/**
+ * @brief Extend a talloc'ed string list with a printf'ed string
+ *
+ * str_list_add_printf() does nothing if *plist is NULL and it sets
+ * *plist to NULL on failure. It is designed to avoid intermediate
+ * NULL checks:
+ *
+ * argv = str_list_make_empty(ctx);
+ * str_list_add_printf(&argv, "smbstatus");
+ * str_list_add_printf(&argv, "--configfile=%s", config);
+ * if (argv == NULL) {
+ * goto nomem;
+ * }
+ *
+ * @param[in,out] plist The talloc'ed list to extend
+ * @param[in] fmt The format string
+ */
+void str_list_add_printf(char ***plist, const char *fmt, ...)
+{
+ char **list = *plist;
+ size_t len;
+ char **tmp = NULL;
+ va_list ap;
+
+ if (list == NULL) {
+ return;
+ }
+ len = str_list_length((const char * const *)list);
+
+ tmp = talloc_realloc(NULL, list, char *, len+2);
+ if (tmp == NULL) {
+ goto fail;
+ }
+ list = tmp;
+ list[len+1] = NULL;
+
+ va_start(ap, fmt);
+ list[len] = talloc_vasprintf(list, fmt, ap);
+ va_end(ap);
+
+ if (list[len] == NULL) {
+ goto fail;
+ }
+ *plist = list;
+
+ return;
+fail:
+ TALLOC_FREE(list);
+ *plist = NULL;
+}
+
+/**
+ remove an entry from a string list
+*/
+_PUBLIC_ void str_list_remove(const char **list, const char *s)
+{
+ int i;
+
+ for (i=0;list[i];i++) {
+ if (strcmp(list[i], s) == 0) break;
+ }
+ if (!list[i]) return;
+
+ for (;list[i];i++) {
+ list[i] = list[i+1];
+ }
+}
+
+
+/**
+ return true if a string is in a list
+*/
+_PUBLIC_ bool str_list_check(const char **list, const char *s)
+{
+ int i;
+
+ for (i=0; list != NULL && list[i] != NULL; i++) {
+ if (strcmp(list[i], s) == 0) return true;
+ }
+ return false;
+}
+
+/**
+ return true if a string is in a list, case insensitively
+*/
+_PUBLIC_ bool str_list_check_ci(const char **list, const char *s)
+{
+ int i;
+
+ for (i=0; list != NULL && list[i] != NULL; i++) {
+ if (strcasecmp(list[i], s) == 0) return true;
+ }
+ return false;
+}
+
+
+/**
+ append one list to another - expanding list1
+*/
+_PUBLIC_ const char **str_list_append(const char **list1,
+ const char * const *list2)
+{
+ size_t len1 = str_list_length(list1);
+ size_t len2 = str_list_length(list2);
+ const char **ret;
+ size_t i;
+
+ ret = talloc_realloc(NULL, list1, const char *, len1+len2+1);
+ if (ret == NULL) return NULL;
+
+ for (i=len1;i<len1+len2;i++) {
+ ret[i] = talloc_strdup(ret, list2[i-len1]);
+ if (ret[i] == NULL) {
+ return NULL;
+ }
+ }
+ ret[i] = NULL;
+
+ return ret;
+}
+
+static int list_cmp(const char **el1, const char **el2)
+{
+ return strcmp(*el1, *el2);
+}
+
+/*
+ return a list that only contains the unique elements of a list,
+ removing any duplicates
+ */
+_PUBLIC_ const char **str_list_unique(const char **list)
+{
+ size_t len = str_list_length(list);
+ const char **list2;
+ size_t i, j;
+ if (len < 2) {
+ return list;
+ }
+ list2 = (const char **)talloc_memdup(list, list,
+ sizeof(list[0])*(len+1));
+ TYPESAFE_QSORT(list2, len, list_cmp);
+ list[0] = list2[0];
+ for (i=j=1;i<len;i++) {
+ if (strcmp(list2[i], list[j-1]) != 0) {
+ list[j] = list2[i];
+ j++;
+ }
+ }
+ list[j] = NULL;
+ list = talloc_realloc(NULL, list, const char *, j + 1);
+ talloc_free(list2);
+ return list;
+}
+
+/*
+ very useful when debugging complex list related code
+ */
+_PUBLIC_ void str_list_show(const char **list)
+{
+ int i;
+ DEBUG(0,("{ "));
+ for (i=0;list && list[i];i++) {
+ DEBUG(0,("\"%s\", ", list[i]));
+ }
+ DEBUG(0,("}\n"));
+}
+
+
+
+/**
+ append one list to another - expanding list1
+ this assumes the elements of list2 are const pointers, so we can re-use them
+*/
+_PUBLIC_ const char **str_list_append_const(const char **list1,
+ const char **list2)
+{
+ size_t len1 = str_list_length(list1);
+ size_t len2 = str_list_length(list2);
+ const char **ret;
+ size_t i;
+
+ ret = talloc_realloc(NULL, list1, const char *, len1+len2+1);
+ if (ret == NULL) return NULL;
+
+ for (i=len1;i<len1+len2;i++) {
+ ret[i] = list2[i-len1];
+ }
+ ret[i] = NULL;
+
+ return ret;
+}
+
+/**
+ * Add a string to an array of strings.
+ *
+ * num should be a pointer to an integer that holds the current
+ * number of elements in strings. It will be updated by this function.
+ */
+_PUBLIC_ bool add_string_to_array(TALLOC_CTX *mem_ctx,
+ const char *str, const char ***strings, size_t *num)
+{
+ char *dup_str = talloc_strdup(mem_ctx, str);
+
+ *strings = talloc_realloc(mem_ctx,
+ *strings,
+ const char *, ((*num)+1));
+
+ if ((*strings == NULL) || (dup_str == NULL)) {
+ *num = 0;
+ return false;
+ }
+
+ (*strings)[*num] = dup_str;
+ *num += 1;
+
+ return true;
+}
+
+/**
+ add an entry to a string list
+ this assumes s will not change
+*/
+_PUBLIC_ const char **str_list_add_const(const char **list, const char *s)
+{
+ size_t len = str_list_length(list);
+ const char **ret;
+
+ ret = talloc_realloc(NULL, list, const char *, len+2);
+ if (ret == NULL) return NULL;
+
+ ret[len] = s;
+ ret[len+1] = NULL;
+
+ return ret;
+}
+
+/**
+ copy a string list
+ this assumes list will not change
+*/
+_PUBLIC_ const char **str_list_copy_const(TALLOC_CTX *mem_ctx,
+ const char **list)
+{
+ int i;
+ const char **ret;
+
+ if (list == NULL)
+ return NULL;
+
+ ret = talloc_array(mem_ctx, const char *, str_list_length(list)+1);
+ if (ret == NULL)
+ return NULL;
+
+ for (i=0;list && list[i];i++) {
+ ret[i] = list[i];
+ }
+ ret[i] = NULL;
+ return ret;
+}
diff --git a/lib/util/util_strlist.h b/lib/util/util_strlist.h
new file mode 100644
index 0000000..5c3a7ee
--- /dev/null
+++ b/lib/util/util_strlist.h
@@ -0,0 +1,156 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Andrew Tridgell 2005
+ Copyright (C) Jelmer Vernooij 2005
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_UTIL_STRLIST_H
+#define _SAMBA_UTIL_STRLIST_H
+
+#include <talloc.h>
+
+/* separators for lists */
+#ifndef LIST_SEP
+#define LIST_SEP " \t,\n\r"
+#endif
+
+/**
+ build an empty (only NULL terminated) list of strings (for expansion with str_list_add() etc)
+*/
+char **str_list_make_empty(TALLOC_CTX *mem_ctx);
+
+/**
+ place the only element 'entry' into a new, NULL terminated string list
+*/
+char **str_list_make_single(TALLOC_CTX *mem_ctx,
+ const char *entry);
+
+/**
+ build a null terminated list of strings from a input string and a
+ separator list. The separator list must contain characters less than
+ or equal to 0x2f for this to work correctly on multi-byte strings
+*/
+char **str_list_make(TALLOC_CTX *mem_ctx, const char *string,
+ const char *sep);
+
+/**
+ * build a null terminated list of strings from an argv-like input string
+ * Entries are separated by spaces and can be enclosed by quotes.
+ * Does NOT support escaping
+ */
+char **str_list_make_shell(TALLOC_CTX *mem_ctx, const char *string,
+ const char *sep);
+
+/**
+ * join a list back to one string
+ */
+char *str_list_join(TALLOC_CTX *mem_ctx, const char **list,
+ char separator);
+
+/** join a list back to one (shell-like) string; entries
+ * separated by spaces, using quotes where necessary */
+char *str_list_join_shell(TALLOC_CTX *mem_ctx, const char **list,
+ char sep);
+
+/**
+ return the number of elements in a string list
+*/
+size_t str_list_length(const char * const *list);
+
+/**
+ copy a string list
+*/
+char **str_list_copy(TALLOC_CTX *mem_ctx, const char **list);
+
+/**
+ Return true if all the elements of the list match exactly.
+ */
+bool str_list_equal(const char * const *list1,
+ const char * const *list2);
+
+/**
+ add an entry to a string list
+*/
+const char **str_list_add(const char **list, const char *s);
+
+/*
+ * Extend a list with a printf'ed string
+ */
+void str_list_add_printf(char ***plist, const char *fmt, ...)
+ PRINTF_ATTRIBUTE(2,3);
+
+/**
+ remove an entry from a string list
+*/
+void str_list_remove(const char **list, const char *s);
+
+/**
+ return true if a string is in a list
+*/
+bool str_list_check(const char **list, const char *s);
+
+/**
+ return true if a string is in a list, case insensitively
+*/
+bool str_list_check_ci(const char **list, const char *s);
+/**
+ append one list to another - expanding list1
+*/
+const char **str_list_append(const char **list1,
+ const char * const *list2);
+
+/**
+ remove duplicate elements from a list
+*/
+const char **str_list_unique(const char **list);
+
+/*
+ very useful when debugging complex list related code
+ */
+void str_list_show(const char **list);
+
+
+/**
+ append one list to another - expanding list1
+ this assumes the elements of list2 are const pointers, so we can re-use them
+*/
+const char **str_list_append_const(const char **list1,
+ const char **list2);
+
+/**
+ Add a string to an array of strings.
+
+ num should be a pointer to an integer that holds the current
+ number of elements in strings. It will be updated by this function.
+ */
+bool add_string_to_array(TALLOC_CTX *mem_ctx,
+ const char *str, const char ***strings, size_t *num);
+
+/**
+ add an entry to a string list
+ this assumes s will not change
+*/
+const char **str_list_add_const(const char **list, const char *s);
+
+/**
+ copy a string list
+ this assumes list will not change
+*/
+const char **str_list_copy_const(TALLOC_CTX *mem_ctx,
+ const char **list);
+
+#endif /* _SAMBA_UTIL_STRLIST_H */
diff --git a/lib/util/util_strlist_v3.c b/lib/util/util_strlist_v3.c
new file mode 100644
index 0000000..75973f2
--- /dev/null
+++ b/lib/util/util_strlist_v3.c
@@ -0,0 +1,128 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Copyright (C) Andrew Tridgell 2005
+ Copyright (C) Jelmer Vernooij 2005
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "system/locale.h"
+#include "lib/util/tsort.h"
+
+#undef strcasecmp
+
+/**
+ * @file
+ * @brief String list manipulation v3
+ */
+
+/**
+ * Needed for making an "unconst" list "const"
+ */
+_PUBLIC_ const char **const_str_list(char **list)
+{
+ return discard_const_p(const char *, list);
+}
+
+/**
+ * str_list_make, v3 version. The v4 version does not
+ * look at quoted strings with embedded blanks, so
+ * do NOT merge this function please!
+ */
+#define S_LIST_ABS 16 /* List Allocation Block Size */
+
+char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
+ const char *sep)
+{
+ char **list;
+ const char *str;
+ char *s, *tok;
+ int num, lsize;
+
+ if (!string || !*string)
+ return NULL;
+
+ list = talloc_array(mem_ctx, char *, S_LIST_ABS+1);
+ if (list == NULL) {
+ return NULL;
+ }
+ lsize = S_LIST_ABS;
+
+ s = talloc_strdup(list, string);
+ if (s == NULL) {
+ DEBUG(0,("str_list_make: Unable to allocate memory\n"));
+ TALLOC_FREE(list);
+ return NULL;
+ }
+
+ /*
+ * DON'T REPLACE THIS BY "LIST_SEP". The common version of
+ * LIST_SEP does not contain the ;, which used to be accepted
+ * by Samba 4.0 before param merges. It would be the far
+ * better solution to split the _v3 version again to source3/
+ * where it belongs, see the _v3 in its name.
+ *
+ * Unfortunately it is referenced in /lib/param/loadparm.c,
+ * which depends on the version that the AD-DC mandates,
+ * namely without the ; as part of the list separator. I am
+ * missing the waf fu to properly work around the wrong
+ * include paths here for this defect.
+ */
+ if (sep == NULL) {
+ sep = " \t,;\n\r";
+ }
+
+ num = 0;
+ str = s;
+
+ while (next_token_talloc(list, &str, &tok, sep)) {
+
+ if (num == lsize) {
+ char **tmp;
+
+ lsize += S_LIST_ABS;
+
+ tmp = talloc_realloc(mem_ctx, list, char *,
+ lsize + 1);
+ if (tmp == NULL) {
+ DEBUG(0,("str_list_make: "
+ "Unable to allocate memory\n"));
+ TALLOC_FREE(list);
+ return NULL;
+ }
+
+ list = tmp;
+
+ memset (&list[num], 0,
+ ((sizeof(char*)) * (S_LIST_ABS +1)));
+ }
+
+ list[num] = tok;
+ num += 1;
+ }
+
+ list[num] = NULL;
+
+ TALLOC_FREE(s);
+ return list;
+}
+
+const char **str_list_make_v3_const(TALLOC_CTX *mem_ctx,
+ const char *string,
+ const char *sep)
+{
+ return const_str_list(str_list_make_v3(mem_ctx, string, sep));
+}
diff --git a/lib/util/util_tdb.c b/lib/util/util_tdb.c
new file mode 100644
index 0000000..d8672c3
--- /dev/null
+++ b/lib/util/util_tdb.c
@@ -0,0 +1,525 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ tdb utility functions
+
+ Copyright (C) Andrew Tridgell 1992-2006
+ Copyright (C) Volker Lendecke 2007-2011
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include <talloc.h>
+#include "libcli/util/ntstatus.h"
+#include "lib/util/memory.h"
+#include "lib/util/byteorder.h"
+#include "system/filesys.h"
+#include "../lib/tdb/include/tdb.h"
+#include "../lib/util/util_tdb.h"
+
+/* these are little tdb utility functions that are meant to make
+ dealing with a tdb database a little less cumbersome in Samba */
+
+/***************************************************************
+ Make a TDB_DATA and keep the const warning in one place
+****************************************************************/
+
+TDB_DATA make_tdb_data(const uint8_t *dptr, size_t dsize)
+{
+ TDB_DATA ret;
+ ret.dptr = discard_const_p(uint8_t, dptr);
+ ret.dsize = dsize;
+ return ret;
+}
+
+bool tdb_data_equal(TDB_DATA t1, TDB_DATA t2)
+{
+ if (t1.dsize != t2.dsize) {
+ return false;
+ }
+ return (memcmp(t1.dptr, t2.dptr, t1.dsize) == 0);
+}
+
+bool tdb_data_is_empty(TDB_DATA d)
+{
+ return (d.dsize == 0) || (d.dptr == NULL);
+}
+
+TDB_DATA string_tdb_data(const char *string)
+{
+ return make_tdb_data((const uint8_t *)string, string ? strlen(string) : 0 );
+}
+
+TDB_DATA string_term_tdb_data(const char *string)
+{
+ return make_tdb_data((const uint8_t *)string, string ? strlen(string) + 1 : 0);
+}
+
+TDB_DATA tdb_data_talloc_copy(TALLOC_CTX* mem_ctx, TDB_DATA data) {
+ TDB_DATA ret = {
+ .dptr = (uint8_t *)talloc_size(mem_ctx, data.dsize+1),
+ .dsize = data.dsize
+ };
+ if (ret.dptr == NULL) {
+ ret.dsize = 0;
+ } else {
+ memcpy(ret.dptr, data.dptr, data.dsize);
+ ret.dptr[ret.dsize] = '\0';
+ }
+ return ret;
+}
+
+
+/****************************************************************************
+ Lock a chain by string. Return non-zero if lock failed.
+****************************************************************************/
+
+int tdb_lock_bystring(struct tdb_context *tdb, const char *keyval)
+{
+ TDB_DATA key = string_term_tdb_data(keyval);
+
+ return tdb_chainlock(tdb, key);
+}
+
+/****************************************************************************
+ Unlock a chain by string.
+****************************************************************************/
+
+void tdb_unlock_bystring(struct tdb_context *tdb, const char *keyval)
+{
+ TDB_DATA key = string_term_tdb_data(keyval);
+
+ tdb_chainunlock(tdb, key);
+}
+
+/****************************************************************************
+ Read lock a chain by string. Return non-zero if lock failed.
+****************************************************************************/
+
+int tdb_read_lock_bystring(struct tdb_context *tdb, const char *keyval)
+{
+ TDB_DATA key = string_term_tdb_data(keyval);
+
+ return tdb_chainlock_read(tdb, key);
+}
+
+/****************************************************************************
+ Read unlock a chain by string.
+****************************************************************************/
+
+void tdb_read_unlock_bystring(struct tdb_context *tdb, const char *keyval)
+{
+ TDB_DATA key = string_term_tdb_data(keyval);
+
+ tdb_chainunlock_read(tdb, key);
+}
+
+
+/****************************************************************************
+ Fetch a int32_t value by a arbitrary blob key, return -1 if not found.
+ Output is int32_t in native byte order.
+****************************************************************************/
+
+static int fetch_int32_parser(TDB_DATA key, TDB_DATA data, void *private_data)
+{
+ if (data.dsize == sizeof(int32_t)) {
+ *((int32_t *)private_data) = PULL_LE_I32(data.dptr, 0);
+ }
+ return 0;
+}
+
+static int32_t tdb_fetch_int32_byblob(struct tdb_context *tdb, TDB_DATA key)
+{
+ int32_t v = -1;
+ int32_t ret = tdb_parse_record(tdb, key, fetch_int32_parser, &v);
+ if (ret == -1) {
+ return ret;
+ }
+ return v;
+}
+
+/****************************************************************************
+ Fetch a int32_t value by string key, return -1 if not found.
+ Output is int32_t in native byte order.
+****************************************************************************/
+
+int32_t tdb_fetch_int32(struct tdb_context *tdb, const char *keystr)
+{
+ return tdb_fetch_int32_byblob(tdb, string_term_tdb_data(keystr));
+}
+
+/****************************************************************************
+ Store a int32_t value by an arbitrary blob key, return 0 on success, -ve on failure.
+ Input is int32_t in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+
+static int tdb_store_int32_byblob(struct tdb_context *tdb, TDB_DATA key,
+ int32_t v)
+{
+ TDB_DATA data;
+ int32_t v_store;
+
+ SIVAL(&v_store,0,v);
+ data.dptr = (unsigned char *)&v_store;
+ data.dsize = sizeof(int32_t);
+
+ return tdb_store(tdb, key, data, TDB_REPLACE);
+}
+
+/****************************************************************************
+ Store a int32_t value by string key, return 0 on success, -ve on failure.
+ Input is int32_t in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+
+int tdb_store_int32(struct tdb_context *tdb, const char *keystr, int32_t v)
+{
+ return tdb_store_int32_byblob(tdb, string_term_tdb_data(keystr), v);
+}
+
+/****************************************************************************
+ Fetch a uint32_t value by a arbitrary blob key, return false if not found.
+ Output is uint32_t in native byte order.
+****************************************************************************/
+
+static int fetch_uint32_parser(TDB_DATA key, TDB_DATA data, void *private_data)
+{
+ if (data.dsize != sizeof(uint32_t)) {
+ return -1;
+ }
+ *((uint32_t *)private_data) = PULL_LE_U32(data.dptr, 0);
+ return 0;
+}
+
+static bool tdb_fetch_uint32_byblob(struct tdb_context *tdb, TDB_DATA key,
+ uint32_t *value)
+{
+ int ret = tdb_parse_record(tdb, key, fetch_uint32_parser, value);
+
+ if (ret == -1) {
+ return false;
+ }
+
+ return true;
+}
+
+/****************************************************************************
+ Fetch a uint32_t value by string key, return false if not found.
+ Output is uint32_t in native byte order.
+****************************************************************************/
+
+bool tdb_fetch_uint32(struct tdb_context *tdb, const char *keystr, uint32_t *value)
+{
+ return tdb_fetch_uint32_byblob(tdb, string_term_tdb_data(keystr), value);
+}
+
+/****************************************************************************
+ Store a uint32_t value by an arbitrary blob key, return true on success, false on failure.
+ Input is uint32_t in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+
+static bool tdb_store_uint32_byblob(struct tdb_context *tdb, TDB_DATA key,
+ uint32_t value)
+{
+ TDB_DATA data;
+ uint32_t v_store;
+ bool ret = true;
+
+ SIVAL(&v_store, 0, value);
+ data.dptr = (unsigned char *)&v_store;
+ data.dsize = sizeof(uint32_t);
+
+ if (tdb_store(tdb, key, data, TDB_REPLACE) != 0)
+ ret = false;
+
+ return ret;
+}
+
+/****************************************************************************
+ Store a uint32_t value by string key, return true on success, false on failure.
+ Input is uint32_t in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+
+bool tdb_store_uint32(struct tdb_context *tdb, const char *keystr, uint32_t value)
+{
+ return tdb_store_uint32_byblob(tdb, string_term_tdb_data(keystr), value);
+}
+/****************************************************************************
+ Store a buffer by a null terminated string key. Return 0 on success, -ve
+ on failure.
+****************************************************************************/
+
+int tdb_store_bystring(struct tdb_context *tdb, const char *keystr, TDB_DATA data, int flags)
+{
+ TDB_DATA key = string_term_tdb_data(keystr);
+
+ return tdb_store(tdb, key, data, flags);
+}
+
+/****************************************************************************
+ Fetch a buffer using a null terminated string key. Don't forget to call
+ free() on the result dptr.
+****************************************************************************/
+
+TDB_DATA tdb_fetch_bystring(struct tdb_context *tdb, const char *keystr)
+{
+ TDB_DATA key = string_term_tdb_data(keystr);
+
+ return tdb_fetch(tdb, key);
+}
+
+/****************************************************************************
+ Delete an entry using a null terminated string key.
+****************************************************************************/
+
+int tdb_delete_bystring(struct tdb_context *tdb, const char *keystr)
+{
+ TDB_DATA key = string_term_tdb_data(keystr);
+
+ return tdb_delete(tdb, key);
+}
+
+/****************************************************************************
+ Atomic integer change. Returns old value. To create, set initial value in *oldval.
+****************************************************************************/
+
+int32_t tdb_change_int32_atomic(struct tdb_context *tdb, const char *keystr, int32_t *oldval, int32_t change_val)
+{
+ int32_t val;
+ int32_t ret = -1;
+
+ if (tdb_lock_bystring(tdb, keystr) != 0)
+ return -1;
+
+ if ((val = tdb_fetch_int32(tdb, keystr)) == -1) {
+ /* The lookup failed */
+ if (tdb_error(tdb) != TDB_ERR_NOEXIST) {
+ /* but not because it didn't exist */
+ goto err_out;
+ }
+
+ /* Start with 'old' value */
+ val = *oldval;
+
+ } else {
+ /* It worked, set return value (oldval) to tdb data */
+ *oldval = val;
+ }
+
+ /* Increment value for storage and return next time */
+ val += change_val;
+
+ if (tdb_store_int32(tdb, keystr, val) != 0)
+ goto err_out;
+
+ ret = 0;
+
+ err_out:
+
+ tdb_unlock_bystring(tdb, keystr);
+ return ret;
+}
+
+/****************************************************************************
+ Atomic unsigned integer change. Returns old value. To create, set initial value in *oldval.
+****************************************************************************/
+
+bool tdb_change_uint32_atomic(struct tdb_context *tdb, const char *keystr, uint32_t *oldval, uint32_t change_val)
+{
+ uint32_t val;
+ bool ret = false;
+
+ if (tdb_lock_bystring(tdb, keystr) != 0)
+ return false;
+
+ if (!tdb_fetch_uint32(tdb, keystr, &val)) {
+ /* It failed */
+ if (tdb_error(tdb) != TDB_ERR_NOEXIST) {
+ /* and not because it didn't exist */
+ goto err_out;
+ }
+
+ /* Start with 'old' value */
+ val = *oldval;
+
+ } else {
+ /* it worked, set return value (oldval) to tdb data */
+ *oldval = val;
+
+ }
+
+ /* get a new value to store */
+ val += change_val;
+
+ if (!tdb_store_uint32(tdb, keystr, val))
+ goto err_out;
+
+ ret = true;
+
+ err_out:
+
+ tdb_unlock_bystring(tdb, keystr);
+ return ret;
+}
+
+/****************************************************************************
+ Return an NTSTATUS from a TDB_ERROR
+****************************************************************************/
+
+NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err)
+{
+ NTSTATUS result;
+
+ switch (err) {
+ case TDB_SUCCESS:
+ result = NT_STATUS_OK;
+ break;
+ case TDB_ERR_CORRUPT:
+ result = NT_STATUS_INTERNAL_DB_CORRUPTION;
+ break;
+ case TDB_ERR_IO:
+ result = NT_STATUS_UNEXPECTED_IO_ERROR;
+ break;
+ case TDB_ERR_OOM:
+ result = NT_STATUS_NO_MEMORY;
+ break;
+ case TDB_ERR_EXISTS:
+ result = NT_STATUS_OBJECT_NAME_COLLISION;
+ break;
+
+ case TDB_ERR_LOCK:
+ /*
+ * TDB_ERR_LOCK is very broad, we could for example
+ * distinguish between fcntl locks and invalid lock
+ * sequences. So NT_STATUS_FILE_LOCK_CONFLICT is a
+ * compromise.
+ */
+ result = NT_STATUS_FILE_LOCK_CONFLICT;
+ break;
+
+ case TDB_ERR_NOLOCK:
+ case TDB_ERR_LOCK_TIMEOUT:
+ /*
+ * These two ones in the enum are not actually used
+ */
+ result = NT_STATUS_FILE_LOCK_CONFLICT;
+ break;
+ case TDB_ERR_NOEXIST:
+ result = NT_STATUS_NOT_FOUND;
+ break;
+ case TDB_ERR_EINVAL:
+ result = NT_STATUS_INVALID_PARAMETER;
+ break;
+ case TDB_ERR_RDONLY:
+ result = NT_STATUS_ACCESS_DENIED;
+ break;
+ case TDB_ERR_NESTING:
+ result = NT_STATUS_INTERNAL_ERROR;
+ break;
+ default:
+ result = NT_STATUS_INTERNAL_ERROR;
+ break;
+ };
+ return result;
+}
+
+int map_unix_error_from_tdb(enum TDB_ERROR err)
+{
+ int result = EINVAL;
+
+ switch (err) {
+ case TDB_SUCCESS:
+ result = 0;
+ break;
+ case TDB_ERR_CORRUPT:
+ result = EILSEQ;
+ break;
+ case TDB_ERR_IO:
+ result = EIO;
+ break;
+ case TDB_ERR_OOM:
+ result = ENOMEM;
+ break;
+ case TDB_ERR_EXISTS:
+ result = EEXIST;
+ break;
+
+ case TDB_ERR_LOCK:
+ /*
+ * TDB_ERR_LOCK is very broad, we could for example
+ * distinguish between fcntl locks and invalid lock
+ * sequences. EWOULDBLOCK is wrong, but there is no real
+ * generic lock error code in errno.h
+ */
+ result = EWOULDBLOCK;
+ break;
+
+ case TDB_ERR_NOLOCK:
+ case TDB_ERR_LOCK_TIMEOUT:
+ /*
+ * These two ones in the enum are not actually used
+ */
+ result = ENOLCK;
+ break;
+ case TDB_ERR_NOEXIST:
+ result = ENOENT;
+ break;
+ case TDB_ERR_EINVAL:
+ result = EINVAL;
+ break;
+ case TDB_ERR_RDONLY:
+ result = EROFS;
+ break;
+ case TDB_ERR_NESTING:
+ /*
+ * Well, this db is already busy...
+ */
+ result = EBUSY;
+ break;
+ };
+ return result;
+}
+
+struct tdb_fetch_talloc_state {
+ TALLOC_CTX *mem_ctx;
+ uint8_t *buf;
+};
+
+static int tdb_fetch_talloc_parser(TDB_DATA key, TDB_DATA data,
+ void *private_data)
+{
+ struct tdb_fetch_talloc_state *state = private_data;
+ state->buf = talloc_memdup(state->mem_ctx, data.dptr, data.dsize);
+ return 0;
+}
+
+int tdb_fetch_talloc(struct tdb_context *tdb, TDB_DATA key,
+ TALLOC_CTX *mem_ctx, uint8_t **buf)
+{
+ struct tdb_fetch_talloc_state state = { .mem_ctx = mem_ctx };
+ int ret;
+
+ ret = tdb_parse_record(tdb, key, tdb_fetch_talloc_parser, &state);
+ if (ret == -1) {
+ enum TDB_ERROR err = tdb_error(tdb);
+ return map_unix_error_from_tdb(err);
+ }
+
+ if (state.buf == NULL) {
+ return ENOMEM;
+ }
+
+ *buf = state.buf;
+ return 0;
+}
diff --git a/lib/util/util_tdb.h b/lib/util/util_tdb.h
new file mode 100644
index 0000000..010521d
--- /dev/null
+++ b/lib/util/util_tdb.h
@@ -0,0 +1,125 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ tdb utility functions
+
+ Copyright (C) Andrew Tridgell 1992-2006
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _____LIB_UTIL_UTIL_TDB_H__
+#define _____LIB_UTIL_UTIL_TDB_H__
+
+#include "replace.h"
+#include <tdb.h>
+#include "libcli/util/ntstatus.h"
+
+/***************************************************************
+ Make a TDB_DATA and keep the const warning in one place
+****************************************************************/
+TDB_DATA make_tdb_data(const uint8_t *dptr, size_t dsize);
+bool tdb_data_equal(TDB_DATA t1, TDB_DATA t2);
+bool tdb_data_is_empty(TDB_DATA d);
+TDB_DATA string_tdb_data(const char *string);
+TDB_DATA string_term_tdb_data(const char *string);
+TDB_DATA tdb_data_talloc_copy(TALLOC_CTX* mem_ctx, TDB_DATA data);
+
+/****************************************************************************
+ Lock a chain by string. Return non-zero if lock failed.
+****************************************************************************/
+int tdb_lock_bystring(struct tdb_context *tdb, const char *keyval);
+
+/****************************************************************************
+ Unlock a chain by string.
+****************************************************************************/
+void tdb_unlock_bystring(struct tdb_context *tdb, const char *keyval);
+
+/****************************************************************************
+ Read lock a chain by string. Return non-zero if lock failed.
+****************************************************************************/
+int tdb_read_lock_bystring(struct tdb_context *tdb, const char *keyval);
+
+/****************************************************************************
+ Read unlock a chain by string.
+****************************************************************************/
+void tdb_read_unlock_bystring(struct tdb_context *tdb, const char *keyval);
+
+/****************************************************************************
+ Fetch a int32_t value by string key, return -1 if not found.
+ Output is int32_t in native byte order.
+****************************************************************************/
+int32_t tdb_fetch_int32(struct tdb_context *tdb, const char *keystr);
+
+/****************************************************************************
+ Store a int32_t value by string key, return 0 on success, -ve on failure.
+ Input is int32_t in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+int tdb_store_int32(struct tdb_context *tdb, const char *keystr, int32_t v);
+
+/****************************************************************************
+ Fetch a uint32_t value by string key, return -1 if not found.
+ Output is uint32_t in native byte order.
+****************************************************************************/
+bool tdb_fetch_uint32(struct tdb_context *tdb, const char *keystr, uint32_t *value);
+
+/****************************************************************************
+ Store a uint32_t value by string key, return true on success, false on failure.
+ Input is uint32_t in native byte order. Output in tdb is in little-endian.
+****************************************************************************/
+bool tdb_store_uint32(struct tdb_context *tdb, const char *keystr, uint32_t value);
+
+/****************************************************************************
+ Store a buffer by a null terminated string key. Return 0 on success, -ve
+ on failure.
+****************************************************************************/
+int tdb_store_bystring(struct tdb_context *tdb, const char *keystr, TDB_DATA data, int flags);
+
+/****************************************************************************
+ Fetch a buffer using a null terminated string key. Don't forget to call
+ free() on the result dptr.
+****************************************************************************/
+TDB_DATA tdb_fetch_bystring(struct tdb_context *tdb, const char *keystr);
+
+/****************************************************************************
+ Delete an entry using a null terminated string key. 0 on success, -ve on err.
+****************************************************************************/
+int tdb_delete_bystring(struct tdb_context *tdb, const char *keystr);
+
+/****************************************************************************
+ Atomic integer change. Returns old value. To create, set initial value in *oldval.
+****************************************************************************/
+int32_t tdb_change_int32_atomic(struct tdb_context *tdb, const char *keystr, int32_t *oldval, int32_t change_val);
+
+/****************************************************************************
+ Atomic unsigned integer change. Returns old value. To create, set initial value in *oldval.
+****************************************************************************/
+bool tdb_change_uint32_atomic(struct tdb_context *tdb, const char *keystr, uint32_t *oldval, uint32_t change_val);
+
+/****************************************************************************
+ Return an NTSTATUS from a TDB_ERROR
+****************************************************************************/
+
+NTSTATUS map_nt_error_from_tdb(enum TDB_ERROR err);
+
+/****************************************************************************
+ Return an errno from a TDB_ERROR
+****************************************************************************/
+
+int map_unix_error_from_tdb(enum TDB_ERROR err);
+
+int tdb_fetch_talloc(struct tdb_context *tdb, TDB_DATA key,
+ TALLOC_CTX *mem_ctx, uint8_t **buf);
+
+#endif /* _____LIB_UTIL_UTIL_TDB_H__ */
diff --git a/lib/util/wscript b/lib/util/wscript
new file mode 100644
index 0000000..425f659
--- /dev/null
+++ b/lib/util/wscript
@@ -0,0 +1,32 @@
+def options(opt):
+ ''' This is a bit strange, but disable is the flag, not enable. '''
+ opt.add_option('--disable-fault-handling', action='store_true', dest='disable_fault_handling', help=('disable the fault handlers'), default=False)
+
+ # We do not want libunwind by default (backtrace_symbols() in
+ # glibc is better) but allow (eg) IA-64 to build with it where it
+ # might be better (per old comment in fault.c)
+ opt.samba_add_onoff_option('libunwind',
+ default=None,
+ help='''Use libunwind instead of the default backtrace_symbols()
+ from libc, for example on IA-64 where it might give a better
+ backtrace.''')
+
+ opt.add_option('--with-systemd',
+ help=("Enable systemd integration"),
+ action='store_true', dest='enable_systemd')
+
+ opt.add_option('--without-systemd',
+ help=("Disable systemd integration"),
+ action='store_false', dest='enable_systemd')
+
+ opt.add_option('--with-lttng',
+ help=("Enable lttng integration"),
+ action='store_true', dest='enable_lttng')
+
+ opt.add_option('--without-lttng',
+ help=("Disable lttng integration"),
+ action='store_false', dest='enable_lttng')
+
+ opt.add_option('--with-gpfs',
+ help=("Directory under which gpfs headers are installed"),
+ action="store", dest='gpfs_headers_dir')
diff --git a/lib/util/wscript_build b/lib/util/wscript_build
new file mode 100644
index 0000000..b4fcfea
--- /dev/null
+++ b/lib/util/wscript_build
@@ -0,0 +1,415 @@
+#!/usr/bin/env python
+
+# Please add any new SAMBA_SUBSYSTEM/SAMBA_LIBRARY to the bottom of the file
+# unless they are also required to build standalone ctdb.
+
+bld.SAMBA_LIBRARY('time-basic',
+ source='time_basic.c',
+ deps='replace',
+ private_library=True,
+ local_include=False)
+
+bld.SAMBA_SUBSYSTEM('tini',
+ source='tini.c',
+ provide_builtin_linking=True,
+ local_include=False)
+
+bld.SAMBA_SUBSYSTEM('tiniparser',
+ source='tiniparser.c',
+ deps='tini',
+ provide_builtin_linking=True,
+ local_include=False)
+
+bld.SAMBA_SUBSYSTEM('strv',
+ source='strv.c',
+ deps='talloc',
+ local_include=False)
+
+bld.SAMBA_SUBSYSTEM('close-low-fd',
+ source='close_low_fd.c',
+ deps='replace',
+ local_include=False)
+
+bld.SAMBA_LIBRARY('sys_rw',
+ source='sys_rw.c sys_rw_data.c',
+ deps='replace iov_buf',
+ local_include=False,
+ private_library=True)
+
+samba_debug_add_deps = ''
+samba_debug_add_inc = ''
+
+if bld.CONFIG_SET('HAVE_GPFS'):
+ bld.SAMBA_SUBSYSTEM('gpfswrap',
+ source='gpfswrap.c',
+ deps='replace',
+ local_include=False,
+ includes=bld.CONFIG_GET('CPPPATH_GPFS'))
+ samba_debug_add_deps += ' gpfswrap'
+ samba_debug_add_inc += bld.CONFIG_GET('CPPPATH_GPFS')
+
+bld.SAMBA_LIBRARY('samba-debug',
+ source='debug.c',
+ deps='replace time-basic close-low-fd talloc socket-blocking' + samba_debug_add_deps,
+ public_deps='systemd systemd-journal lttng-ust',
+ local_include=False,
+ includes='lib/util/debug-classes ' + samba_debug_add_inc,
+ private_library=True)
+
+bld.SAMBA_LIBRARY('socket-blocking',
+ source='blocking.c',
+ local_include=False,
+ private_library=True)
+
+bld.SAMBA_LIBRARY('talloc_report',
+ source='talloc_report.c',
+ local_include=False,
+ public_deps='talloc',
+ private_library=True
+ )
+
+bld.SAMBA_LIBRARY('talloc_report_printf',
+ source='talloc_report_printf.c',
+ local_include=False,
+ public_deps='talloc',
+ private_library=True
+ )
+
+bld.SAMBA_SUBSYSTEM('smb-panic',
+ source='''
+ fault.c
+ signal.c
+ util_process.c
+ ''',
+ deps='''
+ replace
+ samba-debug
+ LIBUNWIND
+ execinfo
+ ''',
+ local_include=False)
+
+bld.SAMBA_SUBSYSTEM('samba-util-core',
+ source='''
+ data_blob.c
+ util_file.c
+ sys_popen.c
+ time.c
+ util.c
+ idtree.c
+ substitute.c
+ util_strlist.c
+ strv_util.c
+ bitmap.c
+ select.c
+ pidfile.c
+ become_daemon.c
+ mkdir_p.c
+ ''',
+ deps='''
+ time-basic
+ samba-debug
+ socket-blocking
+ talloc
+ tevent
+ execinfo
+ pthread
+ strv
+ tini
+ smb_strtox
+ smb-panic
+ gnutls
+ ''',
+ public_deps='systemd systemd-daemon sys_rw',
+ local_include=False)
+
+bld.SAMBA_SUBSYSTEM('smb_strtox',
+ source='smb_strtox.c',
+ provide_builtin_linking=True,
+ local_include=False)
+
+
+bld.SAMBA_LIBRARY('iov_buf',
+ source='iov_buf.c',
+ deps='talloc',
+ local_include=False,
+ private_library=True)
+
+bld.SAMBA_LIBRARY('msghdr',
+ source='msghdr.c',
+ deps='replace iov_buf',
+ local_include=False,
+ private_library=True)
+
+bld.SAMBA_LIBRARY('genrand',
+ source='genrand.c',
+ deps='replace gnutls smb-panic',
+ local_include=False,
+ private_library=True)
+
+bld.SAMBA_LIBRARY('stable_sort',
+ source='stable_sort.c',
+ deps='replace',
+ public_deps='talloc',
+ local_include=False,
+ private_library=True)
+
+if bld.env.SAMBA_UTIL_CORE_ONLY:
+
+ bld.SAMBA_LIBRARY('tevent-util',
+ source='tevent_unix.c',
+ local_include=False,
+ deps='tevent',
+ private_library=True)
+
+else:
+
+ bld.env.public_headers_skip.append('charset_compat.h')
+
+ bld.SAMBA_BINARY('genrandperf',
+ source='tests/genrandperf.c',
+ deps='genrand replace',
+ local_include=False,
+ install=False)
+
+ # TODO: Rewrite ms_fnmatch_core() for a better API.
+ ms_fnmatch_cflags=''
+ if bld.CONFIG_SET('HAVE_WNO_ERROR_ARRAY_BOUNDS'):
+ ms_fnmatch_cflags='-Wno-error=array-bounds'
+ bld.SAMBA_SUBSYSTEM('SAMBA_UTIL_MS_FNMATCH',
+ source='ms_fnmatch.c',
+ deps='talloc',
+ cflags=ms_fnmatch_cflags,
+ local_include=False)
+
+ bld.SAMBA_LIBRARY('samba-util',
+ source='''
+ base64.c
+ dprintf.c
+ fsusage.c
+ genrand_util.c
+ getpass.c
+ idtree_random.c
+ memcache.c
+ params.c
+ rbtree.c
+ rfc1738.c
+ server_id.c
+ smb_threads.c
+ system.c
+ talloc_keep_secret.c
+ talloc_stack.c
+ tevent_debug.c
+ tfork.c
+ tftw.c
+ unix_match.c
+ util_id.c
+ util_net.c
+ util_paths.c
+ util_str.c
+ util_str_common.c
+ util_strlist_v3.c
+ ''',
+ deps='''
+ samba-util-core
+ DYNCONFIG
+ close-low-fd
+ tiniparser
+ genrand
+ util_str_hex
+ SAMBA_UTIL_MS_FNMATCH
+ ''',
+ public_deps='talloc tevent execinfo pthread LIBCRYPTO charset util_setid',
+ public_headers='''
+ attr.h
+ data_blob.h
+ debug.h
+ discard.h
+ time.h
+ idtree.h
+ idtree_random.h
+ blocking.h
+ signal.h
+ substitute.h
+ fault.h
+ genrand.h
+ tfork.h
+ ''',
+ header_path= [ ('dlinklist.h samba_util.h', '.'), ('*', 'util') ],
+ local_include=False,
+ vnum='0.0.1',
+ pc_files='samba-util.pc'
+ )
+
+ bld.SAMBA_LIBRARY('samba-modules',
+ source='modules.c',
+ deps='samba-errors samba-util',
+ local_include=False,
+ private_library=True)
+
+ bld.SAMBA_LIBRARY('asn1util',
+ source='asn1.c',
+ deps='talloc samba-util',
+ private_library=True,
+ local_include=False)
+
+
+ bld.SAMBA_SUBSYSTEM('UNIX_PRIVS',
+ source='unix_privs.c',
+ autoproto='unix_privs.h',
+ deps='replace talloc',
+ local_include=False,
+ )
+
+
+ bld.SAMBA_LIBRARY('util_tdb',
+ source='util_tdb.c',
+ local_include=False,
+ public_deps='tdb talloc',
+ private_library=True
+ )
+
+ bld.SAMBA_LIBRARY('tevent-util',
+ source='''
+ tevent_unix.c
+ tevent_ntstatus.c
+ tevent_werror.c
+ tevent_req_profile.c
+ ''',
+ local_include=False,
+ public_deps='tevent samba-errors',
+ public_headers='tevent_ntstatus.h tevent_unix.h tevent_werror.h',
+ header_path=[ ('*', 'util') ],
+ pc_files=[],
+ vnum='0.0.1'
+ )
+
+ bld.SAMBA_LIBRARY('util_setid',
+ source='setid.c',
+ local_include=False,
+ private_library=True
+ )
+
+ bld.SAMBA_SUBSYSTEM('util_ldb',
+ source='util_ldb.c',
+ local_include=False,
+ public_deps='ldb',
+ public_headers='util_ldb.h'
+ )
+
+
+ bld.SAMBA_SUBSYSTEM('UTIL_RUNCMD',
+ source='util_runcmd.c',
+ local_include=False,
+ public_deps='tevent'
+ )
+
+ bld.SAMBA_SUBSYSTEM('UTIL_PW',
+ source='util_pw.c',
+ local_include=False,
+ public_deps='talloc'
+ )
+
+ bld.SAMBA_LIBRARY('server_id_db',
+ source='server_id_db.c',
+ deps='talloc tdb strv util_tdb tdb-wrap samba-util',
+ local_include=False,
+ private_library=True)
+
+ bld.SAMBA_SUBSYSTEM('access',
+ source='access.c',
+ deps='interfaces samba-util',
+ local_include=False)
+
+ bld.SAMBA_SUBSYSTEM('util_str_escape',
+ source='util_str_escape.c',
+ deps='talloc',
+ local_include=False)
+
+ bld.SAMBA_SUBSYSTEM('util_str_hex',
+ source='util_str_hex.c',
+ deps='talloc',
+ local_include=False)
+
+ bld.SAMBA_BINARY('test_rfc1738',
+ source='tests/rfc1738.c',
+ deps='cmocka replace samba-util',
+ local_include=False,
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_ms_fnmatch',
+ source='tests/test_ms_fnmatch.c',
+ deps='cmocka replace samba-util',
+ local_include=False,
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_talloc_keep_secret',
+ source='tests/test_talloc_keep_secret.c',
+ deps='cmocka replace samba-util',
+ local_include=False,
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_byteorder',
+ source='tests/test_byteorder.c',
+ deps='cmocka replace samba-util',
+ local_include=False,
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_bytearray',
+ source='tests/test_bytearray.c',
+ deps='cmocka replace samba-util',
+ local_include=False,
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_byteorder_verify',
+ source='tests/test_byteorder_verify.c',
+ deps='cmocka replace samba-util',
+ local_include=False,
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_util_paths',
+ source='tests/test_util_paths.c',
+ deps='cmocka replace talloc samba-util',
+ local_include=False,
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_util',
+ source='tests/test_util.c',
+ deps='cmocka replace talloc samba-util',
+ local_include=False,
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_memcache',
+ source='tests/test_memcache.c',
+ deps='cmocka replace talloc samba-util',
+ local_include=False,
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_sys_rw',
+ source='tests/test_sys_rw.c',
+ deps='cmocka replace samba-util',
+ local_include=False,
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_s4_logging',
+ source='tests/test_logging.c',
+ deps=' '.join(['CMDLINE_S4',
+ 'samba-util',
+ 'popt']),
+ local_include=False,
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_s3_logging',
+ source='tests/test_logging.c',
+ deps=' '.join(['CMDLINE_S3',
+ 'samba-util',
+ 'popt']),
+ cflags="-D USING_CMDLINE_S3",
+ local_include=False,
+ for_selftest=True)
+
+ bld.SAMBA_BINARY('test_stable_sort',
+ source='tests/test_stable_sort.c',
+ deps='cmocka replace talloc stable_sort',
+ local_include=False,
+ for_selftest=True)
diff --git a/lib/util/wscript_configure b/lib/util/wscript_configure
new file mode 100644
index 0000000..27206e0
--- /dev/null
+++ b/lib/util/wscript_configure
@@ -0,0 +1,189 @@
+#!/usr/bin/env python
+from waflib import Logs, Options, Errors
+
+import os, sys
+
+if Options.options.disable_fault_handling:
+ conf.DEFINE('HAVE_DISABLE_FAULT_HANDLING',1)
+
+# backtrace could be in libexecinfo or in libc.
+# This is our preferred backtrace handler (more useful output than libunwind as at Ubuntu 20.04 x86_64)
+conf.CHECK_FUNCS_IN('backtrace backtrace_symbols', 'execinfo', checklibc=True, headers='execinfo.h')
+conf.CHECK_HEADERS('execinfo.h')
+
+conf.SET_TARGET_TYPE('LIBUNWIND', 'EMPTY')
+if Options.options.with_libunwind:
+ if conf.check_cfg(package='libunwind-generic',
+ args='--cflags --libs',
+ msg='Checking for libunwind',
+ uselib_store='LIBUNWIND',
+ mandatory=False):
+ if conf.CHECK_HEADERS('libunwind.h'):
+ conf.SET_TARGET_TYPE('LIBUNWIND', 'SYSLIB')
+ else:
+ raise Errors.WafError('--with-libunwind specified but libunwind not found')
+elif Options.options.with_libunwind == None:
+ if not conf.CONFIG_SET('HAVE_BACKTRACE_SYMBOLS') \
+ and not Options.options.disable_fault_handling:
+ raise Errors.WafError(
+'''backtrace_symbols() not found but
+--with-libunwind not specified.
+Use --without-libunwind to build without internal backtrace support or
+--disable-fault-handling to totally defer fault handling to the OS.''')
+
+conf.CHECK_STRUCTURE_MEMBER('struct statvfs', 'f_frsize', define='HAVE_FRSIZE', headers='sys/statvfs.h')
+
+# all the different ways of doing statfs
+statfs_types = [
+ ( 'STAT_STATVFS',
+ 'statvfs (SVR4)',
+ 'struct statvfs fsd; exit(statvfs(0, &fsd))',
+ 'sys/statvfs.h' ),
+
+ ( 'STAT_STATFS3_OSF1',
+ '3-argument statfs function (DEC OSF/1)',
+ 'struct statfs fsd; fsd.f_fsize = 0; exit(statfs(".", &fsd, sizeof(struct statfs)))',
+ 'sys/param.h sys/mount.h' ),
+
+ ( 'STAT_STATFS2_BSIZE',
+ 'two-argument statfs with statfs.bsize',
+ 'struct statfs fsd; fsd.f_bsize = 0; exit(statfs(".", &fsd))',
+ 'sys/param.h sys/mount.h sys/vfs.h' ),
+
+ ( 'STAT_STATFS4',
+ 'four-argument statfs (AIX-3.2.5, SVR3)',
+ 'struct statfs fsd; exit(statfs(".", &fsd, sizeof fsd, 0))',
+ 'sys/statfs.h' ),
+
+ ( 'STAT_STATFS2_FSIZE',
+ 'two-argument statfs with statfs.fsize',
+ 'struct statfs fsd; fsd.f_fsize = 0; exit(statfs(".", &fsd))',
+ 'sys/param.h sys/mount.h' ),
+
+ ( 'STAT_STATFS2_FS_DATA',
+ 'two-argument statfs with struct fs_data (Ultrix)',
+ 'struct fs_data fsd; exit(statfs(".", &fsd) != 1)',
+ 'sys/param.h sys/mount.h sys/fs_types.h' )
+]
+
+found_statfs=False
+for (define, msg, code, headers) in statfs_types:
+ if conf.CHECK_CODE(code,
+ define=define,
+ headers=headers,
+ msg='Checking for %s' % msg,
+ local_include=False):
+ found_statfs=True
+ break
+
+if not found_statfs:
+ print("FATAL: Failed to find a statfs method")
+ raise
+
+conf.CHECK_CODE("""struct statfs fsd;
+ fsd.f_bsize = 0;
+ fsd.f_iosize = 0;
+ return (statfs (".", &fsd));
+ """,
+ headers='sys/param.h sys/mount.h sys/vfs.h',
+ define='BSD_STYLE_STATVFS',
+ msg='Checking for *bsd style statfs with statfs.f_iosize',
+ execute=True,
+ local_include=False)
+
+conf.CHECK_CODE('struct statvfs buf; buf.f_fsid = 0',
+ define='HAVE_FSID_INT',
+ msg='Checking if f_fsid is an integer',
+ execute=False,
+ local_include=False,
+ headers='sys/statvfs.h')
+
+# fsusage.c assumes that statvfs has an f_frsize entry. Some weird
+# systems use f_bsize.
+conf.CHECK_CODE('struct statvfs buf; buf.f_frsize = 0',
+ define='HAVE_FRSIZE',
+ msg='Checking that statvfs.f_frsize works',
+ headers='sys/statvfs.h',
+ execute=False,
+ local_include=False)
+
+# Some systems use f_flag in struct statvfs while others use f_flags
+conf.CHECK_CODE('struct statvfs buf; buf.f_flag = 0',
+ define='HAVE_STATVFS_F_FLAG',
+ msg='Checking whether statvfs.f_flag exists',
+ headers='sys/statvfs.h',
+ local_include=False,
+ execute=False)
+
+conf.CHECK_CODE('struct statvfs buf; buf.f_flags = 0',
+ define='HAVE_STATVFS_F_FLAGS',
+ msg='Checking whether statvfs.f_flags exists',
+ headers='sys/statvfs.h',
+ local_include=False,
+ execute=False)
+
+# Check for mallinfo2() first and fallback to mallinfo() if not found
+body = '''mi.arena + mi.ordblks + mi.smblks + mi.hblks + mi.hblkhd +
+ mi.usmblks + mi.fsmblks + mi.uordblks + mi.fordblks + mi.keepcost'''
+if not conf.CHECK_CODE('''struct mallinfo2 mi = mallinfo2(); return %s;'''
+ % body, 'HAVE_MALLINFO2',
+ msg="Checking for mallinfo2()",
+ headers='malloc.h'):
+ conf.CHECK_CODE('''struct mallinfo mi = mallinfo(); return %s;'''
+ % body, 'HAVE_MALLINFO',
+ msg="Checking for mallinfo()",
+ headers='malloc.h')
+
+#
+# systemd removed the libsystemd-daemon and libsystemd-journal libraries. In newer
+# versions it is only libsystemd. As waf pkg-config handling does not provide
+# targets which could be used as a dependency based on the package name we need
+# to look for them on our own. This enabled one of the library targets based on
+# which version we detect.
+#
+conf.SET_TARGET_TYPE('systemd-daemon', 'EMPTY')
+conf.SET_TARGET_TYPE('systemd-journal', 'EMPTY')
+conf.SET_TARGET_TYPE('systemd', 'EMPTY')
+
+if Options.options.enable_systemd != False:
+ r_daemon = conf.CHECK_CFG(package='libsystemd-daemon', args='--cflags --libs',
+ msg='Checking for libsystemd-daemon')
+ r_journal = conf.CHECK_CFG(package='libsystemd-journal', args='--cflags --libs',
+ msg='Checking for libsystemd-journal')
+ if r_daemon is None and r_journal is None:
+ conf.CHECK_CFG(package='libsystemd', args='--cflags --libs',
+ msg='Checking for libsystemd')
+ conf.CHECK_LIB('systemd', shlib=True)
+ else:
+ conf.CHECK_LIB('systemd-daemon', shlib=True)
+ conf.CHECK_LIB('systemd-journal', shlib=True)
+
+conf.SET_TARGET_TYPE('lttng-ust', 'EMPTY')
+
+if Options.options.enable_lttng != False:
+ conf.CHECK_CFG(package='lttng-ust', args='--cflags --libs',
+ msg='Checking for lttng-ust', uselib_store="LTTNG-UST")
+ conf.CHECK_HEADERS('lttng/tracef.h', lib='lttng-st')
+ conf.CHECK_LIB('lttng-ust', shlib=True)
+
+if (conf.CONFIG_SET('HAVE_LTTNG_TRACEF_H') and
+ conf.CONFIG_SET('HAVE_LTTNG_UST')):
+ conf.DEFINE('HAVE_LTTNG_TRACEF', '1')
+ conf.env['HAVE_LTTNG_TRACEF'] = True
+
+if Options.options.gpfs_headers_dir:
+ conf.env['CPPPATH_GPFS'] = Options.options.gpfs_headers_dir
+ if conf.CHECK_HEADERS('gpfs.h', False, False, "gpfs"):
+ Logs.info('Using gpfs.h from %s' % Options.options.gpfs_headers_dir)
+ conf.DEFINE('HAVE_GPFS', '1')
+else:
+ conf.env['CPPPATH_GPFS'] = "/usr/lpp/mmfs/include/"
+ if conf.CHECK_HEADERS('gpfs.h', False, False, "gpfs"):
+ Logs.info('Using gpfs.h from installed gpfs package.')
+ conf.DEFINE('HAVE_GPFS', '1')
+ else:
+ if sys.platform.startswith('linux'):
+ conf.env['CPPPATH_GPFS'] = os.path.abspath("third_party/gpfs")
+ if conf.CHECK_HEADERS('gpfs.h', False, False, "gpfs"):
+ Logs.info('Using gpfs.h from third_party directory.')
+ conf.DEFINE('HAVE_GPFS', '1')